Compare commits
1 Commits
jebbatime
...
native-del
Author | SHA1 | Date |
---|---|---|
Paul Sokolovsky | b7d32672ce |
|
@ -1,26 +0,0 @@
|
|||
# Per default everything gets normalized and gets LF line endings on checkout.
|
||||
* text eol=lf
|
||||
|
||||
# These will always have CRLF line endings on checkout.
|
||||
*.vcxproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
# These are binary so should never be modified by git.
|
||||
*.a binary
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.dxf binary
|
||||
*.mpy binary
|
||||
|
||||
# These should also not be modified by git.
|
||||
tests/basics/string_cr_conversion.py -text
|
||||
tests/basics/string_crlf_conversion.py -text
|
||||
ports/stm32/pybcdc.inf_template -text
|
||||
ports/stm32/usbhost/** -text
|
||||
ports/cc3200/hal/aes.c -text
|
||||
ports/cc3200/hal/aes.h -text
|
||||
ports/cc3200/hal/des.c -text
|
||||
ports/cc3200/hal/i2s.c -text
|
||||
ports/cc3200/hal/i2s.h -text
|
||||
ports/cc3200/version.h -text
|
|
@ -9,22 +9,20 @@
|
|||
*.dis
|
||||
*.exe
|
||||
|
||||
# Packages
|
||||
# Packages
|
||||
############
|
||||
|
||||
# Logs and Databases
|
||||
######################
|
||||
*.log
|
||||
cscope.out
|
||||
|
||||
# VIM Swap Files
|
||||
######################
|
||||
*.swp
|
||||
|
||||
# Build directories
|
||||
# Build directory
|
||||
######################
|
||||
build/
|
||||
build-*/
|
||||
|
||||
# Test failure outputs
|
||||
######################
|
||||
|
@ -34,13 +32,6 @@ tests/*.out
|
|||
# Python cache files
|
||||
######################
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Customized Makefile/project overrides
|
||||
######################
|
||||
# Customized Makefile overrides
|
||||
GNUmakefile
|
||||
user.props
|
||||
|
||||
# Generated rst files
|
||||
######################
|
||||
genrst/
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
[submodule "lib/axtls"]
|
||||
path = lib/axtls
|
||||
url = https://mirrors.spacecruft.org/pfalcon/axtls
|
||||
branch = micropython
|
||||
[submodule "lib/libffi"]
|
||||
path = lib/libffi
|
||||
url = https://mirrors.spacecruft.org/atgreen/libffi
|
||||
[submodule "lib/lwip"]
|
||||
path = lib/lwip
|
||||
url = https://mirrors.spacecruft.org/savannah/lwip
|
||||
[submodule "lib/berkeley-db-1.xx"]
|
||||
path = lib/berkeley-db-1.xx
|
||||
url = https://mirrors.spacecruft.org/pfalcon/berkeley-db-1.xx
|
||||
[submodule "lib/stm32lib"]
|
||||
path = lib/stm32lib
|
||||
url = https://mirrors.spacecruft.org/micropython/stm32lib
|
||||
branch = work-F4-1.13.1+F7-1.5.0+L4-1.3.0
|
||||
[submodule "lib/nrfx"]
|
||||
path = lib/nrfx
|
||||
url = https://mirrors.spacecruft.org/NordicSemiconductor/nrfx.git
|
||||
[submodule "lib/mbedtls"]
|
||||
path = lib/mbedtls
|
||||
url = https://mirrors.spacecruft.org/ARMmbed/mbedtls.git
|
||||
[submodule "lib/asf4"]
|
||||
path = lib/asf4
|
||||
url = https://mirrors.spacecruft.org/adafruit/asf4
|
||||
[submodule "lib/tinyusb"]
|
||||
path = lib/tinyusb
|
||||
url = https://mirrors.spacecruft.org/hathach/tinyusb
|
||||
[submodule "lib/mynewt-nimble"]
|
||||
path = lib/mynewt-nimble
|
||||
url = https://mirrors.spacecruft.org/apache/mynewt-nimble.git
|
282
.travis.yml
282
.travis.yml
|
@ -1,265 +1,29 @@
|
|||
# global options
|
||||
dist: xenial
|
||||
language:
|
||||
- c
|
||||
language: c
|
||||
compiler:
|
||||
- gcc
|
||||
cache:
|
||||
directories:
|
||||
- "${HOME}/persist"
|
||||
env:
|
||||
global:
|
||||
- MAKEOPTS="-j4"
|
||||
git:
|
||||
submodules: false
|
||||
|
||||
# define the successive stages
|
||||
stages:
|
||||
- name: test
|
||||
before_script:
|
||||
- sudo add-apt-repository -y ppa:fkrull/deadsnakes
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-arm-none-eabi qemu-system mingw32
|
||||
# For teensy build
|
||||
- sudo apt-get install realpath
|
||||
|
||||
# define the jobs for the stages
|
||||
# order of the jobs has longest running first to optimise total time
|
||||
jobs:
|
||||
include:
|
||||
# stm32 port
|
||||
- stage: test
|
||||
env: NAME="stm32 port build"
|
||||
install:
|
||||
# need newer gcc version for Cortex-M7 support
|
||||
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
|
||||
- sudo apt-get update -qq || true
|
||||
- sudo apt-get install gcc-arm-embedded
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
- arm-none-eabi-gcc --version
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/stm32 submodules
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1'
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=B_L072Z_LRWAN1
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=STM32L476DISC
|
||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55
|
||||
- make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6
|
||||
script:
|
||||
- make -C unix CC=gcc-4.7
|
||||
- make -C unix-cpy CC=gcc-4.7
|
||||
- make -C bare-arm
|
||||
- make -C qemu-arm
|
||||
- make -C stmhal
|
||||
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||
- make -C stmhal BOARD=STM32F4DISC
|
||||
- make -C teensy
|
||||
- make -C windows CROSS_COMPILE=i586-mingw32msvc-
|
||||
|
||||
# qemu-arm port
|
||||
- stage: test
|
||||
env: NAME="qemu-arm port build and tests"
|
||||
install:
|
||||
- sudo apt-get install gcc-arm-none-eabi
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
- sudo apt-get install qemu-system
|
||||
- arm-none-eabi-gcc --version
|
||||
- qemu-system-arm --version
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test
|
||||
after_failure:
|
||||
- grep "FAIL" ports/qemu-arm/build/console.out
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests --emit native)
|
||||
|
||||
# unix coverage
|
||||
- stage: test
|
||||
env: NAME="unix coverage build and tests"
|
||||
install:
|
||||
- sudo apt-get install python3-pip
|
||||
- sudo pip install cpp-coveralls
|
||||
- sudo pip3 install setuptools
|
||||
- sudo pip3 install pyelftools
|
||||
- gcc --version
|
||||
- python3 --version
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/unix submodules
|
||||
- make ${MAKEOPTS} -C ports/unix deplibs
|
||||
- make ${MAKEOPTS} -C ports/unix coverage
|
||||
# run the main test suite
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -d thread)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --emit native)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy -d basics float micropython)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy --emit native -d basics float micropython)
|
||||
# test when input script comes from stdin
|
||||
- cat tests/basics/0prelim.py | ports/unix/micropython_coverage | grep -q 'abc'
|
||||
# test building native mpy modules
|
||||
- make -C examples/natmod/features1 ARCH=x64
|
||||
- make -C examples/natmod/features2 ARCH=x64
|
||||
- make -C examples/natmod/btree ARCH=x64
|
||||
- make -C examples/natmod/framebuf ARCH=x64
|
||||
- make -C examples/natmod/uheapq ARCH=x64
|
||||
- make -C examples/natmod/urandom ARCH=x64
|
||||
- make -C examples/natmod/ure ARCH=x64
|
||||
- make -C examples/natmod/uzlib ARCH=x64
|
||||
# test importing .mpy generated by mpy_ld.py
|
||||
- MICROPYPATH=examples/natmod/features2 ./ports/unix/micropython_coverage -m features2
|
||||
- (cd tests && ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py)
|
||||
# run coveralls coverage analysis (try to, even if some builds/tests failed)
|
||||
- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod)
|
||||
after_failure:
|
||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
||||
|
||||
# standard unix port
|
||||
- stage: test
|
||||
env: NAME="unix port build and tests"
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/unix submodules
|
||||
- make ${MAKEOPTS} -C ports/unix deplibs
|
||||
- make ${MAKEOPTS} -C ports/unix
|
||||
- make ${MAKEOPTS} -C ports/unix test
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython ./run-perfbench.py 1000 1000)
|
||||
|
||||
# unix nanbox (and using Python 2 to check it can run the build scripts)
|
||||
- stage: test
|
||||
env: NAME="unix nanbox port build and tests"
|
||||
install:
|
||||
- sudo apt-get install gcc-multilib libffi-dev:i386
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross PYTHON=python2
|
||||
- make ${MAKEOPTS} -C ports/unix submodules
|
||||
- make ${MAKEOPTS} -C ports/unix PYTHON=python2 deplibs
|
||||
- make ${MAKEOPTS} -C ports/unix PYTHON=python2 nanbox
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_nanbox ./run-tests)
|
||||
|
||||
# unix stackless
|
||||
- stage: test
|
||||
env: NAME="unix stackless port build and tests with clang"
|
||||
install:
|
||||
- sudo apt-get install clang
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross CC=clang
|
||||
- make ${MAKEOPTS} -C ports/unix submodules
|
||||
- make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1"
|
||||
- make ${MAKEOPTS} -C ports/unix CC=clang test
|
||||
|
||||
# unix with sys.settrace
|
||||
- stage: test
|
||||
env: NAME="unix port with sys.settrace build and tests"
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_PY_SYS_SETTRACE=1" test
|
||||
- make ${MAKEOPTS} -C ports/unix clean
|
||||
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" test
|
||||
after_failure:
|
||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
||||
|
||||
# minimal unix port with tests
|
||||
- stage: test
|
||||
env: NAME="minimal unix port build and tests"
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/unix minimal
|
||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_minimal ./run-tests -e exception_chain -e self_type_check -e subclass_native_init -d basics)
|
||||
|
||||
# windows port via mingw
|
||||
- stage: test
|
||||
env: NAME="windows port build via mingw"
|
||||
install:
|
||||
- sudo apt-get install gcc-mingw-w64
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32-
|
||||
|
||||
# esp32 port
|
||||
- stage: test
|
||||
env: NAME="esp32 port build"
|
||||
install:
|
||||
- sudo apt-get install python3-pip
|
||||
- sudo pip3 install 'pyparsing<2.4'
|
||||
- wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
|
||||
- zcat xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz | tar x
|
||||
- export PATH=$(pwd)/xtensa-esp32-elf/bin:$PATH
|
||||
- git clone https://github.com/espressif/esp-idf.git
|
||||
- export IDF_PATH=$(pwd)/esp-idf
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
# IDF v3 build
|
||||
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V3 :=" ports/esp32/Makefile | cut -d " " -f 3)
|
||||
- git -C esp-idf submodule update --init components/json/cJSON components/esp32/lib components/esptool_py/esptool components/expat/expat components/lwip/lwip components/mbedtls/mbedtls components/micro-ecc/micro-ecc components/nghttp/nghttp2
|
||||
- make ${MAKEOPTS} -C ports/esp32 submodules
|
||||
- make ${MAKEOPTS} -C ports/esp32
|
||||
# clean
|
||||
- git -C esp-idf clean -f -f -d components/json/cJSON components/esp32/lib components/expat/expat components/micro-ecc/micro-ecc components/nghttp/nghttp2
|
||||
- make ${MAKEOPTS} -C ports/esp32 clean
|
||||
# IDF v4 build
|
||||
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V4 :=" ports/esp32/Makefile | cut -d " " -f 3)
|
||||
- git -C esp-idf submodule update --init components/bt/controller/lib components/bt/host/nimble/nimble components/esp_wifi/lib_esp32 components/esptool_py/esptool components/lwip/lwip components/mbedtls/mbedtls
|
||||
- make ${MAKEOPTS} -C ports/esp32 submodules
|
||||
- make ${MAKEOPTS} -C ports/esp32
|
||||
|
||||
# esp8266 port
|
||||
- stage: test
|
||||
env: NAME="esp8266 port build"
|
||||
install:
|
||||
- wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz
|
||||
- zcat xtensa-lx106-elf-standalone.tar.gz | tar x
|
||||
- export PATH=$(pwd)/xtensa-lx106-elf/bin:$PATH
|
||||
script:
|
||||
- make ${MAKEOPTS} -C mpy-cross
|
||||
- make ${MAKEOPTS} -C ports/esp8266 submodules
|
||||
- make ${MAKEOPTS} -C ports/esp8266
|
||||
- make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_512K
|
||||
|
||||
# nrf port
|
||||
- stage: test
|
||||
env: NAME="nrf port build"
|
||||
install:
|
||||
- sudo apt-get install gcc-arm-none-eabi
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
- arm-none-eabi-gcc --version
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/nrf submodules
|
||||
- make ${MAKEOPTS} -C ports/nrf
|
||||
|
||||
# bare-arm and minimal ports
|
||||
- stage: test
|
||||
env: NAME="bare-arm and minimal ports build"
|
||||
install:
|
||||
- sudo apt-get install gcc-arm-none-eabi
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
- arm-none-eabi-gcc --version
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/bare-arm
|
||||
- make ${MAKEOPTS} -C ports/minimal CROSS=1 build/firmware.bin
|
||||
- ls -l ports/minimal/build/firmware.bin
|
||||
- tools/check_code_size.sh
|
||||
- mkdir -p ${HOME}/persist
|
||||
# Save new firmware for reference, but only if building a main branch, not a pull request
|
||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cp ports/minimal/build/firmware.bin ${HOME}/persist/; fi'
|
||||
|
||||
# cc3200 port
|
||||
- stage: test
|
||||
env: NAME="cc3200 port build"
|
||||
install:
|
||||
- sudo apt-get install gcc-arm-none-eabi
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/cc3200 BTARGET=application BTYPE=release
|
||||
- make ${MAKEOPTS} -C ports/cc3200 BTARGET=bootloader BTYPE=release
|
||||
|
||||
# samd port
|
||||
- stage: test
|
||||
env: NAME="samd port build"
|
||||
install:
|
||||
- sudo apt-get install gcc-arm-none-eabi
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/samd submodules
|
||||
- make ${MAKEOPTS} -C ports/samd
|
||||
|
||||
# teensy port
|
||||
- stage: test
|
||||
env: NAME="teensy port build"
|
||||
install:
|
||||
- sudo apt-get install gcc-arm-none-eabi
|
||||
- sudo apt-get install libnewlib-arm-none-eabi
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/teensy
|
||||
|
||||
# powerpc port
|
||||
- stage: test
|
||||
env: NAME="powerpc port build"
|
||||
install:
|
||||
- sudo apt-get install gcc-powerpc64le-linux-gnu
|
||||
- sudo apt-get install libc6-dev-ppc64el-cross
|
||||
script:
|
||||
- make ${MAKEOPTS} -C ports/powerpc CROSS_COMPILE=powerpc64le-linux-gnu-
|
||||
after_failure:
|
||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
||||
|
|
1764
ACKNOWLEDGEMENTS
1764
ACKNOWLEDGEMENTS
File diff suppressed because it is too large
Load Diff
|
@ -1,52 +1,3 @@
|
|||
Git commit conventions
|
||||
======================
|
||||
|
||||
Each commit message should start with a directory or full file path
|
||||
prefix, so it was clear which part of codebase a commit affects. If
|
||||
a change affects one file, it's better to use path to a file. If it
|
||||
affects few files in a subdirectory, using subdirectory as a prefix
|
||||
is ok. For longish paths, it's acceptable to drop intermediate
|
||||
components, which still should provide good context of a change.
|
||||
It's also ok to drop file extensions.
|
||||
|
||||
Besides prefix, first line of a commit message should describe a
|
||||
change clearly and to the point, and be a grammatical sentence with
|
||||
final full stop. First line should fit within 78 characters. Examples
|
||||
of good first line of commit messages:
|
||||
|
||||
py/objstr: Add splitlines() method.
|
||||
py: Rename FOO to BAR.
|
||||
docs/machine: Fix typo in reset() description.
|
||||
ports: Switch to use lib/foo instead of duplicated code.
|
||||
|
||||
After the first line, add an empty line and in following lines describe
|
||||
a change in a detail, if needed. Any change beyond 5 lines would likely
|
||||
require such detailed description.
|
||||
|
||||
To get good practical examples of good commits and their messages, browse
|
||||
the `git log` of the project.
|
||||
|
||||
MicroPython doesn't require explicit sign-off for patches ("Signed-off-by"
|
||||
lines and similar). Instead, the commit message, and your name and email
|
||||
address on it construes your sign-off of the following:
|
||||
|
||||
* That you wrote the change yourself, or took it from a project with
|
||||
a compatible license (in the latter case the commit message, and possibly
|
||||
source code should provide reference where the implementation was taken
|
||||
from and give credit to the original author, as required by the license).
|
||||
* That you are allowed to release these changes to an open-source project
|
||||
(for example, changes done during paid work for a third party may require
|
||||
explicit approval from that third party).
|
||||
* That you (or your employer) agree to release the changes under
|
||||
MicroPython's license, which is the MIT license. Note that you retain
|
||||
copyright for your changes (for smaller changes, the commit message
|
||||
conveys your copyright; if you make significant changes to a particular
|
||||
source module, you're welcome to add your name to the file header).
|
||||
* Your signature for all of the above, which is the 'Author' line in
|
||||
the commit message, and which should include your full real name and
|
||||
a valid and active email address by which you can be contacted in the
|
||||
foreseeable future.
|
||||
|
||||
Python code conventions
|
||||
=======================
|
||||
|
||||
|
@ -73,7 +24,7 @@ White space:
|
|||
keyword and the opening parenthesis.
|
||||
- Put 1 space after a comma, and 1 space around operators.
|
||||
|
||||
Braces:
|
||||
Braces:
|
||||
- Use braces for all blocks, even no-line and single-line pieces of
|
||||
code.
|
||||
- Put opening braces on the end of the line it belongs to, not on
|
||||
|
@ -82,50 +33,37 @@ Braces:
|
|||
closing brace.
|
||||
|
||||
Header files:
|
||||
- Header files should be protected from multiple inclusion with #if
|
||||
directives. See an existing header for naming convention.
|
||||
- Try to stick to the Plan 9 header style, where header files do not
|
||||
include other header files.
|
||||
- Don't protect a header file from multiple inclusion with #if directives.
|
||||
|
||||
Names:
|
||||
- Use underscore_case, not camelCase for all names.
|
||||
- Use CAPS_WITH_UNDERSCORE for enums and macros.
|
||||
- When defining a type use underscore_case and put '_t' after it.
|
||||
Type names and declarations:
|
||||
- When defining a type, put '_t' after it.
|
||||
|
||||
Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's
|
||||
important to use the correctly-sized (and signed) integer types. The
|
||||
general guidelines are:
|
||||
Integer types: Micro Python runs on 32 and 64 bit machines (and one day
|
||||
maybe 16 bit), so it's important to use the correctly-sized (and signed)
|
||||
integer types. The general guidelines are:
|
||||
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
|
||||
integer values. These are guaranteed to be machine-word sized and
|
||||
therefore big enough to hold the value from a MicroPython small-int
|
||||
therefore big enough to hold the value from a Micro Python small-int
|
||||
object.
|
||||
- Use size_t for things that count bytes / sizes of objects.
|
||||
- You can use int/uint, but remember that they may be 16-bits wide.
|
||||
- If in doubt, use mp_int_t/mp_uint_t.
|
||||
|
||||
Comments:
|
||||
- Be concise and only write comments for things that are not obvious.
|
||||
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
|
||||
|
||||
Memory allocation:
|
||||
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
|
||||
These macros are defined in py/misc.h.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Braces, spaces, names and comments:
|
||||
Braces and spaces:
|
||||
|
||||
#define TO_ADD (123)
|
||||
|
||||
// This function will always recurse indefinitely and is only used to show
|
||||
// coding style
|
||||
int foo_function(int x, int some_value) {
|
||||
if (x < some_value) {
|
||||
foo(some_value, x);
|
||||
int foo(int x, int y) {
|
||||
if (x < y) {
|
||||
foo(y, x);
|
||||
} else {
|
||||
foo(x + TO_ADD, some_value - 1);
|
||||
foo(x + 1, y - 1);
|
||||
}
|
||||
|
||||
for (int my_counter = 0; my_counter < x; my_counter++) {
|
||||
for (int i = 0; i < x; i++) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,76 +73,3 @@ Type declarations:
|
|||
int member;
|
||||
void *data;
|
||||
} my_struct_t;
|
||||
|
||||
Documentation conventions
|
||||
=========================
|
||||
|
||||
MicroPython generally follows CPython in documentation process and
|
||||
conventions. reStructuredText syntax is used for the documention.
|
||||
|
||||
Specific conventions/suggestions:
|
||||
|
||||
* Use `*` markup to refer to arguments of a function, e.g.:
|
||||
|
||||
```
|
||||
.. method:: poll.unregister(obj)
|
||||
|
||||
Unregister *obj* from polling.
|
||||
```
|
||||
|
||||
* Use following syntax for cross-references/cross-links:
|
||||
|
||||
```
|
||||
:func:`foo` - function foo in current module
|
||||
:func:`module1.foo` - function foo in module "module1"
|
||||
(similarly for other referent types)
|
||||
:class:`Foo` - class Foo
|
||||
:meth:`Class.method1` - method1 in Class
|
||||
:meth:`~Class.method1` - method1 in Class, but rendered just as "method1()",
|
||||
not "Class.method1()"
|
||||
:meth:`title <method1>` - reference method1, but render as "title" (use only
|
||||
if really needed)
|
||||
:mod:`module1` - module module1
|
||||
|
||||
`symbol` - generic xref syntax which can replace any of the above in case
|
||||
the xref is unambiguous. If there's ambiguity, there will be a warning
|
||||
during docs generation, which need to be fixed using one of the syntaxes
|
||||
above
|
||||
```
|
||||
|
||||
* Cross-referencing arbitrary locations
|
||||
~~~
|
||||
.. _xref_target:
|
||||
|
||||
Normal non-indented text.
|
||||
|
||||
This is :ref:`reference <xref_target>`.
|
||||
|
||||
(If xref target is followed by section title, can be just
|
||||
:ref:`xref_target`).
|
||||
~~~
|
||||
|
||||
* Linking to external URL:
|
||||
```
|
||||
`link text <http://foo.com/...>`_
|
||||
```
|
||||
|
||||
* Referencing builtin singleton objects:
|
||||
```
|
||||
``None``, ``True``, ``False``
|
||||
```
|
||||
|
||||
* Use following syntax to create common description for more than one element:
|
||||
~~~
|
||||
.. function:: foo(x)
|
||||
bar(y)
|
||||
|
||||
Description common to foo() and bar().
|
||||
~~~
|
||||
|
||||
|
||||
More detailed guides and quickrefs:
|
||||
|
||||
* http://www.sphinx-doc.org/en/stable/rest.html
|
||||
* http://www.sphinx-doc.org/en/stable/markup/inline.html
|
||||
* http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
MicroPython Code of Conduct
|
||||
===========================
|
||||
|
||||
The MicroPython community is made up of members from around the globe with a
|
||||
diverse set of skills, personalities, and experiences. It is through these
|
||||
differences that our community experiences great successes and continued growth.
|
||||
When you're working with members of the community, this Code of Conduct will
|
||||
help steer your interactions and keep MicroPython a positive, successful, and
|
||||
growing community.
|
||||
|
||||
Members of the MicroPython community are open, considerate, and respectful.
|
||||
Behaviours that reinforce these values contribute to a positive environment, and
|
||||
include: acknowledging time and effort, being respectful of differing viewpoints
|
||||
and experiences, gracefully accepting constructive criticism, and using
|
||||
welcoming and inclusive language.
|
||||
|
||||
Every member of our community has the right to have their identity respected.
|
||||
The MicroPython community is dedicated to providing a positive experience for
|
||||
everyone, regardless of age, gender identity and expression, sexual orientation,
|
||||
disability, physical appearance, body size, ethnicity, nationality, race, or
|
||||
religion (or lack thereof), education, or socio-economic status.
|
||||
|
||||
Unacceptable behaviour includes: harassment, trolling, deliberate intimidation,
|
||||
violent threats or language directed against another person; insults, put downs,
|
||||
or jokes that are based upon stereotypes, that are exclusionary, or that hold
|
||||
others up for ridicule; unwelcome sexual attention or advances; sustained
|
||||
disruption of community discussions; publishing others' private information
|
||||
without explicit permission; and other conduct that is inappropriate for a
|
||||
professional audience including people of many different backgrounds.
|
||||
|
||||
This code of conduct covers all online and offline presence related to the
|
||||
MicroPython project, including GitHub and the forum. If a participant engages
|
||||
in behaviour that violates this code of conduct, the MicroPython team may take
|
||||
action as they deem appropriate, including warning the offender or expulsion
|
||||
from the community. Community members asked to stop any inappropriate behaviour
|
||||
are expected to comply immediately.
|
||||
|
||||
Thank you for helping make this a welcoming, friendly community for everyone.
|
||||
|
||||
If you believe that someone is violating the code of conduct, or have any other
|
||||
concerns, please contact a member of the MicroPython team by emailing
|
||||
contact@micropython.org.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
This Code of Conduct is licensed under the Creative Commons
|
||||
Attribution-ShareAlike 3.0 Unported License.
|
||||
|
||||
Attributions
|
||||
------------
|
||||
|
||||
Based on the Python code of conduct found at https://www.python.org/psf/conduct/
|
|
@ -1,8 +0,0 @@
|
|||
When reporting an issue and especially submitting a pull request, please
|
||||
make sure that you are acquainted with Contributor Guidelines:
|
||||
|
||||
https://github.com/micropython/micropython/wiki/ContributorGuidelines
|
||||
|
||||
and Code Conventions:
|
||||
|
||||
https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2019 Damien P. George
|
||||
Copyright (c) 2013, 2014 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
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
[![Build Status](https://travis-ci.org/micropython/micropython.png?branch=master)](https://travis-ci.org/micropython/micropython) [![Coverage Status](https://coveralls.io/repos/micropython/micropython/badge.png?branch=master)](https://coveralls.io/r/micropython/micropython?branch=master)
|
||||
|
||||
The MicroPython project
|
||||
=======================
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
|
||||
</p>
|
||||
|
||||
This is the MicroPython project, which aims to put an implementation
|
||||
of Python 3.x on microcontrollers and small embedded systems.
|
||||
You can find the official website at [micropython.org](http://www.micropython.org).
|
||||
|
||||
WARNING: this project is in beta stage and is subject to changes of the
|
||||
code-base, including project-wide name changes and API changes.
|
||||
|
||||
MicroPython implements the entire Python 3.4 syntax (including exceptions,
|
||||
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
|
||||
Python 3.5). The following core datatypes are provided: `str` (including
|
||||
basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`,
|
||||
`frozenset`, `array.array`, `collections.namedtuple`, classes and instances.
|
||||
Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have
|
||||
support for `_thread` module (multithreading). Note that only a subset of
|
||||
Python 3 functionality is implemented for the data types and modules.
|
||||
|
||||
MicroPython can execute scripts in textual source form or from precompiled
|
||||
bytecode, in both cases either from an on-device filesystem or "frozen" into
|
||||
the MicroPython executable.
|
||||
|
||||
See the repository http://github.com/micropython/pyboard for the MicroPython
|
||||
board (PyBoard), the officially supported reference electronic circuit board.
|
||||
|
||||
Major components in this repository:
|
||||
- py/ -- the core Python implementation, including compiler, runtime, and
|
||||
core library.
|
||||
- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts
|
||||
into precompiled bytecode.
|
||||
- ports/unix/ -- a version of MicroPython that runs on Unix.
|
||||
- ports/stm32/ -- a version of MicroPython that runs on the PyBoard and similar
|
||||
STM32 boards (using ST's Cube HAL drivers).
|
||||
- ports/minimal/ -- a minimal MicroPython port. Start with this if you want
|
||||
to port MicroPython to another microcontroller.
|
||||
- tests/ -- test framework and test scripts.
|
||||
- docs/ -- user documentation in Sphinx reStructuredText format. Rendered
|
||||
HTML documentation is available at http://docs.micropython.org.
|
||||
|
||||
Additional components:
|
||||
- ports/bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used
|
||||
mostly to control code size.
|
||||
- ports/teensy/ -- a version of MicroPython that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- ports/pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
|
||||
- ports/cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
|
||||
- ports/esp8266/ -- a version of MicroPython that runs on Espressif's ESP8266 SoC.
|
||||
- ports/esp32/ -- a version of MicroPython that runs on Espressif's ESP32 SoC.
|
||||
- ports/nrf/ -- a version of MicroPython that runs on Nordic's nRF51 and nRF52 MCUs.
|
||||
- extmod/ -- additional (non-core) modules implemented in C.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
- examples/ -- a few example Python scripts.
|
||||
|
||||
The subdirectories above may include READMEs with additional info.
|
||||
|
||||
"make" is used to build the components, or "gmake" on BSD-based systems.
|
||||
You will also need bash, gcc, and Python 3.3+ available as the command `python3`
|
||||
(if your system only has Python 2.7 then invoke make with the additional option
|
||||
`PYTHON=python2`).
|
||||
|
||||
The MicroPython cross-compiler, mpy-cross
|
||||
-----------------------------------------
|
||||
|
||||
Most ports require the MicroPython cross-compiler to be built first. This
|
||||
program, called mpy-cross, is used to pre-compile Python scripts to .mpy
|
||||
files which can then be included (frozen) into the firmware/executable for
|
||||
a port. To build mpy-cross use:
|
||||
|
||||
$ cd mpy-cross
|
||||
$ make
|
||||
|
||||
The Unix version
|
||||
----------------
|
||||
|
||||
The "unix" port requires a standard Unix environment with gcc and GNU make.
|
||||
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
|
||||
as ARM and MIPS. Making full-featured port to another architecture requires
|
||||
writing some assembly code for the exception handling and garbage collection.
|
||||
Alternatively, fallback implementation based on setjmp/longjmp can be used.
|
||||
|
||||
To build (see section below for required dependencies):
|
||||
|
||||
$ cd ports/unix
|
||||
$ make submodules
|
||||
$ make
|
||||
|
||||
Then to give it a try:
|
||||
|
||||
$ ./micropython
|
||||
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
|
||||
|
||||
Use `CTRL-D` (i.e. EOF) to exit the shell.
|
||||
Learn about command-line options (in particular, how to increase heap size
|
||||
which may be needed for larger applications):
|
||||
|
||||
$ ./micropython --help
|
||||
|
||||
Run complete testsuite:
|
||||
|
||||
$ make test
|
||||
|
||||
Unix version comes with a builtin package manager called upip, e.g.:
|
||||
|
||||
$ ./micropython -m upip install micropython-pystone
|
||||
$ ./micropython -m pystone
|
||||
|
||||
Browse available modules on
|
||||
[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython).
|
||||
Standard library modules come from
|
||||
[micropython-lib](https://github.com/micropython/micropython-lib) project.
|
||||
|
||||
External dependencies
|
||||
---------------------
|
||||
|
||||
Building MicroPython ports may require some dependencies installed.
|
||||
|
||||
For Unix port, `libffi` library and `pkg-config` tool are required. On
|
||||
Debian/Ubuntu/Mint derivative Linux distros, install `build-essential`
|
||||
(includes toolchain and make), `libffi-dev`, and `pkg-config` packages.
|
||||
|
||||
Other dependencies can be built together with MicroPython. This may
|
||||
be required to enable extra features or capabilities, and in recent
|
||||
versions of MicroPython, these may be enabled by default. To build
|
||||
these additional dependencies, in the port directory you're
|
||||
interested in (e.g. `ports/unix/`) first execute:
|
||||
|
||||
$ make submodules
|
||||
|
||||
This will fetch all the relevant git submodules (sub repositories) that
|
||||
the port needs. Use the same command to get the latest versions of
|
||||
submodules as they are updated from time to time. After that execute:
|
||||
|
||||
$ make deplibs
|
||||
|
||||
This will build all available dependencies (regardless whether they
|
||||
are used or not). If you intend to build MicroPython with additional
|
||||
options (like cross-compiling), the same set of options should be passed
|
||||
to `make deplibs`. To actually enable/disable use of dependencies, edit
|
||||
`ports/unix/mpconfigport.mk` file, which has inline descriptions of the options.
|
||||
For example, to build SSL module (required for `upip` tool described above,
|
||||
and so enabled by dfeault), `MICROPY_PY_USSL` should be set to 1.
|
||||
|
||||
For some ports, building required dependences is transparent, and happens
|
||||
automatically. But they still need to be fetched with the `make submodules`
|
||||
command.
|
||||
|
||||
The STM32 version
|
||||
-----------------
|
||||
|
||||
The "stm32" port requires an ARM compiler, arm-none-eabi-gcc, and associated
|
||||
bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils,
|
||||
arm-none-eabi-gcc and arm-none-eabi-newlib packages. Otherwise, try here:
|
||||
https://launchpad.net/gcc-arm-embedded
|
||||
|
||||
To build:
|
||||
|
||||
$ cd ports/stm32
|
||||
$ make submodules
|
||||
$ make
|
||||
|
||||
You then need to get your board into DFU mode. On the pyboard, connect the
|
||||
3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other
|
||||
on the bottom left of the board, second row from the bottom).
|
||||
|
||||
Then to flash the code via USB DFU to your device:
|
||||
|
||||
$ make deploy
|
||||
|
||||
This will use the included `tools/pydfu.py` script. If flashing the firmware
|
||||
does not work it may be because you don't have the correct permissions, and
|
||||
need to use `sudo make deploy`.
|
||||
See the README.md file in the ports/stm32/ directory for further details.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
MicroPython is an open-source project and welcomes contributions. To be
|
||||
productive, please be sure to follow the
|
||||
[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines)
|
||||
and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md).
|
||||
Note that MicroPython is licenced under the MIT license, and all contributions
|
||||
should follow this license.
|
117
README.md
117
README.md
|
@ -1,4 +1,115 @@
|
|||
# Micropython for jebbatime
|
||||
This is a lesser fork of Daniel Thompson's fork of Micropython.
|
||||
It is for the Pinetime watch.
|
||||
[![Build Status][travis-img]][travis-repo]
|
||||
[travis-img]: https://travis-ci.org/micropython/micropython.png?branch=master
|
||||
[travis-repo]: https://travis-ci.org/micropython/micropython
|
||||
|
||||
The Micro Python project
|
||||
========================
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
|
||||
</p>
|
||||
|
||||
This is the Micro Python project, which aims to put an implementation
|
||||
of Python 3.x on a microcontroller.
|
||||
|
||||
WARNING: this project is in early beta stage and is subject to large
|
||||
changes of the code-base, including project-wide name changes and API
|
||||
changes.
|
||||
|
||||
Micro Python implements the entire Python 3.4 syntax (including exceptions,
|
||||
"with", "yield from", etc.). The following core datatypes are provided:
|
||||
str (no Unicode support yet), bytes, bytearray, tuple, list, dict, set,
|
||||
array.array, collections.namedtuple, classes and instances. Builtin
|
||||
modules include sys, time, and struct. Note that only subset of
|
||||
Python 3.4 functionality implemented for the data types and modules.
|
||||
|
||||
See the repository www.github.com/micropython/pyboard for the Micro
|
||||
Python board, the officially supported reference electronic circuit board.
|
||||
|
||||
Major components in this repository:
|
||||
- py/ -- the core Python implementation, including compiler and runtime.
|
||||
- unix/ -- a version of Micro Python that runs on Unix.
|
||||
- stmhal/ -- a version of Micro Python that runs on the Micro Python board
|
||||
with an STM32F405RG (using ST's Cube HAL drivers).
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
|
||||
Additional components:
|
||||
- bare-arm/ -- a bare minimum version of Micro Python for ARM MCUs. Start
|
||||
with this if you want to port Micro Python to another microcontroller.
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- tests/ -- test framework and test scripts.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
- examples/ -- a few example Python scripts.
|
||||
|
||||
"make" is used to build the components, or "gmake" on BSD-based systems.
|
||||
You will also need bash and Python (at least 2.7 or 3.3).
|
||||
|
||||
The Unix version
|
||||
----------------
|
||||
|
||||
The "unix" port requires a standard Unix environment with gcc and GNU make.
|
||||
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
|
||||
as ARM and MIPS. Making full-featured port to another architecture requires
|
||||
writing some assembly code for the exception handling and garbage collection.
|
||||
Alternatively, fallback implementation based on setjmp/longjmp can be used.
|
||||
|
||||
To build:
|
||||
|
||||
$ cd unix
|
||||
$ make
|
||||
|
||||
Then to give it a try:
|
||||
|
||||
$ ./micropython
|
||||
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
|
||||
|
||||
Run complete testsuite:
|
||||
|
||||
$ make test
|
||||
|
||||
Debian/Ubuntu/Mint derivative Linux distros will require build-essentials and
|
||||
libreadline-dev packages installed. To build FFI (Foreign Function Interface)
|
||||
module, libffi-dev and pkg-config packages are required. If you have problems
|
||||
with some dependencies, they can be disabled in unix/mpconfigport.mk .
|
||||
|
||||
The STM version
|
||||
---------------
|
||||
|
||||
The "stmhal" port requires an ARM compiler, arm-none-eabi-gcc, and associated
|
||||
bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils and
|
||||
arm-none-eabi-gcc packages from the AUR. Otherwise, try here:
|
||||
https://launchpad.net/gcc-arm-embedded
|
||||
|
||||
To build:
|
||||
|
||||
$ cd stmhal
|
||||
$ make
|
||||
|
||||
You then need to get your board into DFU mode. On the pyboard, connect the
|
||||
3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other
|
||||
on the bottom left of the board, second row from the bottom).
|
||||
|
||||
Then to flash the code via USB DFU to your device:
|
||||
|
||||
$ make deploy
|
||||
|
||||
You will need the dfu-util program, on Arch Linux it's dfu-util-git in the
|
||||
AUR. If the above does not work it may be because you don't have the
|
||||
correct permissions. Try then:
|
||||
|
||||
$ sudo dfu-util -a 0 -d 0483:df11 -D build-PYBV10/firmware.dfu
|
||||
|
||||
Building the documentation locally
|
||||
----------------------------------
|
||||
|
||||
Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme,
|
||||
preferably in a virtualenv:
|
||||
|
||||
pip install sphinx
|
||||
pip install sphinx_rtd_theme
|
||||
|
||||
In `micropython/docs`, build the docs:
|
||||
|
||||
make html
|
||||
|
||||
You'll find the index page at `micropython/docs/build/html/index.html`.
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
include ../py/mkenv.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
INC = -I.
|
||||
INC += -I..
|
||||
INC += -I$(PY_SRC)
|
||||
INC += -I$(BUILD)
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
||||
|
||||
#Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -O0 -ggdb
|
||||
else
|
||||
CFLAGS += -Os -DNDEBUG
|
||||
endif
|
||||
|
||||
LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref
|
||||
LIBS =
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
# printf.c \
|
||||
string0.c \
|
||||
malloc0.c \
|
||||
gccollect.c \
|
||||
|
||||
SRC_S = \
|
||||
# startup_stm32f40xx.s \
|
||||
gchelper.s \
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o))
|
||||
|
||||
all: $(BUILD)/firmware.elf
|
||||
|
||||
$(BUILD)/firmware.elf: $(OBJ)
|
||||
$(ECHO) "LINK $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
include ../py/mkrules.mk
|
|
@ -0,0 +1,128 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "parsehelper.h"
|
||||
#include "compile.h"
|
||||
#include "runtime0.h"
|
||||
#include "runtime.h"
|
||||
#include "repl.h"
|
||||
#include "pfenv.h"
|
||||
|
||||
void do_str(const char *src) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mp_parse_error_kind_t parse_error_kind;
|
||||
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind);
|
||||
|
||||
if (pn == MP_PARSE_NODE_NULL) {
|
||||
// parse error
|
||||
mp_parse_show_exception(lex, parse_error_kind);
|
||||
mp_lexer_free(lex);
|
||||
return;
|
||||
}
|
||||
|
||||
// parse okay
|
||||
qstr source_name = lex->source_name;
|
||||
mp_lexer_free(lex);
|
||||
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
|
||||
|
||||
if (mp_obj_is_exception_instance(module_fun)) {
|
||||
// compile error
|
||||
mp_obj_print_exception(printf_wrapper, NULL, module_fun);
|
||||
return;
|
||||
}
|
||||
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_call_function_0(module_fun);
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
mp_init();
|
||||
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\n')");
|
||||
mp_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
while (1);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||
__fatal_error("Assertion failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
int _lseek() {return 0;}
|
||||
int _read() {return 0;}
|
||||
int _write() {return 0;}
|
||||
int _close() {return 0;}
|
||||
void _exit(int x) {for(;;){}}
|
||||
int _sbrk() {return 0;}
|
||||
int _kill() {return 0;}
|
||||
int _getpid() {return 0;}
|
||||
int _fstat() {return 0;}
|
||||
int _isatty() {return 0;}
|
||||
*/
|
||||
|
||||
void *malloc(size_t n) {return NULL;}
|
||||
void *calloc(size_t nmemb, size_t size) {return NULL;}
|
||||
void *realloc(void *ptr, size_t size) {return NULL;}
|
||||
void free(void *p) {}
|
||||
int printf(const char *m, ...) {return 0;}
|
||||
void *memcpy(void *dest, const void *src, size_t n) {return NULL;}
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {return 0;}
|
||||
void *memmove(void *dest, const void *src, size_t n) {return NULL;}
|
||||
void *memset(void *s, int c, size_t n) {return NULL;}
|
||||
int strcmp(const char *s1, const char* s2) {return 0;}
|
||||
int strncmp(const char *s1, const char* s2, size_t n) {return 0;}
|
||||
size_t strlen(const char *s) {return 0;}
|
||||
char *strcat(char *dest, const char *src) {return NULL;}
|
||||
char *strchr(const char *dest, int c) {return NULL;}
|
||||
#include <stdarg.h>
|
||||
int vprintf(const char *format, va_list ap) {return 0;}
|
||||
int vsnprintf(char *str, size_t size, const char *format, va_list ap) {return 0;}
|
||||
|
||||
#undef putchar
|
||||
int putchar(int c) {return 0;}
|
||||
int puts(const char *s) {return 0;}
|
||||
|
||||
void _start(void) {main(0, NULL);}
|
|
@ -0,0 +1,57 @@
|
|||
#include <stdint.h>
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_ALLOC_PATH_MAX (512)
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (0)
|
||||
#define MICROPY_HELPER_REPL (0)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (0)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_GC (0)
|
||||
#define MICROPY_PY_ARRAY (0)
|
||||
#define MICROPY_PY_COLLECTIONS (0)
|
||||
#define MICROPY_PY_MATH (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (0)
|
||||
#define MICROPY_PY_STRUCT (0)
|
||||
#define MICROPY_PY_SYS (0)
|
||||
#define MICROPY_CPYTHON_COMPAT (0)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define BYTES_PER_WORD (4)
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||
|
||||
#define UINT_FMT "%lu"
|
||||
#define INT_FMT "%ld"
|
||||
|
||||
typedef int32_t mp_int_t; // must be pointer size
|
||||
typedef uint32_t mp_uint_t; // must be pointer size
|
||||
typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
typedef long mp_off_t;
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
GNU linker script for STM32F405
|
||||
*/
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
|
||||
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */
|
||||
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x080000 /* sectors 5,6,7,8, 4*128KiB = 512 KiB (could increase it more) */
|
||||
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
|
||||
}
|
||||
|
||||
/* top end of the stack */
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
|
||||
/* RAM extents for the garbage collector */
|
||||
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_heap_end = 0x2001c000; /* tunable */
|
||||
|
||||
/* define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
|
||||
. = ALIGN(4);
|
||||
} >FLASH_ISR
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
/* *(.glue_7) */ /* glue arm to thumb code */
|
||||
/* *(.glue_7t) */ /* glue thumb to arm code */
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbol at end of code */
|
||||
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
|
||||
} >FLASH_TEXT
|
||||
|
||||
/*
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} >FLASH
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
*/
|
||||
|
||||
/* This is the initialized data section
|
||||
The program executes knowing that the data is in the RAM
|
||||
but the loader puts the initial values in the FLASH (inidata).
|
||||
It is one task of the startup to copy the initial values from FLASH to RAM. */
|
||||
.data : AT ( _sidata )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
|
||||
_ram_start = .; /* create a global symbol at ram start for garbage collector */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
|
||||
} >RAM
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sbss = .; /* define a global symbol at bss start; used by startup code */
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end; used by startup code */
|
||||
} >RAM
|
||||
|
||||
/* this is to define the start of the heap, and make sure we have a minimum size */
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_heap_start = .; /* define a global symbol at heap start */
|
||||
} >RAM
|
||||
|
||||
/* this just checks there is enough RAM for the stack */
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* Remove information from the standard libraries */
|
||||
/*
|
||||
/DISCARD/ :
|
||||
{
|
||||
libc.a ( * )
|
||||
libm.a ( * )
|
||||
libgcc.a ( * )
|
||||
}
|
||||
*/
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
|
@ -2,17 +2,10 @@
|
|||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
PYTHON = python3
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build/$(MICROPY_PORT)
|
||||
CPYDIFFDIR = ../tools
|
||||
CPYDIFF = gen-cpydiff.py
|
||||
GENRSTDIR = genrst
|
||||
# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk
|
||||
# producing incorrect docs).
|
||||
FORCE = -E
|
||||
BUILDDIR = build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
|
@ -52,19 +45,12 @@ help:
|
|||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " cpydiff to generate the MicroPython differences from CPython"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
rm -f $(GENRSTDIR)/*
|
||||
|
||||
cpydiff:
|
||||
@echo "Generating MicroPython Differences."
|
||||
rm -f $(GENRSTDIR)/*
|
||||
cd $(CPYDIFFDIR) && $(PYTHON) $(CPYDIFF)
|
||||
|
||||
html: cpydiff
|
||||
$(SPHINXBUILD) $(FORCE) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
|
@ -117,20 +103,20 @@ epub:
|
|||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex: cpydiff
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf: cpydiff
|
||||
$(SPHINXBUILD) $(FORCE) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja: cpydiff
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
MicroPython Documentation
|
||||
=========================
|
||||
|
||||
The MicroPython documentation can be found at:
|
||||
http://docs.micropython.org/en/latest/
|
||||
|
||||
The documentation you see there is generated from the files in the docs tree:
|
||||
https://github.com/micropython/micropython/tree/master/docs
|
||||
|
||||
Building the documentation locally
|
||||
----------------------------------
|
||||
|
||||
If you're making changes to the documentation, you may want to build the
|
||||
documentation locally so that you can preview your changes.
|
||||
|
||||
Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme,
|
||||
preferably in a virtualenv:
|
||||
|
||||
pip install sphinx
|
||||
pip install sphinx_rtd_theme
|
||||
|
||||
In `micropython/docs`, build the docs:
|
||||
|
||||
make html
|
||||
|
||||
You'll find the index page at `micropython/docs/build/html/index.html`.
|
||||
|
||||
PDF manual generation
|
||||
---------------------
|
||||
|
||||
This can be achieved with:
|
||||
|
||||
make latexpdf
|
||||
|
||||
but require rather complete install of LaTeX with various extensions. On
|
||||
Debian/Ubuntu, try (500MB+ download):
|
||||
|
||||
apt-get install texlive-latex-recommended texlive-latex-extra
|
60
docs/conf.py
60
docs/conf.py
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# MicroPython documentation build configuration file, created by
|
||||
# Micro Python documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Sep 21 11:42:03 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
|
@ -19,22 +19,7 @@ import os
|
|||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# The members of the html_context dict are available inside topindex.html
|
||||
micropy_version = os.getenv('MICROPY_VERSION') or 'latest'
|
||||
micropy_all_versions = (os.getenv('MICROPY_ALL_VERSIONS') or 'latest').split(',')
|
||||
url_pattern = '%s/en/%%s' % (os.getenv('MICROPY_URL_PREFIX') or '/',)
|
||||
html_context = {
|
||||
'cur_version':micropy_version,
|
||||
'all_versions':[
|
||||
(ver, url_pattern % ver) for ver in micropy_all_versions
|
||||
],
|
||||
'downloads':[
|
||||
('PDF', url_pattern % micropy_version + '/micropython-docs.pdf'),
|
||||
],
|
||||
}
|
||||
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
|
@ -65,16 +50,17 @@ source_suffix = '.rst'
|
|||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'MicroPython'
|
||||
copyright = '2014-2019, Damien P. George, Paul Sokolovsky, and contributors'
|
||||
project = 'Micro Python'
|
||||
copyright = '2014, Damien P. George'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags"
|
||||
# breakdown, so use the same version identifier for both to avoid confusion.
|
||||
version = release = '1.12'
|
||||
# The short X.Y version.
|
||||
version = '1.3'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.3.7'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -88,11 +74,11 @@ version = release = '1.12'
|
|||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['build', '.venv']
|
||||
exclude_patterns = ['build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
default_role = 'any'
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
@ -114,12 +100,6 @@ pygments_style = 'sphinx'
|
|||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
# Global include files. Sphinx docs suggest using rst_epilog in preference
|
||||
# of rst_prolog, so we follow. Absolute paths below mean "from the base
|
||||
# of the doctree".
|
||||
rst_epilog = """
|
||||
.. include:: /templates/replace.inc
|
||||
"""
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
|
@ -154,12 +134,12 @@ else:
|
|||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = '../../logo/trans-logo.png'
|
||||
#html_logo = '../logo/trans-logo.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
html_favicon = 'static/favicon.ico'
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
|
@ -227,16 +207,14 @@ latex_elements = {
|
|||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
# Include 3 levels of headers in PDF ToC
|
||||
'preamble': '\setcounter{tocdepth}{2}',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'MicroPython.tex', 'MicroPython Documentation',
|
||||
'Damien P. George, Paul Sokolovsky, and contributors', 'manual'),
|
||||
('index', 'MicroPython.tex', 'Micro Python Documentation',
|
||||
'Damien P. George', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
|
@ -265,8 +243,8 @@ latex_documents = [
|
|||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'micropython', 'MicroPython Documentation',
|
||||
['Damien P. George, Paul Sokolovsky, and contributors'], 1),
|
||||
('index', 'micropython', 'Micro Python Documentation',
|
||||
['Damien P. George'], 1),
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
|
@ -279,8 +257,8 @@ man_pages = [
|
|||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'MicroPython', 'MicroPython Documentation',
|
||||
'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.',
|
||||
('index', 'MicroPython', 'Micro Python Documentation',
|
||||
'Damien P. George', 'MicroPython', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
|
@ -298,4 +276,4 @@ texinfo_documents = [
|
|||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None)}
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
Micro Python documentation contents
|
||||
===================================
|
||||
|
||||
.. toctree::
|
||||
|
||||
quickref.rst
|
||||
general.rst
|
||||
tutorial/index.rst
|
||||
library/index.rst
|
||||
hardware/index.rst
|
||||
license.rst
|
|
@ -1,180 +0,0 @@
|
|||
.. _cmodules:
|
||||
|
||||
MicroPython external C modules
|
||||
==============================
|
||||
|
||||
When developing modules for use with MicroPython you may find you run into
|
||||
limitations with the Python environment, often due to an inability to access
|
||||
certain hardware resources or Python speed limitations.
|
||||
|
||||
If your limitations can't be resolved with suggestions in :ref:`speed_python`,
|
||||
writing some or all of your module in C is a viable option.
|
||||
|
||||
If your module is designed to access or work with commonly available
|
||||
hardware or libraries please consider implementing it inside the MicroPython
|
||||
source tree alongside similar modules and submitting it as a pull request.
|
||||
If however you're targeting obscure or proprietary systems it may make
|
||||
more sense to keep this external to the main MicroPython repository.
|
||||
|
||||
This chapter describes how to compile such external modules into the
|
||||
MicroPython executable or firmware image.
|
||||
|
||||
An alternative approach is to use :ref:`natmod` which allows writing custom C
|
||||
code that is placed in a .mpy file, which can be imported dynamically in to
|
||||
a running MicroPython system without the need to recompile the main firmware.
|
||||
|
||||
|
||||
Structure of an external C module
|
||||
---------------------------------
|
||||
|
||||
A MicroPython user C module is a directory with the following files:
|
||||
|
||||
* ``*.c`` and/or ``*.h`` source code files for your module.
|
||||
|
||||
These will typically include the low level functionality being implemented and
|
||||
the MicroPython binding functions to expose the functions and module(s).
|
||||
|
||||
Currently the best reference for writing these functions/modules is
|
||||
to find similar modules within the MicroPython tree and use them as examples.
|
||||
|
||||
* ``micropython.mk`` contains the Makefile fragment for this module.
|
||||
|
||||
``$(USERMOD_DIR)`` is available in ``micropython.mk`` as the path to your
|
||||
module directory. As it's redefined for each c module, is should be expanded
|
||||
in your ``micropython.mk`` to a local make variable,
|
||||
eg ``EXAMPLE_MOD_DIR := $(USERMOD_DIR)``
|
||||
|
||||
Your ``micropython.mk`` must add your modules C files relative to your
|
||||
expanded copy of ``$(USERMOD_DIR)`` to ``SRC_USERMOD``, eg
|
||||
``SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c``
|
||||
|
||||
If you have custom ``CFLAGS`` settings or include folders to define, these
|
||||
should be added to ``CFLAGS_USERMOD``.
|
||||
|
||||
See below for full usage example.
|
||||
|
||||
|
||||
Basic Example
|
||||
-------------
|
||||
|
||||
This simple module named ``example`` provides a single function
|
||||
``example.add_ints(a, b)`` which adds the two integer args together and returns
|
||||
the result.
|
||||
|
||||
Directory::
|
||||
|
||||
example/
|
||||
├── example.c
|
||||
└── micropython.mk
|
||||
|
||||
|
||||
``example.c``
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Include required definitions first.
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/builtin.h"
|
||||
|
||||
// This is the function which will be called from Python as example.add_ints(a, b).
|
||||
STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
|
||||
// Extract the ints from the micropython input objects
|
||||
int a = mp_obj_get_int(a_obj);
|
||||
int b = mp_obj_get_int(b_obj);
|
||||
|
||||
// Calculate the addition and convert to MicroPython object.
|
||||
return mp_obj_new_int(a + b);
|
||||
}
|
||||
// Define a Python reference to the function above
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
|
||||
|
||||
// Define all properties of the example module.
|
||||
// Table entries are key/value pairs of the attribute name (a string)
|
||||
// and the MicroPython object reference.
|
||||
// All identifiers and strings are written as MP_QSTR_xxx and will be
|
||||
// optimized to word-sized integers by the build system (interned strings).
|
||||
STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
|
||||
|
||||
// Define module object.
|
||||
const mp_obj_module_t example_user_cmodule = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&example_module_globals,
|
||||
};
|
||||
|
||||
// Register the module to make it available in Python
|
||||
MP_REGISTER_MODULE(MP_QSTR_example, example_user_cmodule, MODULE_EXAMPLE_ENABLED);
|
||||
|
||||
|
||||
``micropython.mk``
|
||||
|
||||
.. code-block:: make
|
||||
|
||||
EXAMPLE_MOD_DIR := $(USERMOD_DIR)
|
||||
|
||||
# Add all C files to SRC_USERMOD.
|
||||
SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c
|
||||
|
||||
# We can add our module folder to include paths if needed
|
||||
# This is not actually needed in this example.
|
||||
CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR)
|
||||
|
||||
Finally you will need to define ``MODULE_EXAMPLE_ENABLED`` to 1. This
|
||||
can be done by adding ``CFLAGS_EXTRA=-DMODULE_EXAMPLE_ENABLED=1`` to
|
||||
the ``make`` command, or editing ``mpconfigport.h`` or
|
||||
``mpconfigboard.h`` to add
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#define MODULE_EXAMPLE_ENABLED (1)
|
||||
|
||||
Note that the exact method depends on the port as they have different
|
||||
structures. If not done correctly it will compile but importing will
|
||||
fail to find the module.
|
||||
|
||||
|
||||
Compiling the cmodule into MicroPython
|
||||
--------------------------------------
|
||||
|
||||
To build such a module, compile MicroPython (see `getting started
|
||||
<https://github.com/micropython/micropython/wiki/Getting-Started>`_) with an
|
||||
extra ``make`` flag named ``USER_C_MODULES`` set to the directory containing
|
||||
all modules you want included (not to the module itself). For example:
|
||||
|
||||
|
||||
Directory::
|
||||
|
||||
my_project/
|
||||
├── modules/
|
||||
│ └──example/
|
||||
│ ├──example.c
|
||||
│ └──micropython.mk
|
||||
└── micropython/
|
||||
├──ports/
|
||||
... ├──stm32/
|
||||
...
|
||||
|
||||
Building for stm32 port:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd my_project/micropython/ports/stm32
|
||||
make USER_C_MODULES=../../../modules CFLAGS_EXTRA=-DMODULE_EXAMPLE_ENABLED=1 all
|
||||
|
||||
|
||||
Module usage in MicroPython
|
||||
---------------------------
|
||||
|
||||
Once built into your copy of MicroPython, the module implemented
|
||||
in ``example.c`` above can now be accessed in Python just
|
||||
like any other builtin module, eg
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import example
|
||||
print(example.add_ints(1, 3))
|
||||
# should display 4
|
|
@ -1,14 +0,0 @@
|
|||
Developing and building MicroPython
|
||||
===================================
|
||||
|
||||
This chapter describes some options for extending MicroPython in C. Note
|
||||
that it doesn't aim to be a complete guide for developing with MicroPython.
|
||||
See the `getting started guide
|
||||
<https://github.com/micropython/micropython/wiki/Getting-Started>`_ for further information.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
cmodules.rst
|
||||
qstr.rst
|
||||
natmod.rst
|
|
@ -1,202 +0,0 @@
|
|||
.. _natmod:
|
||||
|
||||
Native machine code in .mpy files
|
||||
=================================
|
||||
|
||||
This section describes how to build and work with .mpy files that contain native
|
||||
machine code from a language other than Python. This allows you to
|
||||
write code in a language like C, compile and link it into a .mpy file, and then
|
||||
import this file like a normal Python module. This can be used for implementing
|
||||
functionality which is performance critical, or for including an existing
|
||||
library written in another language.
|
||||
|
||||
One of the main advantages of using native .mpy files is that native machine code
|
||||
can be imported by a script dynamically, without the need to rebuild the main
|
||||
MicroPython firmware. This is in contrast to :ref:`cmodules` which also allows
|
||||
defining custom modules in C but they must be compiled into the main firmware image.
|
||||
|
||||
The focus here is on using C to build native modules, but in principle any
|
||||
language which can be compiled to stand-alone machine code can be put into a
|
||||
.mpy file.
|
||||
|
||||
A native .mpy module is built using the ``mpy_ld.py`` tool, which is found in the
|
||||
``tools/`` directory of the project. This tool takes a set of object files
|
||||
(.o files) and links them together to create a native .mpy files.
|
||||
|
||||
Supported features and limitations
|
||||
----------------------------------
|
||||
|
||||
A .mpy file can contain MicroPython bytecode and/or native machine code. If it
|
||||
contains native machine code then the .mpy file has a specific architecture
|
||||
associated with it. Current supported architectures are (these are the valid
|
||||
options for the ``ARCH`` variable, see below):
|
||||
|
||||
* ``x86`` (32 bit)
|
||||
* ``x64`` (64 bit x86)
|
||||
* ``armv7m`` (ARM Thumb 2, eg Cortex-M3)
|
||||
* ``armv7emsp`` (ARM Thumb 2, single precision float, eg Cortex-M4F, Cortex-M7)
|
||||
* ``armv7emdp`` (ARM Thumb 2, double precision float, eg Cortex-M7)
|
||||
* ``xtensa`` (non-windowed, eg ESP8266)
|
||||
* ``xtensawin`` (windowed with window size 8, eg ESP32)
|
||||
|
||||
When compiling and linking the native .mpy file the architecture must be chosen
|
||||
and the corresponding file can only be imported on that architecture. For more
|
||||
details about .mpy files see :ref:`mpy_files`.
|
||||
|
||||
Native code must be compiled as position independent code (PIC) and use a global
|
||||
offset table (GOT), although the details of this varies from architecture to
|
||||
architecture. When importing .mpy files with native code the import machinery
|
||||
is able to do some basic relocation of the native code. This includes
|
||||
relocating text, rodata and BSS sections.
|
||||
|
||||
Supported features of the linker and dynamic loader are:
|
||||
|
||||
* executable code (text)
|
||||
* read-only data (rodata), including strings and constant data (arrays, structs, etc)
|
||||
* zeroed data (BSS)
|
||||
* pointers in text to text, rodata and BSS
|
||||
* pointers in rodata to text, rodata and BSS
|
||||
|
||||
The known limitations are:
|
||||
|
||||
* data sections are not supported; workaround: use BSS data and initialise the
|
||||
data values explicitly
|
||||
|
||||
* static BSS variables are not supported; workaround: use global BSS variables
|
||||
|
||||
So, if your C code has writable data, make sure the data is defined globally,
|
||||
without an initialiser, and only written to within functions.
|
||||
|
||||
Defining a native module
|
||||
------------------------
|
||||
|
||||
A native .mpy module is defined by a set of files that are used to build the .mpy.
|
||||
The filesystem layout consists of two main parts, the source files and the Makefile:
|
||||
|
||||
* In the simplest case only a single C source file is required, which contains all
|
||||
the code that will be compiled into the .mpy module. This C source code must
|
||||
include the ``py/dynruntime.h`` file to access the MicroPython dynamic API, and
|
||||
must at least define a function called ``mpy_init``. This function will be the
|
||||
entry point of the module, called when the module is imported.
|
||||
|
||||
The module can be split into multiple C source files if desired. Parts of the
|
||||
module can also be implemented in Python. All source files should be listed in
|
||||
the Makefile, by adding them to the ``SRC`` variable (see below). This includes
|
||||
both C source files as well as any Python files which will be included in the
|
||||
resulting .mpy file.
|
||||
|
||||
* The ``Makefile`` contains the build configuration for the module and list the
|
||||
source files used to build the .mpy module. It should define ``MPY_DIR`` as the
|
||||
location of the MicroPython repository (to find header files, the relevant Makefile
|
||||
fragment, and the ``mpy_ld.py`` tool), ``MOD`` as the name of the module, ``SRC``
|
||||
as the list of source files, optionally specify the machine architecture via ``ARCH``,
|
||||
and then include ``py/dynruntime.mk``.
|
||||
|
||||
Minimal example
|
||||
---------------
|
||||
|
||||
This section provides a fully working example of a simple module named ``factorial``.
|
||||
This module provides a single function ``factorial.factorial(x)`` which computes the
|
||||
factorial of the input and returns the result.
|
||||
|
||||
Directory layout::
|
||||
|
||||
factorial/
|
||||
├── factorial.c
|
||||
└── Makefile
|
||||
|
||||
The file ``factorial.c`` contains:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Include the header file to get access to the MicroPython API
|
||||
#include "py/dynruntime.h"
|
||||
|
||||
// Helper function to compute factorial
|
||||
STATIC mp_int_t factorial_helper(mp_int_t x) {
|
||||
if (x == 0) {
|
||||
return 1;
|
||||
}
|
||||
return x * factorial_helper(x - 1);
|
||||
}
|
||||
|
||||
// This is the function which will be called from Python, as factorial(x)
|
||||
STATIC mp_obj_t factorial(mp_obj_t x_obj) {
|
||||
// Extract the integer from the MicroPython input object
|
||||
mp_int_t x = mp_obj_get_int(x_obj);
|
||||
// Calculate the factorial
|
||||
mp_int_t result = factorial_helper(x);
|
||||
// Convert the result to a MicroPython integer object and return it
|
||||
return mp_obj_new_int(result);
|
||||
}
|
||||
// Define a Python reference to the function above
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial);
|
||||
|
||||
// This is the entry point and is called when the module is imported
|
||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
||||
// This must be first, it sets up the globals dict and other things
|
||||
MP_DYNRUNTIME_INIT_ENTRY
|
||||
|
||||
// Make the function available in the module's namespace
|
||||
mp_store_global(MP_QSTR_factorial, MP_OBJ_FROM_PTR(&factorial_obj));
|
||||
|
||||
// This must be last, it restores the globals dict
|
||||
MP_DYNRUNTIME_INIT_EXIT
|
||||
}
|
||||
|
||||
The file ``Makefile`` contains:
|
||||
|
||||
.. code-block:: make
|
||||
|
||||
# Location of top-level MicroPython directory
|
||||
MPY_DIR = ../../..
|
||||
|
||||
# Name of module
|
||||
MOD = features0
|
||||
|
||||
# Source files (.c or .py)
|
||||
SRC = features0.c
|
||||
|
||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
||||
ARCH = x64
|
||||
|
||||
# Include to get the rules for compiling and linking the module
|
||||
include $(MPY_DIR)/py/dynruntime.mk
|
||||
|
||||
Compiling the module
|
||||
--------------------
|
||||
|
||||
Be sure to select the correct ``ARCH`` for the target you are going to run on.
|
||||
Then build with::
|
||||
|
||||
$ make
|
||||
|
||||
Without modifying the Makefile you can specify the target architecture via::
|
||||
|
||||
$ make ARCH=armv7m
|
||||
|
||||
Module usage in MicroPython
|
||||
---------------------------
|
||||
|
||||
Once the module is built there should be a file called ``factorial.mpy``. Copy
|
||||
this so it is accessible on the filesystem of your MicroPython system and can be
|
||||
found in the import path. The module con now be accessed in Python just like any
|
||||
other module, for example::
|
||||
|
||||
import factorial
|
||||
print(factorial.factorial(10))
|
||||
# should display 3628800
|
||||
|
||||
Further examples
|
||||
----------------
|
||||
|
||||
See ``examples/natmod/`` for further examples which show many of the available
|
||||
features of native .mpy modules. Such features include:
|
||||
|
||||
* using multiple C source files
|
||||
* including Python code alongside C code
|
||||
* rodata and BSS data
|
||||
* memory allocation
|
||||
* use of floating point
|
||||
* exception handling
|
||||
* including external C libraries
|
|
@ -1,112 +0,0 @@
|
|||
MicroPython string interning
|
||||
============================
|
||||
|
||||
MicroPython uses `string interning`_ to save both RAM and ROM. This avoids
|
||||
having to store duplicate copies of the same string. Primarily, this applies to
|
||||
identifiers in your code, as something like a function or variable name is very
|
||||
likely to appear in multiple places in the code. In MicroPython an interned
|
||||
string is called a QSTR (uniQue STRing).
|
||||
|
||||
A QSTR value (with type ``qstr``) is a index into a linked list of QSTR pools.
|
||||
QSTRs store their length and a hash of their contents for fast comparison during
|
||||
the de-duplication process. All bytecode operations that work with strings use
|
||||
a QSTR argument.
|
||||
|
||||
Compile-time QSTR generation
|
||||
----------------------------
|
||||
|
||||
In the MicroPython C code, any strings that should be interned in the final
|
||||
firmware are written as ``MP_QSTR_Foo``. At compile time this will evaluate to
|
||||
a ``qstr`` value that points to the index of ``"Foo"`` in the QSTR pool.
|
||||
|
||||
A multi-step process in the ``Makefile`` makes this work. In summary this
|
||||
process has three parts:
|
||||
|
||||
1. Find all ``MP_QSTR_Foo`` tokens in the code.
|
||||
|
||||
2. Generate a static QSTR pool containing all the string data (including lengths
|
||||
and hashes).
|
||||
|
||||
3. Replace all ``MP_QSTR_Foo`` (via the preprocessor) with their corresponding
|
||||
index.
|
||||
|
||||
``MP_QSTR_Foo`` tokens are searched for in two sources:
|
||||
|
||||
1. All files referenced in ``$(SRC_QSTR)``. This is all C code (i.e. ``py``,
|
||||
``extmod``, ``ports/stm32``) but not including third-party code such as
|
||||
``lib``.
|
||||
|
||||
2. Additional ``$(QSTR_GLOBAL_DEPENDENCIES)`` (which includes ``mpconfig*.h``).
|
||||
|
||||
*Note:* ``frozen_mpy.c`` (generated by mpy-tool.py) has its own QSTR generation
|
||||
and pool.
|
||||
|
||||
Some additional strings that can't be expressed using the ``MP_QSTR_Foo`` syntax
|
||||
(e.g. they contain non-alphanumeric characters) are explicitly provided in
|
||||
``qstrdefs.h`` and ``qstrdefsport.h`` via the ``$(QSTR_DEFS)`` variable.
|
||||
|
||||
Processing happens in the following stages:
|
||||
|
||||
1. ``qstr.i.last`` is the concatenation of putting every single input file
|
||||
through the C pre-processor. This means that any conditionally disabled code
|
||||
will be removed, and macros expanded. This means we don't add strings to the
|
||||
pool that won't be used in the final firmware. Because at this stage (thanks
|
||||
to the ``NO_QSTR`` macro added by ``QSTR_GEN_EXTRA_CFLAGS``) there is no
|
||||
definition for ``MP_QSTR_Foo`` it passes through this stage unaffected. This
|
||||
file also includes comments from the preprocessor that include line number
|
||||
information. Note that this step only uses files that have changed, which
|
||||
means that ``qstr.i.last`` will only contain data from files that have
|
||||
changed since the last compile.
|
||||
2. ``qstr.split`` is an empty file created after running ``makeqstrdefs.py split``
|
||||
on qstr.i.last. It's just used as a dependency to indicate that the step ran.
|
||||
This script outputs one file per input C file, ``genhdr/qstr/...file.c.qstr``,
|
||||
which contains only the matched QSTRs. Each QSTR is printed as ``Q(Foo)``.
|
||||
This step is necessary to combine the existing files with the new data
|
||||
generated from the incremental update in ``qstr.i.last``.
|
||||
|
||||
3. ``qstrdefs.collected.h`` is the output of concatenating ``genhdr/qstr/*``
|
||||
using ``makeqstrdefs.py cat``. This is now the full set of ``MP_QSTR_Foo``'s
|
||||
found in the code, now formatted as ``Q(Foo)``, one-per-line, with duplicates.
|
||||
This file is only updated if the set of qstrs has changed. A hash of the QSTR
|
||||
data is written to another file (``qstrdefs.collected.h.hash``) which allows
|
||||
it to track changes across builds.
|
||||
|
||||
4. ``qstrdefs.preprocessed.h`` adds in the QSTRs from qstrdefs*. It
|
||||
concatenates ``qstrdefs.collected.h`` with ``qstrdefs*.h``, then it transforms
|
||||
each line from ``Q(Foo)`` to ``"Q(Foo)"`` so they pass through the preprocessor
|
||||
unchanged. Then the preprocessor is used to deal with any conditional
|
||||
compilation in ``qstrdefs*.h``. Then the transformation is undone back to
|
||||
``Q(Foo)``, and saved as ``qstrdefs.preprocessed.h``.
|
||||
|
||||
5. ``qstrdefs.generated.h`` is the output of ``makeqstrdata.py``. For each
|
||||
``Q(Foo)`` in qstrdefs.preprocessed.h (plus some extra hard-coded ones), it outputs
|
||||
``QDEF(MP_QSTR_Foo, (const byte*)"hash" "Foo")``.
|
||||
|
||||
Then in the main compile, two things happen with ``qstrdefs.generated.h``:
|
||||
|
||||
1. In qstr.h, each QDEF becomes an entry in an enum, which makes ``MP_QSTR_Foo``
|
||||
available to code and equal to the index of that string in the QSTR table.
|
||||
|
||||
2. In qstr.c, the actual QSTR data table is generated as elements of the
|
||||
``mp_qstr_const_pool->qstrs``.
|
||||
|
||||
.. _`string interning`: https://en.wikipedia.org/wiki/String_interning
|
||||
|
||||
Run-time QSTR generation
|
||||
------------------------
|
||||
|
||||
Additional QSTR pools can be created at runtime so that strings can be added to
|
||||
them. For example, the code::
|
||||
|
||||
foo[x] = 3
|
||||
|
||||
Will need to create a QSTR for the value of ``x`` so it can be used by the
|
||||
"load attr" bytecode.
|
||||
|
||||
Also, when compiling Python code, identifiers and literals need to have QSTRs
|
||||
created. Note: only literals shorter than 10 characters become QSTRs. This is
|
||||
because a regular string on the heap always takes up a minimum of 16 bytes (one
|
||||
GC block), whereas QSTRs allow them to be packed more efficiently into the pool.
|
||||
|
||||
QSTR pools (and the underlying "chunks" that store the string data) are allocated
|
||||
on-demand on the heap with a minimum size.
|
|
@ -1,11 +0,0 @@
|
|||
.. _cpython_diffs:
|
||||
|
||||
MicroPython differences from CPython
|
||||
====================================
|
||||
|
||||
The operations listed in this section produce conflicting results in MicroPython when compared to standard Python.
|
||||
MicroPython implements Python 3.4 and some select features of Python 3.5.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
.. _esp32_general:
|
||||
|
||||
General information about the ESP32 port
|
||||
========================================
|
||||
|
||||
The ESP32 is a popular WiFi and Bluetooth enabled System-on-Chip (SoC) by
|
||||
Espressif Systems.
|
||||
|
||||
Multitude of boards
|
||||
-------------------
|
||||
|
||||
There is a multitude of modules and boards from different sources which carry
|
||||
the ESP32 chip. MicroPython tries to provide a generic port which would run on
|
||||
as many boards/modules as possible, but there may be limitations. Espressif
|
||||
development boards are taken as reference for the port (for example, testing is
|
||||
performed on them). For any board you are using please make sure you have a
|
||||
datasheet, schematics and other reference materials so you can look up any
|
||||
board-specific functions.
|
||||
|
||||
To make a generic ESP32 port and support as many boards as possible the
|
||||
following design and implementation decision were made:
|
||||
|
||||
* GPIO pin numbering is based on ESP32 chip numbering. Please have the manual/pin
|
||||
diagram of your board at hand to find correspondence between your board pins and
|
||||
actual ESP32 pins.
|
||||
* All pins are supported by MicroPython but not all are usable on any given board.
|
||||
For example pins that are connected to external SPI flash should not be used,
|
||||
and a board may only expose a certain selection of pins.
|
||||
|
||||
|
||||
Technical specifications and SoC datasheets
|
||||
-------------------------------------------
|
||||
|
||||
The datasheets and other reference material for ESP32 chip are available
|
||||
from the vendor site: https://www.espressif.com/en/support/download/documents?keys=esp32 .
|
||||
They are the primary reference for the chip technical specifications, capabilities,
|
||||
operating modes, internal functioning, etc.
|
||||
|
||||
For your convenience, some of technical specifications are provided below:
|
||||
|
||||
* Architecture: Xtensa Dual-Core 32-bit LX6
|
||||
* CPU frequency: up to 240MHz
|
||||
* Total RAM available: 528KB (part of it reserved for system)
|
||||
* BootROM: 448KB
|
||||
* Internal FlashROM: none
|
||||
* External FlashROM: code and data, via SPI Flash; usual size 4MB
|
||||
* GPIO: 34 (GPIOs are multiplexed with other functions, including
|
||||
external FlashROM, UART, etc.)
|
||||
* UART: 3 RX/TX UART (no hardware handshaking), one TX-only UART
|
||||
* SPI: 4 SPI interfaces (one used for FlashROM)
|
||||
* I2C: 2 I2C (bitbang implementation available on any pins)
|
||||
* I2S: 2
|
||||
* ADC: 12-bit SAR ADC up to 18 channels
|
||||
* DAC: 2 8-bit DACs
|
||||
* RMT: 8 channels allowing accurate pulse transmit/receive
|
||||
* Programming: using BootROM bootloader from UART - due to external FlashROM
|
||||
and always-available BootROM bootloader, the ESP32 is not brickable
|
||||
|
||||
For more information see the ESP32 datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
|
||||
|
||||
MicroPython is implemented on top of the ESP-IDF, Espressif's development
|
||||
framework for the ESP32. This is a FreeRTOS based system. See the
|
||||
`ESP-IDF Programming Guide <https://docs.espressif.com/projects/esp-idf/en/latest/index.html>`_
|
||||
for details.
|
Binary file not shown.
Before Width: | Height: | Size: 84 KiB |
|
@ -1,519 +0,0 @@
|
|||
.. _esp32_quickref:
|
||||
|
||||
Quick reference for the ESP32
|
||||
=============================
|
||||
|
||||
.. image:: img/esp32.jpg
|
||||
:alt: ESP32 board
|
||||
:width: 640px
|
||||
|
||||
The Espressif ESP32 Development Board (image attribution: Adafruit).
|
||||
|
||||
Below is a quick reference for ESP32-based boards. If it is your first time
|
||||
working with this board it may be useful to get an overview of the microcontroller:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
general.rst
|
||||
tutorial/intro.rst
|
||||
|
||||
Installing MicroPython
|
||||
----------------------
|
||||
|
||||
See the corresponding section of tutorial: :ref:`esp32_intro`. It also includes
|
||||
a troubleshooting subsection.
|
||||
|
||||
General board control
|
||||
---------------------
|
||||
|
||||
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200.
|
||||
Tab-completion is useful to find out what methods an object has.
|
||||
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
|
||||
the REPL.
|
||||
|
||||
The :mod:`machine` module::
|
||||
|
||||
import machine
|
||||
|
||||
machine.freq() # get the current frequency of the CPU
|
||||
machine.freq(240000000) # set the CPU frequency to 240 MHz
|
||||
|
||||
The :mod:`esp` module::
|
||||
|
||||
import esp
|
||||
|
||||
esp.osdebug(None) # turn off vendor O/S debugging messages
|
||||
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)
|
||||
|
||||
# low level methods to interact with flash storage
|
||||
esp.flash_size()
|
||||
esp.flash_user_start()
|
||||
esp.flash_erase(sector_no)
|
||||
esp.flash_write(byte_offset, buffer)
|
||||
esp.flash_read(byte_offset, buffer)
|
||||
|
||||
The :mod:`esp32` module::
|
||||
|
||||
import esp32
|
||||
|
||||
esp32.hall_sensor() # read the internal hall sensor
|
||||
esp32.raw_temperature() # read the internal temperature of the MCU, in Farenheit
|
||||
esp32.ULP() # access to the Ultra-Low-Power Co-processor
|
||||
|
||||
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
|
||||
by reading the temperature sensor immediately after waking up from sleep.
|
||||
|
||||
Networking
|
||||
----------
|
||||
|
||||
The :mod:`network` module::
|
||||
|
||||
import network
|
||||
|
||||
wlan = network.WLAN(network.STA_IF) # create station interface
|
||||
wlan.active(True) # activate the interface
|
||||
wlan.scan() # scan for access points
|
||||
wlan.isconnected() # check if the station is connected to an AP
|
||||
wlan.connect('essid', 'password') # connect to an AP
|
||||
wlan.config('mac') # get the interface's MAC address
|
||||
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
|
||||
|
||||
ap = network.WLAN(network.AP_IF) # create access-point interface
|
||||
ap.config(essid='ESP-AP') # set the ESSID of the access point
|
||||
ap.active(True) # activate the interface
|
||||
|
||||
A useful function for connecting to your local WiFi network is::
|
||||
|
||||
def do_connect():
|
||||
import network
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to network...')
|
||||
wlan.connect('essid', 'password')
|
||||
while not wlan.isconnected():
|
||||
pass
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
Once the network is established the :mod:`socket <usocket>` module can be used
|
||||
to create and use TCP/UDP sockets as usual, and the ``urequests`` module for
|
||||
convenient HTTP requests.
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
Use the :mod:`time <utime>` module::
|
||||
|
||||
import time
|
||||
|
||||
time.sleep(1) # sleep for 1 second
|
||||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get millisecond counter
|
||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||
|
||||
Timers
|
||||
------
|
||||
|
||||
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class
|
||||
with timer ID of -1::
|
||||
|
||||
from machine import Timer
|
||||
|
||||
tim = Timer(-1)
|
||||
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
|
||||
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
|
||||
|
||||
The period is in milliseconds.
|
||||
|
||||
.. _Pins_and_GPIO:
|
||||
|
||||
Pins and GPIO
|
||||
-------------
|
||||
|
||||
Use the :ref:`machine.Pin <machine.Pin>` class::
|
||||
|
||||
from machine import Pin
|
||||
|
||||
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
|
||||
p0.on() # set pin to "on" (high) level
|
||||
p0.off() # set pin to "off" (low) level
|
||||
p0.value(1) # set pin to on/high
|
||||
|
||||
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
|
||||
print(p2.value()) # get value, 0 or 1
|
||||
|
||||
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
|
||||
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
|
||||
|
||||
Available Pins are from the following ranges (inclusive): 0-19, 21-23, 25-27, 32-39.
|
||||
These correspond to the actual GPIO pin numbers of ESP32 chip. Note that many
|
||||
end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...).
|
||||
For mapping between board logical pins and physical chip pins consult your board
|
||||
documentation.
|
||||
|
||||
Notes:
|
||||
|
||||
* Pins 1 and 3 are REPL UART TX and RX respectively
|
||||
|
||||
* Pins 6, 7, 8, 11, 16, and 17 are used for connecting the embedded flash,
|
||||
and are not recommended for other uses
|
||||
|
||||
* Pins 34-39 are input only, and also do not have internal pull-up resistors
|
||||
|
||||
* The pull value of some pins can be set to ``Pin.PULL_HOLD`` to reduce power
|
||||
consumption during deepsleep.
|
||||
|
||||
PWM (pulse width modulation)
|
||||
----------------------------
|
||||
|
||||
PWM can be enabled on all output-enabled pins. The base frequency can
|
||||
range from 1Hz to 40MHz but there is a tradeoff; as the base frequency
|
||||
*increases* the duty resolution *decreases*. See
|
||||
`LED Control <https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html>`_
|
||||
for more details.
|
||||
|
||||
Use the ``machine.PWM`` class::
|
||||
|
||||
from machine import Pin, PWM
|
||||
|
||||
pwm0 = PWM(Pin(0)) # create PWM object from a pin
|
||||
pwm0.freq() # get current frequency
|
||||
pwm0.freq(1000) # set frequency
|
||||
pwm0.duty() # get current duty cycle
|
||||
pwm0.duty(200) # set duty cycle
|
||||
pwm0.deinit() # turn off PWM on the pin
|
||||
|
||||
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
|
||||
|
||||
ADC (analog to digital conversion)
|
||||
----------------------------------
|
||||
|
||||
On the ESP32 ADC functionality is available on Pins 32-39. Note that, when
|
||||
using the default configuration, input voltages on the ADC pin must be between
|
||||
0.0v and 1.0v (anything above 1.0v will just read as 4095). Attenuation must
|
||||
be applied in order to increase this usable voltage range.
|
||||
|
||||
Use the :ref:`machine.ADC <machine.ADC>` class::
|
||||
|
||||
from machine import ADC
|
||||
|
||||
adc = ADC(Pin(32)) # create ADC object on ADC pin
|
||||
adc.read() # read value, 0-4095 across voltage range 0.0v - 1.0v
|
||||
|
||||
adc.atten(ADC.ATTN_11DB) # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v)
|
||||
adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511)
|
||||
adc.read() # read value using the newly configured attenuation and width
|
||||
|
||||
ESP32 specific ADC class method reference:
|
||||
|
||||
.. method:: ADC.atten(attenuation)
|
||||
|
||||
This method allows for the setting of the amount of attenuation on the
|
||||
input of the ADC. This allows for a wider possible input voltage range,
|
||||
at the cost of accuracy (the same number of bits now represents a wider
|
||||
range). The possible attenuation options are:
|
||||
|
||||
- ``ADC.ATTN_0DB``: 0dB attenuation, gives a maximum input voltage
|
||||
of 1.00v - this is the default configuration
|
||||
- ``ADC.ATTN_2_5DB``: 2.5dB attenuation, gives a maximum input voltage
|
||||
of approximately 1.34v
|
||||
- ``ADC.ATTN_6DB``: 6dB attenuation, gives a maximum input voltage
|
||||
of approximately 2.00v
|
||||
- ``ADC.ATTN_11DB``: 11dB attenuation, gives a maximum input voltage
|
||||
of approximately 3.6v
|
||||
|
||||
.. Warning::
|
||||
Despite 11dB attenuation allowing for up to a 3.6v range, note that the
|
||||
absolute maximum voltage rating for the input pins is 3.6v, and so going
|
||||
near this boundary may be damaging to the IC!
|
||||
|
||||
.. method:: ADC.width(width)
|
||||
|
||||
This method allows for the setting of the number of bits to be utilised
|
||||
and returned during ADC reads. Possible width options are:
|
||||
|
||||
- ``ADC.WIDTH_9BIT``: 9 bit data
|
||||
- ``ADC.WIDTH_10BIT``: 10 bit data
|
||||
- ``ADC.WIDTH_11BIT``: 11 bit data
|
||||
- ``ADC.WIDTH_12BIT``: 12 bit data - this is the default configuration
|
||||
|
||||
Software SPI bus
|
||||
----------------
|
||||
|
||||
There are two SPI drivers. One is implemented in software (bit-banging)
|
||||
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>`
|
||||
class::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
# construct an SPI bus on the given pins
|
||||
# polarity is the idle state of SCK
|
||||
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
||||
spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
||||
|
||||
spi.init(baudrate=200000) # set the baudrate
|
||||
|
||||
spi.read(10) # read 10 bytes on MISO
|
||||
spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI
|
||||
|
||||
buf = bytearray(50) # create a buffer
|
||||
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)
|
||||
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
|
||||
|
||||
spi.write(b'12345') # write 5 bytes on MOSI
|
||||
|
||||
buf = bytearray(4) # create a buffer
|
||||
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
|
||||
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
|
||||
|
||||
.. Warning::
|
||||
Currently *all* of ``sck``, ``mosi`` and ``miso`` *must* be specified when
|
||||
initialising Software SPI.
|
||||
|
||||
Hardware SPI bus
|
||||
----------------
|
||||
|
||||
There are two hardware SPI channels that allow faster transmission
|
||||
rates (up to 80Mhz). These may be used on any IO pins that support the
|
||||
required direction and are otherwise unused (see :ref:`Pins_and_GPIO`)
|
||||
but if they are not configured to their default pins then they need to
|
||||
pass through an extra layer of GPIO multiplexing, which can impact
|
||||
their reliability at high speeds. Hardware SPI channels are limited
|
||||
to 40MHz when used on pins other than the default ones listed below.
|
||||
|
||||
===== =========== ============
|
||||
\ HSPI (id=1) VSPI (id=2)
|
||||
===== =========== ============
|
||||
sck 14 18
|
||||
mosi 13 23
|
||||
miso 12 19
|
||||
===== =========== ============
|
||||
|
||||
Hardware SPI has the same methods as Software SPI above::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
|
||||
vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
|
||||
|
||||
|
||||
I2C bus
|
||||
-------
|
||||
|
||||
The I2C driver has both software and hardware implementations, and the two
|
||||
hardware peripherals have identifiers 0 and 1. Any available output-capable
|
||||
pins can be used for SCL and SDA. The driver is accessed via the
|
||||
:ref:`machine.I2C <machine.I2C>` class::
|
||||
|
||||
from machine import Pin, I2C
|
||||
|
||||
# construct a software I2C bus
|
||||
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
|
||||
|
||||
# construct a hardware I2C bus
|
||||
i2c = I2C(0)
|
||||
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
|
||||
|
||||
i2c.scan() # scan for slave devices
|
||||
|
||||
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a
|
||||
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
|
||||
|
||||
buf = bytearray(10) # create a buffer with 10 bytes
|
||||
i2c.writeto(0x3a, buf) # write the given buffer to the slave
|
||||
|
||||
Real time clock (RTC)
|
||||
---------------------
|
||||
|
||||
See :ref:`machine.RTC <machine.RTC>` ::
|
||||
|
||||
from machine import RTC
|
||||
|
||||
rtc = RTC()
|
||||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
Deep-sleep mode
|
||||
---------------
|
||||
|
||||
The following code can be used to sleep, wake and check the reset cause::
|
||||
|
||||
import machine
|
||||
|
||||
# check if the device woke from a deep sleep
|
||||
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
|
||||
print('woke from a deep sleep')
|
||||
|
||||
# put the device to sleep for 10 seconds
|
||||
machine.deepsleep(10000)
|
||||
|
||||
Notes:
|
||||
|
||||
* Calling ``deepsleep()`` without an argument will put the device to sleep
|
||||
indefinitely
|
||||
* A software reset does not change the reset cause
|
||||
* There may be some leakage current flowing through enabled internal pullups.
|
||||
To further reduce power consumption it is possible to disable the internal pullups::
|
||||
|
||||
p1 = Pin(4, Pin.IN, Pin.PULL_HOLD)
|
||||
|
||||
After leaving deepsleep it may be necessary to un-hold the pin explicitly (e.g. if
|
||||
it is an output pin) via::
|
||||
|
||||
p1 = Pin(4, Pin.OUT, None)
|
||||
|
||||
RMT
|
||||
---
|
||||
|
||||
The RMT is ESP32-specific and allows generation of accurate digital pulses with
|
||||
12.5ns resolution. See :ref:`esp32.RMT <esp32.RMT>` for details. Usage is::
|
||||
|
||||
import esp32
|
||||
from machine import Pin
|
||||
|
||||
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
|
||||
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
|
||||
# The channel resolution is 100ns (1/(source_freq/clock_div)).
|
||||
r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
|
||||
|
||||
OneWire driver
|
||||
--------------
|
||||
|
||||
The OneWire driver is implemented in software and works on all pins::
|
||||
|
||||
from machine import Pin
|
||||
import onewire
|
||||
|
||||
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
|
||||
ow.scan() # return a list of devices on the bus
|
||||
ow.reset() # reset the bus
|
||||
ow.readbyte() # read a byte
|
||||
ow.writebyte(0x12) # write a byte on the bus
|
||||
ow.write('123') # write bytes on the bus
|
||||
ow.select_rom(b'12345678') # select a specific device by its ROM code
|
||||
|
||||
There is a specific driver for DS18S20 and DS18B20 devices::
|
||||
|
||||
import time, ds18x20
|
||||
ds = ds18x20.DS18X20(ow)
|
||||
roms = ds.scan()
|
||||
ds.convert_temp()
|
||||
time.sleep_ms(750)
|
||||
for rom in roms:
|
||||
print(ds.read_temp(rom))
|
||||
|
||||
Be sure to put a 4.7k pull-up resistor on the data line. Note that
|
||||
the ``convert_temp()`` method must be called each time you want to
|
||||
sample the temperature.
|
||||
|
||||
NeoPixel driver
|
||||
---------------
|
||||
|
||||
Use the ``neopixel`` module::
|
||||
|
||||
from machine import Pin
|
||||
from neopixel import NeoPixel
|
||||
|
||||
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels
|
||||
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels
|
||||
np[0] = (255, 255, 255) # set the first pixel to white
|
||||
np.write() # write data to all pixels
|
||||
r, g, b = np[0] # get first pixel colour
|
||||
|
||||
For low-level driving of a NeoPixel::
|
||||
|
||||
import esp
|
||||
esp.neopixel_write(pin, grb_buf, is800khz)
|
||||
|
||||
.. Warning::
|
||||
By default ``NeoPixel`` is configured to control the more popular *800kHz*
|
||||
units. It is possible to use alternative timing to control other (typically
|
||||
400kHz) devices by passing ``timing=0`` when constructing the
|
||||
``NeoPixel`` object.
|
||||
|
||||
|
||||
Capacitive Touch
|
||||
----------------
|
||||
|
||||
Use the ``TouchPad`` class in the ``machine`` module::
|
||||
|
||||
from machine import TouchPad, Pin
|
||||
|
||||
t = TouchPad(Pin(14))
|
||||
t.read() # Returns a smaller number when touched
|
||||
|
||||
``TouchPad.read`` returns a value relative to the capacitive variation. Small numbers (typically in
|
||||
the *tens*) are common when a pin is touched, larger numbers (above *one thousand*) when
|
||||
no touch is present. However the values are *relative* and can vary depending on the board
|
||||
and surrounding composition so some calibration may be required.
|
||||
|
||||
There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13
|
||||
14, 15, 27, 32, 33. Trying to assign to any other pins will result in a ``ValueError``.
|
||||
|
||||
Note that TouchPads can be used to wake an ESP32 from sleep::
|
||||
|
||||
import machine
|
||||
from machine import TouchPad, Pin
|
||||
import esp32
|
||||
|
||||
t = TouchPad(Pin(14))
|
||||
t.config(500) # configure the threshold at which the pin is considered touched
|
||||
esp32.wake_on_touch(True)
|
||||
machine.lightsleep() # put the MCU to sleep until a touchpad is touched
|
||||
|
||||
For more details on touchpads refer to `Espressif Touch Sensor
|
||||
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/touch_pad.html>`_.
|
||||
|
||||
|
||||
DHT driver
|
||||
----------
|
||||
|
||||
The DHT driver is implemented in software and works on all pins::
|
||||
|
||||
import dht
|
||||
import machine
|
||||
|
||||
d = dht.DHT11(machine.Pin(4))
|
||||
d.measure()
|
||||
d.temperature() # eg. 23 (°C)
|
||||
d.humidity() # eg. 41 (% RH)
|
||||
|
||||
d = dht.DHT22(machine.Pin(4))
|
||||
d.measure()
|
||||
d.temperature() # eg. 23.6 (°C)
|
||||
d.humidity() # eg. 41.3 (% RH)
|
||||
|
||||
WebREPL (web browser interactive prompt)
|
||||
----------------------------------------
|
||||
|
||||
WebREPL (REPL over WebSockets, accessible via a web browser) is an
|
||||
experimental feature available in ESP32 port. Download web client
|
||||
from https://github.com/micropython/webrepl (hosted version available
|
||||
at http://micropython.org/webrepl), and configure it by executing::
|
||||
|
||||
import webrepl_setup
|
||||
|
||||
and following on-screen instructions. After reboot, it will be available
|
||||
for connection. If you disabled automatic start-up on boot, you may
|
||||
run configured daemon on demand using::
|
||||
|
||||
import webrepl
|
||||
webrepl.start()
|
||||
|
||||
# or, start with a specific password
|
||||
webrepl.start(password='mypass')
|
||||
|
||||
The WebREPL daemon listens on all active interfaces, which can be STA or
|
||||
AP. This allows you to connect to the ESP32 via a router (the STA
|
||||
interface) or directly when connected to its access point.
|
||||
|
||||
In addition to terminal/command prompt access, WebREPL also has provision
|
||||
for file transfer (both upload and download). The web client has buttons for
|
||||
the corresponding functions, or you can use the command-line client
|
||||
``webrepl_cli.py`` from the repository above.
|
||||
|
||||
See the MicroPython forum for other community-supported alternatives
|
||||
to transfer files to an ESP32 board.
|
|
@ -1,139 +0,0 @@
|
|||
.. _esp32_intro:
|
||||
|
||||
Getting started with MicroPython on the ESP32
|
||||
=============================================
|
||||
|
||||
Using MicroPython is a great way to get the most of your ESP32 board. And
|
||||
vice versa, the ESP32 chip is a great platform for using MicroPython. This
|
||||
tutorial will guide you through setting up MicroPython, getting a prompt, using
|
||||
WebREPL, connecting to the network and communicating with the Internet, using
|
||||
the hardware peripherals, and controlling some external components.
|
||||
|
||||
Let's get started!
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The first thing you need is a board with an ESP32 chip. The MicroPython
|
||||
software supports the ESP32 chip itself and any board should work. The main
|
||||
characteristic of a board is how the GPIO pins are connected to the outside
|
||||
world, and whether it includes a built-in USB-serial convertor to make the
|
||||
UART available to your PC.
|
||||
|
||||
Names of pins will be given in this tutorial using the chip names (eg GPIO2)
|
||||
and it should be straightforward to find which pin this corresponds to on your
|
||||
particular board.
|
||||
|
||||
Powering the board
|
||||
------------------
|
||||
|
||||
If your board has a USB connector on it then most likely it is powered through
|
||||
this when connected to your PC. Otherwise you will need to power it directly.
|
||||
Please refer to the documentation for your board for further details.
|
||||
|
||||
Getting the firmware
|
||||
--------------------
|
||||
|
||||
The first thing you need to do is download the most recent MicroPython firmware
|
||||
.bin file to load onto your ESP32 device. You can download it from the
|
||||
`MicroPython downloads page <https://micropython.org/download#esp32>`_.
|
||||
From here, you have 3 main choices:
|
||||
|
||||
* Stable firmware builds
|
||||
* Daily firmware builds
|
||||
* Daily firmware builds with SPIRAM support
|
||||
|
||||
If you are just starting with MicroPython, the best bet is to go for the Stable
|
||||
firmware builds. If you are an advanced, experienced MicroPython ESP32 user
|
||||
who would like to follow development closely and help with testing new
|
||||
features, there are daily builds. If your board has SPIRAM support you can
|
||||
use either the standard firmware or the firmware with SPIRAM support, and in
|
||||
the latter case you will have access to more RAM for Python objects.
|
||||
|
||||
Deploying the firmware
|
||||
----------------------
|
||||
|
||||
Once you have the MicroPython firmware you need to load it onto your ESP32 device.
|
||||
There are two main steps to do this: first you need to put your device in
|
||||
bootloader mode, and second you need to copy across the firmware. The exact
|
||||
procedure for these steps is highly dependent on the particular board and you will
|
||||
need to refer to its documentation for details.
|
||||
|
||||
Fortunately, most boards have a USB connector, a USB-serial convertor, and the DTR
|
||||
and RTS pins wired in a special way then deploying the firmware should be easy as
|
||||
all steps can be done automatically. Boards that have such features
|
||||
include the Adafruit Feather HUZZAH32, M5Stack, Wemos LOLIN32, and TinyPICO
|
||||
boards, along with the Espressif DevKitC, PICO-KIT, WROVER-KIT dev-kits.
|
||||
|
||||
For best results it is recommended to first erase the entire flash of your
|
||||
device before putting on new MicroPython firmware.
|
||||
|
||||
Currently we only support esptool.py to copy across the firmware. You can find
|
||||
this tool here: `<https://github.com/espressif/esptool/>`__, or install it
|
||||
using pip::
|
||||
|
||||
pip install esptool
|
||||
|
||||
Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer).
|
||||
An older version (at least 1.2.1 is needed) works fine but will require Python
|
||||
2.7.
|
||||
|
||||
Using esptool.py you can erase the flash with the command::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 erase_flash
|
||||
|
||||
And then deploy the new firmware using::
|
||||
|
||||
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-20180511-v1.9.4.bin
|
||||
|
||||
Notes:
|
||||
|
||||
* You might need to change the "port" setting to something else relevant for your
|
||||
PC
|
||||
* You may need to reduce the baudrate if you get errors when flashing
|
||||
(eg down to 115200 by adding ``--baud 115200`` into the command)
|
||||
* For some boards with a particular FlashROM configuration you may need to
|
||||
change the flash mode (eg by adding ``-fm dio`` into the command)
|
||||
* The filename of the firmware should match the file that you have
|
||||
|
||||
If the above commands run without error then MicroPython should be installed on
|
||||
your board!
|
||||
|
||||
Serial prompt
|
||||
-------------
|
||||
|
||||
Once you have the firmware on the device you can access the REPL (Python prompt)
|
||||
over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial
|
||||
convertor, depending on your board. The baudrate is 115200.
|
||||
|
||||
From here you can now follow the ESP8266 tutorial, because these two Espressif chips
|
||||
are very similar when it comes to using MicroPython on them. The ESP8266 tutorial
|
||||
is found at :ref:`esp8266_tutorial` (but skip the Introduction section).
|
||||
|
||||
Troubleshooting installation problems
|
||||
-------------------------------------
|
||||
|
||||
If you experience problems during flashing or with running firmware immediately
|
||||
after it, here are troubleshooting recommendations:
|
||||
|
||||
* Be aware of and try to exclude hardware problems. There are 2 common
|
||||
problems: bad power source quality, and worn-out/defective FlashROM.
|
||||
Speaking of power source, not just raw amperage is important, but also low
|
||||
ripple and noise/EMI in general. The most reliable and convenient power
|
||||
source is a USB port.
|
||||
|
||||
* The flashing instructions above use flashing speed of 460800 baud, which is
|
||||
good compromise between speed and stability. However, depending on your
|
||||
module/board, USB-UART convertor, cables, host OS, etc., the above baud
|
||||
rate may be too high and lead to errors. Try a more common 115200 baud
|
||||
rate instead in such cases.
|
||||
|
||||
* To catch incorrect flash content (e.g. from a defective sector on a chip),
|
||||
add ``--verify`` switch to the commands above.
|
||||
|
||||
* If you still experience problems with flashing the firmware please
|
||||
refer to esptool.py project page, https://github.com/espressif/esptool
|
||||
for additional documentation and a bug tracker where you can report problems.
|
||||
|
||||
* If you are able to flash the firmware but the ``--verify`` option returns
|
||||
errors even after multiple retries the you may have a defective FlashROM chip.
|
|
@ -1,197 +0,0 @@
|
|||
.. _esp8266_general:
|
||||
|
||||
General information about the ESP8266 port
|
||||
==========================================
|
||||
|
||||
ESP8266 is a popular WiFi-enabled System-on-Chip (SoC) by Espressif Systems.
|
||||
|
||||
Multitude of boards
|
||||
-------------------
|
||||
|
||||
There is a multitude of modules and boards from different sources which carry
|
||||
the ESP8266 chip. MicroPython tries to provide a generic port which would run on
|
||||
as many boards/modules as possible, but there may be limitations. Adafruit
|
||||
Feather HUZZAH board is taken as a reference board for the port (for example,
|
||||
testing is performed on it). If you have another board, please make sure you
|
||||
have a datasheet, schematics and other reference materials for your board
|
||||
handy to look up various aspects of your board functioning.
|
||||
|
||||
To make a generic ESP8266 port and support as many boards as possible,
|
||||
the following design and implementation decision were made:
|
||||
|
||||
* GPIO pin numbering is based on ESP8266 chip numbering, not some "logical"
|
||||
numbering of a particular board. Please have the manual/pin diagram of your board
|
||||
at hand to find correspondence between your board pins and actual ESP8266 pins.
|
||||
We also encourage users of various boards to share this mapping via MicroPython
|
||||
forum, with the idea to collect community-maintained reference materials
|
||||
eventually.
|
||||
* All pins which make sense to support, are supported by MicroPython
|
||||
(for example, pins which are used to connect SPI flash
|
||||
are not exposed, as they're unlikely useful for anything else, and
|
||||
operating on them will lead to board lock-up). However, any particular
|
||||
board may expose only subset of pins. Consult your board reference manual.
|
||||
* Some boards may lack external pins/internal connectivity to support
|
||||
ESP8266 deepsleep mode.
|
||||
|
||||
|
||||
Technical specifications and SoC datasheets
|
||||
-------------------------------------------
|
||||
|
||||
The datasheets and other reference material for ESP8266 chip are available
|
||||
from the vendor site: http://bbs.espressif.com/viewtopic.php?f=67&t=225 .
|
||||
They are the primary reference for the chip technical specifications, capabilities,
|
||||
operating modes, internal functioning, etc.
|
||||
|
||||
For your convenience, some of technical specifications are provided below:
|
||||
|
||||
* Architecture: Xtensa lx106
|
||||
* CPU frequency: 80MHz overclockable to 160MHz
|
||||
* Total RAM available: 96KB (part of it reserved for system)
|
||||
* BootROM: 64KB
|
||||
* Internal FlashROM: None
|
||||
* External FlashROM: code and data, via SPI Flash. Normal sizes 512KB-4MB.
|
||||
* GPIO: 16 + 1 (GPIOs are multiplexed with other functions, including
|
||||
external FlashROM, UART, deep sleep wake-up, etc.)
|
||||
* UART: One RX/TX UART (no hardware handshaking), one TX-only UART.
|
||||
* SPI: 2 SPI interfaces (one used for FlashROM).
|
||||
* I2C: No native external I2C (bitbang implementation available on any pins).
|
||||
* I2S: 1.
|
||||
* Programming: using BootROM bootloader from UART. Due to external FlashROM
|
||||
and always-available BootROM bootloader, ESP8266 is not brickable.
|
||||
|
||||
|
||||
Scarcity of runtime resources
|
||||
-----------------------------
|
||||
|
||||
ESP8266 has very modest resources (first of all, RAM memory). So, please
|
||||
avoid allocating too big container objects (lists, dictionaries) and
|
||||
buffers. There is also no full-fledged OS to keep track of resources
|
||||
and automatically clean them up, so that's the task of a user/user
|
||||
application: please be sure to close open files, sockets, etc. as soon
|
||||
as possible after use.
|
||||
|
||||
|
||||
Boot process
|
||||
------------
|
||||
|
||||
On boot, MicroPython EPS8266 port executes ``_boot.py`` script from internal
|
||||
frozen modules. It mounts filesystem in FlashROM, or if it's not available,
|
||||
performs first-time setup of the module and creates the filesystem. This
|
||||
part of the boot process is considered fixed, and not available for customization
|
||||
for end users (even if you build from source, please refrain from changes to
|
||||
it; customization of early boot process is available only to advanced users
|
||||
and developers, who can diagnose themselves any issues arising from
|
||||
modifying the standard process).
|
||||
|
||||
Once the filesystem is mounted, ``boot.py`` is executed from it. The standard
|
||||
version of this file is created during first-time module set up and has
|
||||
commands to start a WebREPL daemon (disabled by default, configurable
|
||||
with ``webrepl_setup`` module), etc. This
|
||||
file is customizable by end users (for example, you may want to set some
|
||||
parameters or add other services which should be run on
|
||||
a module start-up). But keep in mind that incorrect modifications to boot.py
|
||||
may still lead to boot loops or lock ups, requiring to reflash a module
|
||||
from scratch. (In particular, it's recommended that you use either
|
||||
``webrepl_setup`` module or manual editing to configure WebREPL, but not
|
||||
both).
|
||||
|
||||
As a final step of boot procedure, ``main.py`` is executed from filesystem,
|
||||
if exists. This file is a hook to start up a user application each time
|
||||
on boot (instead of going to REPL). For small test applications, you may
|
||||
name them directly as ``main.py``, and upload to module, but instead it's
|
||||
recommended to keep your application(s) in separate files, and have just
|
||||
the following in ``main.py``::
|
||||
|
||||
import my_app
|
||||
my_app.main()
|
||||
|
||||
This will allow to keep the structure of your application clear, as well as
|
||||
allow to install multiple applications on a board, and switch among them.
|
||||
|
||||
|
||||
Known Issues
|
||||
------------
|
||||
|
||||
Real-time clock
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
RTC in ESP8266 has very bad accuracy, drift may be seconds per minute. As
|
||||
a workaround, to measure short enough intervals you can use
|
||||
``utime.time()``, etc. functions, and for wall clock time, synchronize from
|
||||
the net using included ``ntptime.py`` module.
|
||||
|
||||
Due to limitations of the ESP8266 chip the internal real-time clock (RTC)
|
||||
will overflow every 7:45h. If a long-term working RTC time is required then
|
||||
``time()`` or ``localtime()`` must be called at least once within 7 hours.
|
||||
MicroPython will then handle the overflow.
|
||||
|
||||
Sockets and WiFi buffers overflow
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Socket instances remain active until they are explicitly closed. This has two
|
||||
consequences. Firstly they occupy RAM, so an application which opens sockets
|
||||
without closing them may eventually run out of memory. Secondly not properly
|
||||
closed socket can cause the low-level part of the vendor WiFi stack to emit
|
||||
``Lmac`` errors. This occurs if data comes in for a socket and is not
|
||||
processed in a timely manner. This can overflow the WiFi stack input queue
|
||||
and lead to a deadlock. The only recovery is by a hard reset.
|
||||
|
||||
The above may also happen after an application terminates and quits to the REPL
|
||||
for any reason including an exception. Subsequent arrival of data provokes the
|
||||
failure with the above error message repeatedly issued. So, sockets should be
|
||||
closed in any case, regardless whether an application terminates successfully
|
||||
or by an exception, for example using try/finally::
|
||||
|
||||
sock = socket(...)
|
||||
try:
|
||||
# Use sock
|
||||
finally:
|
||||
sock.close()
|
||||
|
||||
|
||||
SSL/TLS limitations
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ESP8266 uses `axTLS <http://axtls.sourceforge.net/>`_ library, which is one
|
||||
of the smallest TLS libraries with the compatible licensing. However, it
|
||||
also has some known issues/limitations:
|
||||
|
||||
1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve
|
||||
cryptography (ECC). This means it can't work with sites which force
|
||||
the use of these features (it works ok with classic RSA certificates).
|
||||
2. Half-duplex communication nature. axTLS uses a single buffer for both
|
||||
sending and receiving, which leads to considerable memory saving and
|
||||
works well with protocols like HTTP. But there may be problems with
|
||||
protocols which don't follow classic request-response model.
|
||||
|
||||
Besides axTLS own limitations, the configuration used for MicroPython is
|
||||
highly optimized for code size, which leads to additional limitations
|
||||
(these may be lifted in the future):
|
||||
|
||||
3. Optimized RSA algorithms are not enabled, which may lead to slow
|
||||
SSL handshakes.
|
||||
4. Stored sessions are not supported (may allow faster repeated connections
|
||||
to the same site in some circumstances).
|
||||
|
||||
Besides axTLS specific limitations described above, there's another generic
|
||||
limitation with usage of TLS on the low-memory devices:
|
||||
|
||||
5. The TLS standard specifies the maximum length of the TLS record (unit
|
||||
of TLS communication, the entire record must be buffered before it can
|
||||
be processed) as 16KB. That's almost half of the available ESP8266 memory,
|
||||
and inside a more or less advanced application would be hard to allocate
|
||||
due to memory fragmentation issues. As a compromise, a smaller buffer is
|
||||
used, with the idea that the most interesting usage for SSL would be
|
||||
accessing various REST APIs, which usually require much smaller messages.
|
||||
The buffers size is on the order of 5KB, and is adjusted from time to
|
||||
time, taking as a reference being able to access https://google.com .
|
||||
The smaller buffer hower means that some sites can't be accessed using
|
||||
it, and it's not possible to stream large amounts of data.
|
||||
|
||||
There are also some not implemented features specifically in MicroPython's
|
||||
``ussl`` module based on axTLS:
|
||||
|
||||
6. Certificates are not validated (this may make connections susceptible
|
||||
to man-in-the-middle attacks).
|
||||
7. There is no support for client certificates (scheduled to be fixed in
|
||||
1.9.4 release).
|
Binary file not shown.
Before Width: | Height: | Size: 78 KiB |
|
@ -1,394 +0,0 @@
|
|||
.. _esp8266_quickref:
|
||||
|
||||
Quick reference for the ESP8266
|
||||
===============================
|
||||
|
||||
.. image:: img/adafruit_products_pinoutstop.jpg
|
||||
:alt: Adafruit Feather HUZZAH board
|
||||
:width: 640px
|
||||
|
||||
The Adafruit Feather HUZZAH board (image attribution: Adafruit).
|
||||
|
||||
Below is a quick reference for ESP8266-based boards. If it is your first time
|
||||
working with this board please consider reading the following sections first:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
general.rst
|
||||
tutorial/index.rst
|
||||
|
||||
Installing MicroPython
|
||||
----------------------
|
||||
|
||||
See the corresponding section of tutorial: :ref:`intro`. It also includes
|
||||
a troubleshooting subsection.
|
||||
|
||||
General board control
|
||||
---------------------
|
||||
|
||||
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200.
|
||||
Tab-completion is useful to find out what methods an object has.
|
||||
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
|
||||
the REPL.
|
||||
|
||||
The :mod:`machine` module::
|
||||
|
||||
import machine
|
||||
|
||||
machine.freq() # get the current frequency of the CPU
|
||||
machine.freq(160000000) # set the CPU frequency to 160 MHz
|
||||
|
||||
The :mod:`esp` module::
|
||||
|
||||
import esp
|
||||
|
||||
esp.osdebug(None) # turn off vendor O/S debugging messages
|
||||
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)
|
||||
|
||||
Networking
|
||||
----------
|
||||
|
||||
The :mod:`network` module::
|
||||
|
||||
import network
|
||||
|
||||
wlan = network.WLAN(network.STA_IF) # create station interface
|
||||
wlan.active(True) # activate the interface
|
||||
wlan.scan() # scan for access points
|
||||
wlan.isconnected() # check if the station is connected to an AP
|
||||
wlan.connect('essid', 'password') # connect to an AP
|
||||
wlan.config('mac') # get the interface's MAC adddress
|
||||
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
|
||||
|
||||
ap = network.WLAN(network.AP_IF) # create access-point interface
|
||||
ap.active(True) # activate the interface
|
||||
ap.config(essid='ESP-AP') # set the ESSID of the access point
|
||||
|
||||
A useful function for connecting to your local WiFi network is::
|
||||
|
||||
def do_connect():
|
||||
import network
|
||||
wlan = network.WLAN(network.STA_IF)
|
||||
wlan.active(True)
|
||||
if not wlan.isconnected():
|
||||
print('connecting to network...')
|
||||
wlan.connect('essid', 'password')
|
||||
while not wlan.isconnected():
|
||||
pass
|
||||
print('network config:', wlan.ifconfig())
|
||||
|
||||
Once the network is established the :mod:`socket <usocket>` module can be used
|
||||
to create and use TCP/UDP sockets as usual.
|
||||
|
||||
Delay and timing
|
||||
----------------
|
||||
|
||||
Use the :mod:`time <utime>` module::
|
||||
|
||||
import time
|
||||
|
||||
time.sleep(1) # sleep for 1 second
|
||||
time.sleep_ms(500) # sleep for 500 milliseconds
|
||||
time.sleep_us(10) # sleep for 10 microseconds
|
||||
start = time.ticks_ms() # get millisecond counter
|
||||
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
||||
|
||||
Timers
|
||||
------
|
||||
|
||||
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class
|
||||
with timer ID of -1::
|
||||
|
||||
from machine import Timer
|
||||
|
||||
tim = Timer(-1)
|
||||
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
|
||||
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
|
||||
|
||||
The period is in milliseconds.
|
||||
|
||||
Pins and GPIO
|
||||
-------------
|
||||
|
||||
Use the :ref:`machine.Pin <machine.Pin>` class::
|
||||
|
||||
from machine import Pin
|
||||
|
||||
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
|
||||
p0.on() # set pin to "on" (high) level
|
||||
p0.off() # set pin to "off" (low) level
|
||||
p0.value(1) # set pin to on/high
|
||||
|
||||
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
|
||||
print(p2.value()) # get value, 0 or 1
|
||||
|
||||
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
|
||||
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
|
||||
|
||||
Available pins are: 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, which correspond
|
||||
to the actual GPIO pin numbers of ESP8266 chip. Note that many end-user
|
||||
boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). As
|
||||
MicroPython supports different boards and modules, physical pin numbering
|
||||
was chosen as the lowest common denominator. For mapping between board
|
||||
logical pins and physical chip pins, consult your board documentation.
|
||||
|
||||
Note that Pin(1) and Pin(3) are REPL UART TX and RX respectively.
|
||||
Also note that Pin(16) is a special pin (used for wakeup from deepsleep
|
||||
mode) and may be not available for use with higher-level classes like
|
||||
``Neopixel``.
|
||||
|
||||
PWM (pulse width modulation)
|
||||
----------------------------
|
||||
|
||||
PWM can be enabled on all pins except Pin(16). There is a single frequency
|
||||
for all channels, with range between 1 and 1000 (measured in Hz). The duty
|
||||
cycle is between 0 and 1023 inclusive.
|
||||
|
||||
Use the ``machine.PWM`` class::
|
||||
|
||||
from machine import Pin, PWM
|
||||
|
||||
pwm0 = PWM(Pin(0)) # create PWM object from a pin
|
||||
pwm0.freq() # get current frequency
|
||||
pwm0.freq(1000) # set frequency
|
||||
pwm0.duty() # get current duty cycle
|
||||
pwm0.duty(200) # set duty cycle
|
||||
pwm0.deinit() # turn off PWM on the pin
|
||||
|
||||
pwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go
|
||||
|
||||
ADC (analog to digital conversion)
|
||||
----------------------------------
|
||||
|
||||
ADC is available on a dedicated pin.
|
||||
Note that input voltages on the ADC pin must be between 0v and 1.0v.
|
||||
|
||||
Use the :ref:`machine.ADC <machine.ADC>` class::
|
||||
|
||||
from machine import ADC
|
||||
|
||||
adc = ADC(0) # create ADC object on ADC pin
|
||||
adc.read() # read value, 0-1024
|
||||
|
||||
Software SPI bus
|
||||
----------------
|
||||
|
||||
There are two SPI drivers. One is implemented in software (bit-banging)
|
||||
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>`
|
||||
class::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
# construct an SPI bus on the given pins
|
||||
# polarity is the idle state of SCK
|
||||
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
||||
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
||||
|
||||
spi.init(baudrate=200000) # set the baudrate
|
||||
|
||||
spi.read(10) # read 10 bytes on MISO
|
||||
spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI
|
||||
|
||||
buf = bytearray(50) # create a buffer
|
||||
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)
|
||||
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
|
||||
|
||||
spi.write(b'12345') # write 5 bytes on MOSI
|
||||
|
||||
buf = bytearray(4) # create a buffer
|
||||
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
|
||||
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
|
||||
|
||||
|
||||
Hardware SPI bus
|
||||
----------------
|
||||
|
||||
The hardware SPI is faster (up to 80Mhz), but only works on following pins:
|
||||
``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same
|
||||
methods as the bitbanging SPI class above, except for the pin parameters for the
|
||||
constructor and init (as those are fixed)::
|
||||
|
||||
from machine import Pin, SPI
|
||||
|
||||
hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)
|
||||
|
||||
(``SPI(0)`` is used for FlashROM and not available to users.)
|
||||
|
||||
I2C bus
|
||||
-------
|
||||
|
||||
The I2C driver is implemented in software and works on all pins,
|
||||
and is accessed via the :ref:`machine.I2C <machine.I2C>` class::
|
||||
|
||||
from machine import Pin, I2C
|
||||
|
||||
# construct an I2C bus
|
||||
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
|
||||
|
||||
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a
|
||||
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
|
||||
|
||||
buf = bytearray(10) # create a buffer with 10 bytes
|
||||
i2c.writeto(0x3a, buf) # write the given buffer to the slave
|
||||
|
||||
Real time clock (RTC)
|
||||
---------------------
|
||||
|
||||
See :ref:`machine.RTC <machine.RTC>` ::
|
||||
|
||||
from machine import RTC
|
||||
|
||||
rtc = RTC()
|
||||
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
||||
rtc.datetime() # get date and time
|
||||
|
||||
# synchronize with ntp
|
||||
# need to be connected to wifi
|
||||
import ntptime
|
||||
ntptime.settime() # set the rtc datetime from the remote server
|
||||
rtc.datetime() # get the date and time in UTC
|
||||
|
||||
.. note:: Not all methods are implemented: `RTC.now()`, `RTC.irq(handler=*) <RTC.irq>`
|
||||
(using a custom handler), `RTC.init()` and `RTC.deinit()` are
|
||||
currently not supported.
|
||||
|
||||
Deep-sleep mode
|
||||
---------------
|
||||
|
||||
Connect GPIO16 to the reset pin (RST on HUZZAH). Then the following code
|
||||
can be used to sleep, wake and check the reset cause::
|
||||
|
||||
import machine
|
||||
|
||||
# configure RTC.ALARM0 to be able to wake the device
|
||||
rtc = machine.RTC()
|
||||
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
|
||||
|
||||
# check if the device woke from a deep sleep
|
||||
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
|
||||
print('woke from a deep sleep')
|
||||
|
||||
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
|
||||
rtc.alarm(rtc.ALARM0, 10000)
|
||||
|
||||
# put the device to sleep
|
||||
machine.deepsleep()
|
||||
|
||||
OneWire driver
|
||||
--------------
|
||||
|
||||
The OneWire driver is implemented in software and works on all pins::
|
||||
|
||||
from machine import Pin
|
||||
import onewire
|
||||
|
||||
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
|
||||
ow.scan() # return a list of devices on the bus
|
||||
ow.reset() # reset the bus
|
||||
ow.readbyte() # read a byte
|
||||
ow.writebyte(0x12) # write a byte on the bus
|
||||
ow.write('123') # write bytes on the bus
|
||||
ow.select_rom(b'12345678') # select a specific device by its ROM code
|
||||
|
||||
There is a specific driver for DS18S20 and DS18B20 devices::
|
||||
|
||||
import time, ds18x20
|
||||
ds = ds18x20.DS18X20(ow)
|
||||
roms = ds.scan()
|
||||
ds.convert_temp()
|
||||
time.sleep_ms(750)
|
||||
for rom in roms:
|
||||
print(ds.read_temp(rom))
|
||||
|
||||
Be sure to put a 4.7k pull-up resistor on the data line. Note that
|
||||
the ``convert_temp()`` method must be called each time you want to
|
||||
sample the temperature.
|
||||
|
||||
NeoPixel driver
|
||||
---------------
|
||||
|
||||
Use the ``neopixel`` module::
|
||||
|
||||
from machine import Pin
|
||||
from neopixel import NeoPixel
|
||||
|
||||
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels
|
||||
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels
|
||||
np[0] = (255, 255, 255) # set the first pixel to white
|
||||
np.write() # write data to all pixels
|
||||
r, g, b = np[0] # get first pixel colour
|
||||
|
||||
For low-level driving of a NeoPixel::
|
||||
|
||||
import esp
|
||||
esp.neopixel_write(pin, grb_buf, is800khz)
|
||||
|
||||
APA102 driver
|
||||
-------------
|
||||
|
||||
Use the ``apa102`` module::
|
||||
|
||||
from machine import Pin
|
||||
from apa102 import APA102
|
||||
|
||||
clock = Pin(14, Pin.OUT) # set GPIO14 to output to drive the clock
|
||||
data = Pin(13, Pin.OUT) # set GPIO13 to output to drive the data
|
||||
apa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixels
|
||||
apa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31
|
||||
apa.write() # write data to all pixels
|
||||
r, g, b, brightness = apa[0] # get first pixel colour
|
||||
|
||||
For low-level driving of an APA102::
|
||||
|
||||
import esp
|
||||
esp.apa102_write(clock_pin, data_pin, rgbi_buf)
|
||||
|
||||
DHT driver
|
||||
----------
|
||||
|
||||
The DHT driver is implemented in software and works on all pins::
|
||||
|
||||
import dht
|
||||
import machine
|
||||
|
||||
d = dht.DHT11(machine.Pin(4))
|
||||
d.measure()
|
||||
d.temperature() # eg. 23 (°C)
|
||||
d.humidity() # eg. 41 (% RH)
|
||||
|
||||
d = dht.DHT22(machine.Pin(4))
|
||||
d.measure()
|
||||
d.temperature() # eg. 23.6 (°C)
|
||||
d.humidity() # eg. 41.3 (% RH)
|
||||
|
||||
WebREPL (web browser interactive prompt)
|
||||
----------------------------------------
|
||||
|
||||
WebREPL (REPL over WebSockets, accessible via a web browser) is an
|
||||
experimental feature available in ESP8266 port. Download web client
|
||||
from https://github.com/micropython/webrepl (hosted version available
|
||||
at http://micropython.org/webrepl), and configure it by executing::
|
||||
|
||||
import webrepl_setup
|
||||
|
||||
and following on-screen instructions. After reboot, it will be available
|
||||
for connection. If you disabled automatic start-up on boot, you may
|
||||
run configured daemon on demand using::
|
||||
|
||||
import webrepl
|
||||
webrepl.start()
|
||||
|
||||
The supported way to use WebREPL is by connecting to ESP8266 access point,
|
||||
but the daemon is also started on STA interface if it is active, so if your
|
||||
router is set up and works correctly, you may also use WebREPL while connected
|
||||
to your normal Internet access point (use the ESP8266 AP connection method
|
||||
if you face any issues).
|
||||
|
||||
Besides terminal/command prompt access, WebREPL also has provision for file
|
||||
transfer (both upload and download). Web client has buttons for the
|
||||
corresponding functions, or you can use command-line client ``webrepl_cli.py``
|
||||
from the repository above.
|
||||
|
||||
See the MicroPython forum for other community-supported alternatives
|
||||
to transfer files to ESP8266.
|
|
@ -1,19 +0,0 @@
|
|||
Analog to Digital Conversion
|
||||
============================
|
||||
|
||||
The ESP8266 has a single pin (separate to the GPIO pins) which can be used to
|
||||
read analog voltages and convert them to a digital value. You can construct
|
||||
such an ADC pin object using::
|
||||
|
||||
>>> import machine
|
||||
>>> adc = machine.ADC(0)
|
||||
|
||||
Then read its value with::
|
||||
|
||||
>>> adc.read()
|
||||
58
|
||||
|
||||
The values returned from the ``read()`` function are between 0 (for 0.0 volts)
|
||||
and 1024 (for 1.0 volts). Please note that this input can only tolerate a
|
||||
maximum of 1.0 volts and you must use a voltage divider circuit to measure
|
||||
larger voltages.
|
|
@ -1,91 +0,0 @@
|
|||
Controlling APA102 LEDs
|
||||
=======================
|
||||
|
||||
APA102 LEDs, also known as DotStar LEDs, are individually addressable
|
||||
full-colour RGB LEDs, generally in a string formation. They differ from
|
||||
NeoPixels in that they require two pins to control - both a Clock and Data pin.
|
||||
They can operate at a much higher data and PWM frequencies than NeoPixels and
|
||||
are more suitable for persistence-of-vision effects.
|
||||
|
||||
To create an APA102 object do the following::
|
||||
|
||||
>>> import machine, apa102
|
||||
>>> strip = apa102.APA102(machine.Pin(5), machine.Pin(4), 60)
|
||||
|
||||
This configures an 60 pixel APA102 strip with clock on GPIO5 and data on GPIO4.
|
||||
You can adjust the pin numbers and the number of pixels to suit your needs.
|
||||
|
||||
The RGB colour data, as well as a brightness level, is sent to the APA102 in a
|
||||
certain order. Usually this is ``(Red, Green, Blue, Brightness)``.
|
||||
If you are using one of the newer APA102C LEDs the green and blue are swapped,
|
||||
so the order is ``(Red, Blue, Green, Brightness)``.
|
||||
The APA102 has more of a square lens while the APA102C has more of a round one.
|
||||
If you are using a APA102C strip and would prefer to provide colours in RGB
|
||||
order instead of RBG, you can customise the tuple colour order like so::
|
||||
|
||||
>>> strip.ORDER = (0, 2, 1, 3)
|
||||
|
||||
To set the colour of pixels use::
|
||||
|
||||
>>> strip[0] = (255, 255, 255, 31) # set to white, full brightness
|
||||
>>> strip[1] = (255, 0, 0, 31) # set to red, full brightness
|
||||
>>> strip[2] = (0, 255, 0, 15) # set to green, half brightness
|
||||
>>> strip[3] = (0, 0, 255, 7) # set to blue, quarter brightness
|
||||
|
||||
Use the ``write()`` method to output the colours to the LEDs::
|
||||
|
||||
>>> strip.write()
|
||||
|
||||
Demonstration::
|
||||
|
||||
import time
|
||||
import machine, apa102
|
||||
|
||||
# 1M strip with 60 LEDs
|
||||
strip = apa102.APA102(machine.Pin(5), machine.Pin(4), 60)
|
||||
|
||||
brightness = 1 # 0 is off, 1 is dim, 31 is max
|
||||
|
||||
# Helper for converting 0-255 offset to a colour tuple
|
||||
def wheel(offset, brightness):
|
||||
# The colours are a transition r - g - b - back to r
|
||||
offset = 255 - offset
|
||||
if offset < 85:
|
||||
return (255 - offset * 3, 0, offset * 3, brightness)
|
||||
if offset < 170:
|
||||
offset -= 85
|
||||
return (0, offset * 3, 255 - offset * 3, brightness)
|
||||
offset -= 170
|
||||
return (offset * 3, 255 - offset * 3, 0, brightness)
|
||||
|
||||
# Demo 1: RGB RGB RGB
|
||||
red = 0xff0000
|
||||
green = red >> 8
|
||||
blue = red >> 16
|
||||
for i in range(strip.n):
|
||||
colour = red >> (i % 3) * 8
|
||||
strip[i] = ((colour & red) >> 16, (colour & green) >> 8, (colour & blue), brightness)
|
||||
strip.write()
|
||||
|
||||
# Demo 2: Show all colours of the rainbow
|
||||
for i in range(strip.n):
|
||||
strip[i] = wheel((i * 256 // strip.n) % 255, brightness)
|
||||
strip.write()
|
||||
|
||||
# Demo 3: Fade all pixels together through rainbow colours, offset each pixel
|
||||
for r in range(5):
|
||||
for n in range(256):
|
||||
for i in range(strip.n):
|
||||
strip[i] = wheel(((i * 256 // strip.n) + n) & 255, brightness)
|
||||
strip.write()
|
||||
time.sleep_ms(25)
|
||||
|
||||
# Demo 4: Same colour, different brightness levels
|
||||
for b in range(31,-1,-1):
|
||||
strip[0] = (255, 153, 0, b)
|
||||
strip.write()
|
||||
time.sleep_ms(250)
|
||||
|
||||
# End: Turn off all the LEDs
|
||||
strip.fill((0, 0, 0, 0))
|
||||
strip.write()
|
|
@ -1,65 +0,0 @@
|
|||
Temperature and Humidity
|
||||
========================
|
||||
|
||||
DHT (Digital Humidity & Temperature) sensors are low cost digital sensors with
|
||||
capacitive humidity sensors and thermistors to measure the surrounding air.
|
||||
They feature a chip that handles analog to digital conversion and provide a
|
||||
1-wire interface. Newer sensors additionally provide an I2C interface.
|
||||
|
||||
The DHT11 (blue) and DHT22 (white) sensors provide the same 1-wire interface,
|
||||
however, the DHT22 requires a separate object as it has more complex
|
||||
calculation. DHT22 have 1 decimal place resolution for both humidity and
|
||||
temperature readings. DHT11 have whole number for both.
|
||||
|
||||
A custom 1-wire protocol, which is different to Dallas 1-wire, is used to get
|
||||
the measurements from the sensor. The payload consists of a humidity value,
|
||||
a temperature value and a checksum.
|
||||
|
||||
To use the 1-wire interface, construct the objects referring to their data pin::
|
||||
|
||||
>>> import dht
|
||||
>>> import machine
|
||||
>>> d = dht.DHT11(machine.Pin(4))
|
||||
|
||||
>>> import dht
|
||||
>>> import machine
|
||||
>>> d = dht.DHT22(machine.Pin(4))
|
||||
|
||||
Then measure and read their values with::
|
||||
|
||||
>>> d.measure()
|
||||
>>> d.temperature()
|
||||
>>> d.humidity()
|
||||
|
||||
Values returned from ``temperature()`` are in degrees Celsius and values
|
||||
returned from ``humidity()`` are a percentage of relative humidity.
|
||||
|
||||
The DHT11 can be called no more than once per second and the DHT22 once every
|
||||
two seconds for most accurate results. Sensor accuracy will degrade over time.
|
||||
Each sensor supports a different operating range. Refer to the product
|
||||
datasheets for specifics.
|
||||
|
||||
In 1-wire mode, only three of the four pins are used and in I2C mode, all four
|
||||
pins are used. Older sensors may still have 4 pins even though they do not
|
||||
support I2C. The 3rd pin is simply not connected.
|
||||
|
||||
Pin configurations:
|
||||
|
||||
Sensor without I2C in 1-wire mode (eg. DHT11, DHT22, AM2301, AM2302):
|
||||
|
||||
1=VDD, 2=Data, 3=NC, 4=GND
|
||||
|
||||
Sensor with I2C in 1-wire mode (eg. DHT12, AM2320, AM2321, AM2322):
|
||||
|
||||
1=VDD, 2=Data, 3=GND, 4=GND
|
||||
|
||||
Sensor with I2C in I2C mode (eg. DHT12, AM2320, AM2321, AM2322):
|
||||
|
||||
1=VDD, 2=SDA, 3=GND, 4=SCL
|
||||
|
||||
You should use pull-up resistors for the Data, SDA and SCL pins.
|
||||
|
||||
To make newer I2C sensors work in backwards compatible 1-wire mode, you must
|
||||
connect both pins 3 and 4 to GND. This disables the I2C interface.
|
||||
|
||||
DHT22 sensors are now sold under the name AM2302 and are otherwise identical.
|
|
@ -1,69 +0,0 @@
|
|||
The internal filesystem
|
||||
=======================
|
||||
|
||||
If your devices has 1Mbyte or more of storage then it will be set up (upon first
|
||||
boot) to contain a filesystem. This filesystem uses the FAT format and is
|
||||
stored in the flash after the MicroPython firmware.
|
||||
|
||||
Creating and reading files
|
||||
--------------------------
|
||||
|
||||
MicroPython on the ESP8266 supports the standard way of accessing files in
|
||||
Python, using the built-in ``open()`` function.
|
||||
|
||||
To create a file try::
|
||||
|
||||
>>> f = open('data.txt', 'w')
|
||||
>>> f.write('some data')
|
||||
9
|
||||
>>> f.close()
|
||||
|
||||
The "9" is the number of bytes that were written with the ``write()`` method.
|
||||
Then you can read back the contents of this new file using::
|
||||
|
||||
>>> f = open('data.txt')
|
||||
>>> f.read()
|
||||
'some data'
|
||||
>>> f.close()
|
||||
|
||||
Note that the default mode when opening a file is to open it in read-only mode,
|
||||
and as a text file. Specify ``'wb'`` as the second argument to ``open()`` to
|
||||
open for writing in binary mode, and ``'rb'`` to open for reading in binary
|
||||
mode.
|
||||
|
||||
Listing file and more
|
||||
---------------------
|
||||
|
||||
The os module can be used for further control over the filesystem. First
|
||||
import the module::
|
||||
|
||||
>>> import os
|
||||
|
||||
Then try listing the contents of the filesystem::
|
||||
|
||||
>>> os.listdir()
|
||||
['boot.py', 'port_config.py', 'data.txt']
|
||||
|
||||
You can make directories::
|
||||
|
||||
>>> os.mkdir('dir')
|
||||
|
||||
And remove entries::
|
||||
|
||||
>>> os.remove('data.txt')
|
||||
|
||||
Start up scripts
|
||||
----------------
|
||||
|
||||
There are two files that are treated specially by the ESP8266 when it starts up:
|
||||
boot.py and main.py. The boot.py script is executed first (if it exists) and
|
||||
then once it completes the main.py script is executed. You can create these
|
||||
files yourself and populate them with the code that you want to run when the
|
||||
device starts up.
|
||||
|
||||
Accessing the filesystem via WebREPL
|
||||
------------------------------------
|
||||
|
||||
You can access the filesystem over WebREPL using the web client in a browser
|
||||
or via the command-line tool. Please refer to Quick Reference and Tutorial
|
||||
sections for more information about WebREPL.
|
|
@ -1,34 +0,0 @@
|
|||
.. _esp8266_tutorial:
|
||||
|
||||
MicroPython tutorial for ESP8266
|
||||
================================
|
||||
|
||||
This tutorial is intended to get you started using MicroPython on the ESP8266
|
||||
system-on-a-chip. If it is your first time it is recommended to follow the
|
||||
tutorial through in the order below. Otherwise the sections are mostly self
|
||||
contained, so feel free to skip to those that interest you.
|
||||
|
||||
The tutorial does not assume that you know Python, but it also does not attempt
|
||||
to explain any of the details of the Python language. Instead it provides you
|
||||
with commands that are ready to run, and hopes that you will gain a bit of
|
||||
Python knowledge along the way. To learn more about Python itself please refer
|
||||
to `<https://www.python.org>`__.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:numbered:
|
||||
|
||||
intro.rst
|
||||
repl.rst
|
||||
filesystem.rst
|
||||
network_basics.rst
|
||||
network_tcp.rst
|
||||
pins.rst
|
||||
pwm.rst
|
||||
adc.rst
|
||||
powerctrl.rst
|
||||
onewire.rst
|
||||
neopixel.rst
|
||||
apa102.rst
|
||||
dht.rst
|
||||
nextsteps.rst
|
|
@ -1,202 +0,0 @@
|
|||
.. _intro:
|
||||
|
||||
Getting started with MicroPython on the ESP8266
|
||||
===============================================
|
||||
|
||||
Using MicroPython is a great way to get the most of your ESP8266 board. And
|
||||
vice versa, the ESP8266 chip is a great platform for using MicroPython. This
|
||||
tutorial will guide you through setting up MicroPython, getting a prompt, using
|
||||
WebREPL, connecting to the network and communicating with the Internet, using
|
||||
the hardware peripherals, and controlling some external components.
|
||||
|
||||
Let's get started!
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
The first thing you need is a board with an ESP8266 chip. The MicroPython
|
||||
software supports the ESP8266 chip itself and any board should work. The main
|
||||
characteristic of a board is how much flash it has, how the GPIO pins are
|
||||
connected to the outside world, and whether it includes a built-in USB-serial
|
||||
convertor to make the UART available to your PC.
|
||||
|
||||
The minimum requirement for flash size is 1Mbyte. There is also a special
|
||||
build for boards with 512KB, but it is highly limited comparing to the
|
||||
normal build: there is no support for filesystem, and thus features which
|
||||
depend on it won't work (WebREPL, upip, etc.). As such, 512KB build will
|
||||
be more interesting for users who build from source and fine-tune parameters
|
||||
for their particular application.
|
||||
|
||||
Names of pins will be given in this tutorial using the chip names (eg GPIO0)
|
||||
and it should be straightforward to find which pin this corresponds to on your
|
||||
particular board.
|
||||
|
||||
Powering the board
|
||||
------------------
|
||||
|
||||
If your board has a USB connector on it then most likely it is powered through
|
||||
this when connected to your PC. Otherwise you will need to power it directly.
|
||||
Please refer to the documentation for your board for further details.
|
||||
|
||||
Getting the firmware
|
||||
--------------------
|
||||
|
||||
The first thing you need to do is download the most recent MicroPython firmware
|
||||
.bin file to load onto your ESP8266 device. You can download it from the
|
||||
`MicroPython downloads page <http://micropython.org/download#esp8266>`_.
|
||||
From here, you have 3 main choices
|
||||
|
||||
* Stable firmware builds for 1024kb modules and above.
|
||||
* Daily firmware builds for 1024kb modules and above.
|
||||
* Daily firmware builds for 512kb modules.
|
||||
|
||||
If you are just starting with MicroPython, the best bet is to go for the Stable
|
||||
firmware builds. If you are an advanced, experienced MicroPython ESP8266 user
|
||||
who would like to follow development closely and help with testing new
|
||||
features, there are daily builds (note: you actually may need some
|
||||
development experience, e.g. being ready to follow git history to know
|
||||
what new changes and features were introduced).
|
||||
|
||||
Support for 512kb modules is provided on a feature preview basis. For end
|
||||
users, it's recommended to use modules with flash of 1024kb or more. As
|
||||
such, only daily builds for 512kb modules are provided.
|
||||
|
||||
Deploying the firmware
|
||||
----------------------
|
||||
|
||||
Once you have the MicroPython firmware (compiled code), you need to load it onto
|
||||
your ESP8266 device. There are two main steps to do this: first you
|
||||
need to put your device in boot-loader mode, and second you need to copy across
|
||||
the firmware. The exact procedure for these steps is highly dependent on the
|
||||
particular board and you will need to refer to its documentation for details.
|
||||
|
||||
If you have a board that has a USB connector, a USB-serial convertor, and has
|
||||
the DTR and RTS pins wired in a special way then deploying the firmware should
|
||||
be easy as all steps can be done automatically. Boards that have such features
|
||||
include the Adafruit Feather HUZZAH and NodeMCU boards.
|
||||
|
||||
For best results it is recommended to first erase the entire flash of your
|
||||
device before putting on new MicroPython firmware.
|
||||
|
||||
Currently we only support esptool.py to copy across the firmware. You can find
|
||||
this tool here: `<https://github.com/espressif/esptool/>`__, or install it
|
||||
using pip::
|
||||
|
||||
pip install esptool
|
||||
|
||||
Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer).
|
||||
An older version (at least 1.2.1 is needed) works fine but will require Python
|
||||
2.7.
|
||||
|
||||
Any other flashing program should work, so feel free to try them out or refer
|
||||
to the documentation for your board to see its recommendations.
|
||||
|
||||
Using esptool.py you can erase the flash with the command::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 erase_flash
|
||||
|
||||
And then deploy the new firmware using::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-20170108-v1.8.7.bin
|
||||
|
||||
You might need to change the "port" setting to something else relevant for your
|
||||
PC. You may also need to reduce the baudrate if you get errors when flashing
|
||||
(eg down to 115200). The filename of the firmware should also match the file
|
||||
that you have.
|
||||
|
||||
For some boards with a particular FlashROM configuration (e.g. some variants of
|
||||
a NodeMCU board) you may need to use the following command to deploy
|
||||
the firmware (note the ``-fm dio`` option)::
|
||||
|
||||
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-20170108-v1.8.7.bin
|
||||
|
||||
If the above commands run without error then MicroPython should be installed on
|
||||
your board!
|
||||
|
||||
Serial prompt
|
||||
-------------
|
||||
|
||||
Once you have the firmware on the device you can access the REPL (Python prompt)
|
||||
over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial
|
||||
convertor, depending on your board. The baudrate is 115200. The next part of
|
||||
the tutorial will discuss the prompt in more detail.
|
||||
|
||||
WiFi
|
||||
----
|
||||
|
||||
After a fresh install and boot the device configures itself as a WiFi access
|
||||
point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx
|
||||
where the x's are replaced with part of the MAC address of your device (so will
|
||||
be the same everytime, and most likely different for all ESP8266 chips). The
|
||||
password for the WiFi is micropythoN (note the upper-case N). Its IP address
|
||||
will be 192.168.4.1 once you connect to its network. WiFi configuration will
|
||||
be discussed in more detail later in the tutorial.
|
||||
|
||||
Troubleshooting installation problems
|
||||
-------------------------------------
|
||||
|
||||
If you experience problems during flashing or with running firmware immediately
|
||||
after it, here are troubleshooting recommendations:
|
||||
|
||||
* Be aware of and try to exclude hardware problems. There are 2 common problems:
|
||||
bad power source quality and worn-out/defective FlashROM. Speaking of power
|
||||
source, not just raw amperage is important, but also low ripple and noise/EMI
|
||||
in general. If you experience issues with self-made or wall-wart style power
|
||||
supply, try USB power from a computer. Unearthed power supplies are also known
|
||||
to cause problems as they source of increased EMI (electromagnetic interference)
|
||||
- at the very least, and may lead to electrical devices breakdown. So, you are
|
||||
advised to avoid using unearthed power connections when working with ESP8266
|
||||
and other boards. In regard to FlashROM hardware problems, there are independent
|
||||
(not related to MicroPython in any way) reports
|
||||
`(e.g.) <http://internetofhomethings.com/homethings/?p=538>`_
|
||||
that on some ESP8266 modules, FlashROM can be programmed as little as 20 times
|
||||
before programming errors occur. This is *much* less than 100,000 programming
|
||||
cycles cited for FlashROM chips of a type used with ESP8266 by reputable
|
||||
vendors, which points to either production rejects, or second-hand worn-out
|
||||
flash chips to be used on some (apparently cheap) modules/boards. You may want
|
||||
to use your best judgement about source, price, documentation, warranty,
|
||||
post-sales support for the modules/boards you purchase.
|
||||
|
||||
* The flashing instructions above use flashing speed of 460800 baud, which is
|
||||
good compromise between speed and stability. However, depending on your
|
||||
module/board, USB-UART convertor, cables, host OS, etc., the above baud
|
||||
rate may be too high and lead to errors. Try a more common 115200 baud
|
||||
rate instead in such cases.
|
||||
|
||||
* If lower baud rate didn't help, you may want to try older version of
|
||||
esptool.py, which had a different programming algorithm::
|
||||
|
||||
pip install esptool==1.0.1
|
||||
|
||||
This version doesn't support ``--flash_size=detect`` option, so you will
|
||||
need to specify FlashROM size explicitly (in megabits). It also requires
|
||||
Python 2.7, so you may need to use ``pip2`` instead of ``pip`` in the
|
||||
command above.
|
||||
|
||||
* The ``--flash_size`` option in the commands above is mandatory. Omitting
|
||||
it will lead to a corrupted firmware.
|
||||
|
||||
* To catch incorrect flash content (e.g. from a defective sector on a chip),
|
||||
add ``--verify`` switch to the commands above.
|
||||
|
||||
* Additionally, you can check the firmware integrity from a MicroPython REPL
|
||||
prompt (assuming you were able to flash it and ``--verify`` option doesn't
|
||||
report errors)::
|
||||
|
||||
import esp
|
||||
esp.check_fw()
|
||||
|
||||
If the last output value is True, the firmware is OK. Otherwise, it's
|
||||
corrupted and need to be reflashed correctly.
|
||||
|
||||
* If you experience any issues with another flashing application (not
|
||||
esptool.py), try esptool.py, it is a generally accepted flashing
|
||||
application in the ESP8266 community.
|
||||
|
||||
* If you still experience problems with even flashing the firmware, please
|
||||
refer to esptool.py project page, https://github.com/espressif/esptool
|
||||
for additional documentation and bug tracker where you can report problems.
|
||||
|
||||
* If you are able to flash firmware, but ``--verify`` option or
|
||||
``esp.check_fw()`` return errors even after multiple retries, you
|
||||
may have a defective FlashROM chip, as explained above.
|
|
@ -1,84 +0,0 @@
|
|||
Controlling NeoPixels
|
||||
=====================
|
||||
|
||||
NeoPixels, also known as WS2812 LEDs, are full-colour LEDs that are connected in
|
||||
serial, are individually addressable, and can have their red, green and blue
|
||||
components set between 0 and 255. They require precise timing to control them
|
||||
and there is a special neopixel module to do just this.
|
||||
|
||||
To create a NeoPixel object do the following::
|
||||
|
||||
>>> import machine, neopixel
|
||||
>>> np = neopixel.NeoPixel(machine.Pin(4), 8)
|
||||
|
||||
This configures a NeoPixel strip on GPIO4 with 8 pixels. You can adjust the
|
||||
"4" (pin number) and the "8" (number of pixel) to suit your set up.
|
||||
|
||||
To set the colour of pixels use::
|
||||
|
||||
>>> np[0] = (255, 0, 0) # set to red, full brightness
|
||||
>>> np[1] = (0, 128, 0) # set to green, half brightness
|
||||
>>> np[2] = (0, 0, 64) # set to blue, quarter brightness
|
||||
|
||||
For LEDs with more than 3 colours, such as RGBW pixels or RGBY pixels, the
|
||||
NeoPixel class takes a ``bpp`` parameter. To setup a NeoPixel object for an
|
||||
RGBW Pixel, do the following::
|
||||
|
||||
>>> import machine, neopixel
|
||||
>>> np = neopixel.NeoPixel(machine.Pin(4), 8, bpp=4)
|
||||
|
||||
In a 4-bpp mode, remember to use 4-tuples instead of 3-tuples to set the colour.
|
||||
For example to set the first three pixels use::
|
||||
|
||||
>>> np[0] = (255, 0, 0, 128) # Orange in an RGBY Setup
|
||||
>>> np[1] = (0, 255, 0, 128) # Yellow-green in an RGBY Setup
|
||||
>>> np[2] = (0, 0, 255, 128) # Green-blue in an RGBY Setup
|
||||
|
||||
Then use the ``write()`` method to output the colours to the LEDs::
|
||||
|
||||
>>> np.write()
|
||||
|
||||
The following demo function makes a fancy show on the LEDs::
|
||||
|
||||
import time
|
||||
|
||||
def demo(np):
|
||||
n = np.n
|
||||
|
||||
# cycle
|
||||
for i in range(4 * n):
|
||||
for j in range(n):
|
||||
np[j] = (0, 0, 0)
|
||||
np[i % n] = (255, 255, 255)
|
||||
np.write()
|
||||
time.sleep_ms(25)
|
||||
|
||||
# bounce
|
||||
for i in range(4 * n):
|
||||
for j in range(n):
|
||||
np[j] = (0, 0, 128)
|
||||
if (i // n) % 2 == 0:
|
||||
np[i % n] = (0, 0, 0)
|
||||
else:
|
||||
np[n - 1 - (i % n)] = (0, 0, 0)
|
||||
np.write()
|
||||
time.sleep_ms(60)
|
||||
|
||||
# fade in/out
|
||||
for i in range(0, 4 * 256, 8):
|
||||
for j in range(n):
|
||||
if (i // 256) % 2 == 0:
|
||||
val = i & 0xff
|
||||
else:
|
||||
val = 255 - (i & 0xff)
|
||||
np[j] = (val, 0, 0)
|
||||
np.write()
|
||||
|
||||
# clear
|
||||
for i in range(n):
|
||||
np[i] = (0, 0, 0)
|
||||
np.write()
|
||||
|
||||
Execute it using::
|
||||
|
||||
>>> demo(np)
|
|
@ -1,81 +0,0 @@
|
|||
Network basics
|
||||
==============
|
||||
|
||||
The network module is used to configure the WiFi connection. There are two WiFi
|
||||
interfaces, one for the station (when the ESP8266 connects to a router) and one
|
||||
for the access point (for other devices to connect to the ESP8266). Create
|
||||
instances of these objects using::
|
||||
|
||||
>>> import network
|
||||
>>> sta_if = network.WLAN(network.STA_IF)
|
||||
>>> ap_if = network.WLAN(network.AP_IF)
|
||||
|
||||
You can check if the interfaces are active by::
|
||||
|
||||
>>> sta_if.active()
|
||||
False
|
||||
>>> ap_if.active()
|
||||
True
|
||||
|
||||
You can also check the network settings of the interface by::
|
||||
|
||||
>>> ap_if.ifconfig()
|
||||
('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
|
||||
|
||||
The returned values are: IP address, netmask, gateway, DNS.
|
||||
|
||||
Configuration of the WiFi
|
||||
-------------------------
|
||||
|
||||
Upon a fresh install the ESP8266 is configured in access point mode, so the
|
||||
AP_IF interface is active and the STA_IF interface is inactive. You can
|
||||
configure the module to connect to your own network using the STA_IF interface.
|
||||
|
||||
First activate the station interface::
|
||||
|
||||
>>> sta_if.active(True)
|
||||
|
||||
Then connect to your WiFi network::
|
||||
|
||||
>>> sta_if.connect('<your ESSID>', '<your password>')
|
||||
|
||||
To check if the connection is established use::
|
||||
|
||||
>>> sta_if.isconnected()
|
||||
|
||||
Once established you can check the IP address::
|
||||
|
||||
>>> sta_if.ifconfig()
|
||||
('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::
|
||||
|
||||
>>> ap_if.active(False)
|
||||
|
||||
Here is a function you can run (or put in your boot.py file) to automatically
|
||||
connect to your WiFi network::
|
||||
|
||||
def do_connect():
|
||||
import network
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
if not sta_if.isconnected():
|
||||
print('connecting to network...')
|
||||
sta_if.active(True)
|
||||
sta_if.connect('<essid>', '<password>')
|
||||
while not sta_if.isconnected():
|
||||
pass
|
||||
print('network config:', sta_if.ifconfig())
|
||||
|
||||
Sockets
|
||||
-------
|
||||
|
||||
Once the WiFi is set up the way to access the network is by using sockets.
|
||||
A socket represents an endpoint on a network device, and when two sockets are
|
||||
connected together communication can proceed.
|
||||
Internet protocols are built on top of sockets, such as email (SMTP), the web
|
||||
(HTTP), telnet, ssh, among many others. Each of these protocols is assigned
|
||||
a specific port, which is just an integer. Given an IP address and a port
|
||||
number you can connect to a remote device and start talking with it.
|
||||
|
||||
The next part of the tutorial discusses how to use sockets to do some common
|
||||
and useful network tasks.
|
|
@ -1,122 +0,0 @@
|
|||
Network - TCP sockets
|
||||
=====================
|
||||
|
||||
The building block of most of the internet is the TCP socket. These sockets
|
||||
provide a reliable stream of bytes between the connected network devices.
|
||||
This part of the tutorial will show how to use TCP sockets in a few different
|
||||
cases.
|
||||
|
||||
Star Wars Asciimation
|
||||
---------------------
|
||||
|
||||
The simplest thing to do is to download data from the internet. In this case
|
||||
we will use the Star Wars Asciimation service provided by the blinkenlights.nl
|
||||
website. It uses the telnet protocol on port 23 to stream data to anyone that
|
||||
connects. It's very simple to use because it doesn't require you to
|
||||
authenticate (give a username or password), you can just start downloading data
|
||||
straight away.
|
||||
|
||||
The first thing to do is make sure we have the socket module available::
|
||||
|
||||
>>> import socket
|
||||
|
||||
Then get the IP address of the server::
|
||||
|
||||
>>> addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23)
|
||||
|
||||
The ``getaddrinfo`` function actually returns a list of addresses, and each
|
||||
address has more information than we need. We want to get just the first valid
|
||||
address, and then just the IP address and port of the server. To do this use::
|
||||
|
||||
>>> addr = addr_info[0][-1]
|
||||
|
||||
If you type ``addr_info`` and ``addr`` at the prompt you will see exactly what
|
||||
information they hold.
|
||||
|
||||
Using the IP address we can make a socket and connect to the server::
|
||||
|
||||
>>> s = socket.socket()
|
||||
>>> s.connect(addr)
|
||||
|
||||
Now that we are connected we can download and display the data::
|
||||
|
||||
>>> while True:
|
||||
... data = s.recv(500)
|
||||
... print(str(data, 'utf8'), end='')
|
||||
...
|
||||
|
||||
When this loop executes it should start showing the animation (use ctrl-C to
|
||||
interrupt it).
|
||||
|
||||
You should also be able to run this same code on your PC using normal Python if
|
||||
you want to try it out there.
|
||||
|
||||
HTTP GET request
|
||||
----------------
|
||||
|
||||
The next example shows how to download a webpage. HTTP uses port 80 and you
|
||||
first need to send a "GET" request before you can download anything. As part
|
||||
of the request you need to specify the page to retrieve.
|
||||
|
||||
Let's define a function that can download and print a URL::
|
||||
|
||||
def http_get(url):
|
||||
import socket
|
||||
_, _, host, path = url.split('/', 3)
|
||||
addr = socket.getaddrinfo(host, 80)[0][-1]
|
||||
s = socket.socket()
|
||||
s.connect(addr)
|
||||
s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
|
||||
while True:
|
||||
data = s.recv(100)
|
||||
if data:
|
||||
print(str(data, 'utf8'), end='')
|
||||
else:
|
||||
break
|
||||
s.close()
|
||||
|
||||
Then you can try::
|
||||
|
||||
>>> http_get('http://micropython.org/ks/test.html')
|
||||
|
||||
This should retrieve the webpage and print the HTML to the console.
|
||||
|
||||
Simple HTTP server
|
||||
------------------
|
||||
|
||||
The following code creates an simple HTTP server which serves a single webpage
|
||||
that contains a table with the state of all the GPIO pins::
|
||||
|
||||
import machine
|
||||
pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)]
|
||||
|
||||
html = """<!DOCTYPE html>
|
||||
<html>
|
||||
<head> <title>ESP8266 Pins</title> </head>
|
||||
<body> <h1>ESP8266 Pins</h1>
|
||||
<table border="1"> <tr><th>Pin</th><th>Value</th></tr> %s </table>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
import socket
|
||||
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
|
||||
|
||||
s = socket.socket()
|
||||
s.bind(addr)
|
||||
s.listen(1)
|
||||
|
||||
print('listening on', addr)
|
||||
|
||||
while True:
|
||||
cl, addr = s.accept()
|
||||
print('client connected from', addr)
|
||||
cl_file = cl.makefile('rwb', 0)
|
||||
while True:
|
||||
line = cl_file.readline()
|
||||
if not line or line == b'\r\n':
|
||||
break
|
||||
rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins]
|
||||
response = html % '\n'.join(rows)
|
||||
cl.send(response)
|
||||
cl.close()
|
|
@ -1,12 +0,0 @@
|
|||
Next steps
|
||||
==========
|
||||
|
||||
That brings us to the end of the tutorial! Hopefully by now you have a good
|
||||
feel for the capabilities of MicroPython on the ESP8266 and understand how to
|
||||
control both the WiFi and IO aspects of the chip.
|
||||
|
||||
There are many features that were not covered in this tutorial. The best way
|
||||
to learn about them is to read the full documentation of the modules, and to
|
||||
experiment!
|
||||
|
||||
Good luck creating your Internet of Things devices!
|
|
@ -1,37 +0,0 @@
|
|||
Controlling 1-wire devices
|
||||
==========================
|
||||
|
||||
The 1-wire bus is a serial bus that uses just a single wire for communication
|
||||
(in addition to wires for ground and power). The DS18B20 temperature sensor
|
||||
is a very popular 1-wire device, and here we show how to use the onewire module
|
||||
to read from such a device.
|
||||
|
||||
For the following code to work you need to have at least one DS18S20 or DS18B20 temperature
|
||||
sensor with its data line connected to GPIO12. You must also power the sensors
|
||||
and connect a 4.7k Ohm resistor between the data pin and the power pin. ::
|
||||
|
||||
import time
|
||||
import machine
|
||||
import onewire, ds18x20
|
||||
|
||||
# the device is on GPIO12
|
||||
dat = machine.Pin(12)
|
||||
|
||||
# create the onewire object
|
||||
ds = ds18x20.DS18X20(onewire.OneWire(dat))
|
||||
|
||||
# scan for devices on the bus
|
||||
roms = ds.scan()
|
||||
print('found devices:', roms)
|
||||
|
||||
# loop 10 times and print all temperatures
|
||||
for i in range(10):
|
||||
print('temperatures:', end=' ')
|
||||
ds.convert_temp()
|
||||
time.sleep_ms(750)
|
||||
for rom in roms:
|
||||
print(ds.read_temp(rom), end=' ')
|
||||
print()
|
||||
|
||||
Note that you must execute the ``convert_temp()`` function to initiate a
|
||||
temperature reading, then wait at least 750ms before reading the value.
|
|
@ -1,76 +0,0 @@
|
|||
GPIO Pins
|
||||
=========
|
||||
|
||||
The way to connect your board to the external world, and control other
|
||||
components, is through the GPIO pins. Not all pins are available to use,
|
||||
in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used.
|
||||
|
||||
The pins are available in the machine module, so make sure you import that
|
||||
first. Then you can create a pin using::
|
||||
|
||||
>>> pin = machine.Pin(0)
|
||||
|
||||
Here, the "0" is the pin that you want to access. Usually you want to
|
||||
configure the pin to be input or output, and you do this when constructing
|
||||
it. To make an input pin use::
|
||||
|
||||
>>> pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
|
||||
|
||||
You can either use PULL_UP or None for the input pull-mode. If it's
|
||||
not specified then it defaults to None, which is no pull resistor. GPIO16
|
||||
has no pull-up mode.
|
||||
You can read the value on the pin using::
|
||||
|
||||
>>> pin.value()
|
||||
0
|
||||
|
||||
The pin on your board may return 0 or 1 here, depending on what it's connected
|
||||
to. To make an output pin use::
|
||||
|
||||
>>> pin = machine.Pin(0, machine.Pin.OUT)
|
||||
|
||||
Then set its value using::
|
||||
|
||||
>>> pin.value(0)
|
||||
>>> pin.value(1)
|
||||
|
||||
Or::
|
||||
|
||||
>>> pin.off()
|
||||
>>> pin.on()
|
||||
|
||||
External interrupts
|
||||
-------------------
|
||||
|
||||
All pins except number 16 can be configured to trigger a hard interrupt if their
|
||||
input changes. You can set code (a callback function) to be executed on the
|
||||
trigger.
|
||||
|
||||
Let's first define a callback function, which must take a single argument,
|
||||
being the pin that triggered the function. We will make the function just print
|
||||
the pin::
|
||||
|
||||
>>> def callback(p):
|
||||
... print('pin change', p)
|
||||
|
||||
Next we will create two pins and configure them as inputs::
|
||||
|
||||
>>> from machine import Pin
|
||||
>>> p0 = Pin(0, Pin.IN)
|
||||
>>> p2 = Pin(2, Pin.IN)
|
||||
|
||||
An finally we need to tell the pins when to trigger, and the function to call
|
||||
when they detect an event::
|
||||
|
||||
>>> p0.irq(trigger=Pin.IRQ_FALLING, handler=callback)
|
||||
>>> p2.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=callback)
|
||||
|
||||
We set pin 0 to trigger only on a falling edge of the input (when it goes from
|
||||
high to low), and set pin 2 to trigger on both a rising and falling edge. After
|
||||
entering this code you can apply high and low voltages to pins 0 and 2 to see
|
||||
the interrupt being executed.
|
||||
|
||||
A hard interrupt will trigger as soon as the event occurs and will interrupt any
|
||||
running code, including Python code. As such your callback functions are
|
||||
limited in what they can do (they cannot allocate memory, for example) and
|
||||
should be as short and simple as possible.
|
|
@ -1,61 +0,0 @@
|
|||
Power control
|
||||
=============
|
||||
|
||||
The ESP8266 provides the ability to change the CPU frequency on the fly, and
|
||||
enter a deep-sleep state. Both can be used to manage power consumption.
|
||||
|
||||
Changing the CPU frequency
|
||||
--------------------------
|
||||
|
||||
The machine module has a function to get and set the CPU frequency. To get the
|
||||
current frequency use::
|
||||
|
||||
>>> import machine
|
||||
>>> machine.freq()
|
||||
80000000
|
||||
|
||||
By default the CPU runs at 80MHz. It can be changed to 160MHz if you need more
|
||||
processing power, at the expense of current consumption::
|
||||
|
||||
>>> machine.freq(160000000)
|
||||
>>> machine.freq()
|
||||
160000000
|
||||
|
||||
You can change to the higher frequency just while your code does the heavy
|
||||
processing and then change back when it's finished.
|
||||
|
||||
Deep-sleep mode
|
||||
---------------
|
||||
|
||||
The deep-sleep mode will shut down the ESP8266 and all its peripherals,
|
||||
including the WiFi (but not including the real-time-clock, which is used to wake
|
||||
the chip). This drastically reduces current consumption and is a good way to
|
||||
make devices that can run for a while on a battery.
|
||||
|
||||
To be able to use the deep-sleep feature you must connect GPIO16 to the reset
|
||||
pin (RST on the Adafruit Feather HUZZAH board). Then the following code can be
|
||||
used to sleep and wake the device::
|
||||
|
||||
import machine
|
||||
|
||||
# configure RTC.ALARM0 to be able to wake the device
|
||||
rtc = machine.RTC()
|
||||
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
|
||||
|
||||
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
|
||||
rtc.alarm(rtc.ALARM0, 10000)
|
||||
|
||||
# put the device to sleep
|
||||
machine.deepsleep()
|
||||
|
||||
Note that when the chip wakes from a deep-sleep it is completely reset,
|
||||
including all of the memory. The boot scripts will run as usual and you can
|
||||
put code in them to check the reset cause to perhaps do something different if
|
||||
the device just woke from a deep-sleep. For example, to print the reset cause
|
||||
you can use::
|
||||
|
||||
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
|
||||
print('woke from a deep sleep')
|
||||
else:
|
||||
print('power on or hard reset')
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
Pulse Width Modulation
|
||||
======================
|
||||
|
||||
Pulse width modulation (PWM) is a way to get an artificial analog output on a
|
||||
digital pin. It achieves this by rapidly toggling the pin from low to high.
|
||||
There are two parameters associated with this: the frequency of the toggling,
|
||||
and the duty cycle. The duty cycle is defined to be how long the pin is high
|
||||
compared with the length of a single period (low plus high time). Maximum
|
||||
duty cycle is when the pin is high all of the time, and minimum is when it is
|
||||
low all of the time.
|
||||
|
||||
On the ESP8266 the pins 0, 2, 4, 5, 12, 13, 14 and 15 all support PWM. The
|
||||
limitation is that they must all be at the same frequency, and the frequency
|
||||
must be between 1Hz and 1kHz.
|
||||
|
||||
To use PWM on a pin you must first create the pin object, for example::
|
||||
|
||||
>>> import machine
|
||||
>>> p12 = machine.Pin(12)
|
||||
|
||||
Then create the PWM object using::
|
||||
|
||||
>>> pwm12 = machine.PWM(p12)
|
||||
|
||||
You can set the frequency and duty cycle using::
|
||||
|
||||
>>> pwm12.freq(500)
|
||||
>>> pwm12.duty(512)
|
||||
|
||||
Note that the duty cycle is between 0 (all off) and 1023 (all on), with 512
|
||||
being a 50% duty. Values beyond this min/max will be clipped. If you
|
||||
print the PWM object then it will tell you its current configuration::
|
||||
|
||||
>>> pwm12
|
||||
PWM(12, freq=500, duty=512)
|
||||
|
||||
You can also call the ``freq()`` and ``duty()`` methods with no arguments to
|
||||
get their current values.
|
||||
|
||||
The pin will continue to be in PWM mode until you deinitialise it using::
|
||||
|
||||
>>> pwm12.deinit()
|
||||
|
||||
Fading an LED
|
||||
-------------
|
||||
|
||||
Let's use the PWM feature to fade an LED. Assuming your board has an LED
|
||||
connected to pin 2 (ESP-12 modules do) we can create an LED-PWM object using::
|
||||
|
||||
>>> led = machine.PWM(machine.Pin(2), freq=1000)
|
||||
|
||||
Notice that we can set the frequency in the PWM constructor.
|
||||
|
||||
For the next part we will use timing and some math, so import these modules::
|
||||
|
||||
>>> import time, math
|
||||
|
||||
Then create a function to pulse the LED::
|
||||
|
||||
>>> def pulse(l, t):
|
||||
... for i in range(20):
|
||||
... l.duty(int(math.sin(i / 10 * math.pi) * 500 + 500))
|
||||
... time.sleep_ms(t)
|
||||
|
||||
You can try this function out using::
|
||||
|
||||
>>> pulse(led, 50)
|
||||
|
||||
For a nice effect you can pulse many times in a row::
|
||||
|
||||
>>> for i in range(10):
|
||||
... pulse(led, 20)
|
||||
|
||||
Remember you can use ctrl-C to interrupt the code.
|
||||
|
||||
Control a hobby servo
|
||||
---------------------
|
||||
|
||||
Hobby servo motors can be controlled using PWM. They require a frequency of
|
||||
50Hz and then a duty between about 40 and 115, with 77 being the centre value.
|
||||
If you connect a servo to the power and ground pins, and then the signal line
|
||||
to pin 12 (other pins will work just as well), you can control the motor using::
|
||||
|
||||
>>> servo = machine.PWM(machine.Pin(12), freq=50)
|
||||
>>> servo.duty(40)
|
||||
>>> servo.duty(115)
|
||||
>>> servo.duty(77)
|
|
@ -1,212 +0,0 @@
|
|||
Getting a MicroPython REPL prompt
|
||||
=================================
|
||||
|
||||
REPL stands for Read Evaluate Print Loop, and is the name given to the
|
||||
interactive MicroPython prompt that you can access on the ESP8266. Using the
|
||||
REPL is by far the easiest way to test out your code and run commands.
|
||||
|
||||
There are two ways to access the REPL: either via a wired connection through the
|
||||
UART serial port, or via WiFi.
|
||||
|
||||
REPL over the serial port
|
||||
-------------------------
|
||||
|
||||
The REPL is always available on the UART0 serial peripheral, which is connected
|
||||
to the pins GPIO1 for TX and GPIO3 for RX. The baudrate of the REPL is 115200.
|
||||
If your board has a USB-serial convertor on it then you should be able to access
|
||||
the REPL directly from your PC. Otherwise you will need to have a way of
|
||||
communicating with the UART.
|
||||
|
||||
To access the prompt over USB-serial you need to use a terminal emulator program.
|
||||
On Windows TeraTerm is a good choice, on Mac you can use the built-in screen
|
||||
program, and Linux has picocom and minicom. Of course, there are many other
|
||||
terminal programs that will work, so pick your favourite!
|
||||
|
||||
For example, on Linux you can try running::
|
||||
|
||||
picocom /dev/ttyUSB0 -b115200
|
||||
|
||||
Once you have made the connection over the serial port you can test if it is
|
||||
working by hitting enter a few times. You should see the Python REPL prompt,
|
||||
indicated by ``>>>``.
|
||||
|
||||
WebREPL - a prompt over WiFi
|
||||
----------------------------
|
||||
|
||||
WebREPL allows you to use the Python prompt over WiFi, connecting through a
|
||||
browser. The latest versions of Firefox and Chrome are supported.
|
||||
|
||||
For your convenience, WebREPL client is hosted at
|
||||
`<http://micropython.org/webrepl>`__ . Alternatively, you can install it
|
||||
locally from the the GitHub repository
|
||||
`<https://github.com/micropython/webrepl>`__ .
|
||||
|
||||
Before connecting to WebREPL, you should set a password and enable it via
|
||||
a normal serial connection. Initial versions of MicroPython for ESP8266
|
||||
came with WebREPL automatically enabled on the boot and with the
|
||||
ability to set a password via WiFi on the first connection, but as WebREPL
|
||||
was becoming more widely known and popular, the initial setup has switched
|
||||
to a wired connection for improved security::
|
||||
|
||||
import webrepl_setup
|
||||
|
||||
Follow the on-screen instructions and prompts. To make any changes active,
|
||||
you will need to reboot your device.
|
||||
|
||||
To use WebREPL connect your computer to the ESP8266's access point
|
||||
(MicroPython-xxxxxx, see the previous section about this). If you have
|
||||
already reconfigured your ESP8266 to connect to a router then you can
|
||||
skip this part.
|
||||
|
||||
Once you are on the same network as the ESP8266 you click the "Connect" button
|
||||
(if you are connecting via a router then you may need to change the IP address,
|
||||
by default the IP address is correct when connected to the ESP8266's access
|
||||
point). If the connection succeeds then you should see a password prompt.
|
||||
|
||||
Once you type the password configured at the setup step above, press Enter once
|
||||
more and you should get a prompt looking like ``>>>``. You can now start
|
||||
typing Python commands!
|
||||
|
||||
Using the REPL
|
||||
--------------
|
||||
|
||||
Once you have a prompt you can start experimenting! Anything you type at the
|
||||
prompt will be executed after you press the Enter key. MicroPython will run
|
||||
the code that you enter and print the result (if there is one). If there is an
|
||||
error with the text that you enter then an error message is printed.
|
||||
|
||||
Try typing the following at the prompt::
|
||||
|
||||
>>> print('hello esp8266!')
|
||||
hello esp8266!
|
||||
|
||||
Note that you shouldn't type the ``>>>`` arrows, they are there to indicate that
|
||||
you should type the text after it at the prompt. And then the line following is
|
||||
what the device should respond with. In the end, once you have entered the text
|
||||
``print("hello esp8266!")`` and pressed the Enter key, the output on your screen
|
||||
should look exactly like it does above.
|
||||
|
||||
If you already know some python you can now try some basic commands here. For
|
||||
example::
|
||||
|
||||
>>> 1 + 2
|
||||
3
|
||||
>>> 1 / 2
|
||||
0.5
|
||||
>>> 12**34
|
||||
4922235242952026704037113243122008064
|
||||
|
||||
If your board has an LED attached to GPIO2 (the ESP-12 modules do) then you can
|
||||
turn it on and off using the following code::
|
||||
|
||||
>>> import machine
|
||||
>>> pin = machine.Pin(2, machine.Pin.OUT)
|
||||
>>> pin.on()
|
||||
>>> pin.off()
|
||||
|
||||
Note that ``on`` method of a Pin might turn the LED off and ``off`` might
|
||||
turn it on (or vice versa), depending on how the LED is wired on your board.
|
||||
To resolve this, machine.Signal class is provided.
|
||||
|
||||
Line editing
|
||||
~~~~~~~~~~~~
|
||||
|
||||
You can edit the current line that you are entering using the left and right
|
||||
arrow keys to move the cursor, as well as the delete and backspace keys. Also,
|
||||
pressing Home or ctrl-A moves the cursor to the start of the line, and pressing
|
||||
End or ctrl-E moves to the end of the line.
|
||||
|
||||
Input history
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The REPL remembers a certain number of previous lines of text that you entered
|
||||
(up to 8 on the ESP8266). To recall previous lines use the up and down arrow
|
||||
keys.
|
||||
|
||||
Tab completion
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Pressing the Tab key will do an auto-completion of the current word that you are
|
||||
entering. This can be very useful to find out functions and methods that a
|
||||
module or object has. Try it out by typing "ma" and then pressing Tab. It
|
||||
should complete to "machine" (assuming you imported machine in the above
|
||||
example). Then type "." and press Tab again to see a list of all the functions
|
||||
that the machine module has.
|
||||
|
||||
Line continuation and auto-indent
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Certain things that you type will need "continuing", that is, will need more
|
||||
lines of text to make a proper Python statement. In this case the prompt will
|
||||
change to ``...`` and the cursor will auto-indent the correct amount so you can
|
||||
start typing the next line straight away. Try this by defining the following
|
||||
function::
|
||||
|
||||
>>> def toggle(p):
|
||||
... p.value(not p.value())
|
||||
...
|
||||
...
|
||||
...
|
||||
>>>
|
||||
|
||||
In the above, you needed to press the Enter key three times in a row to finish
|
||||
the compound statement (that's the three lines with just dots on them). The
|
||||
other way to finish a compound statement is to press backspace to get to the
|
||||
start of the line, then press the Enter key. (If you did something wrong and
|
||||
want to escape the continuation mode then press ctrl-C; all lines will be
|
||||
ignored.)
|
||||
|
||||
The function you just defined allows you to toggle a pin. The pin object you
|
||||
created earlier should still exist (recreate it if it doesn't) and you can
|
||||
toggle the LED using::
|
||||
|
||||
>>> toggle(pin)
|
||||
|
||||
Let's now toggle the LED in a loop (if you don't have an LED then you can just
|
||||
print some text instead of calling toggle, to see the effect)::
|
||||
|
||||
>>> import time
|
||||
>>> while True:
|
||||
... toggle(pin)
|
||||
... time.sleep_ms(500)
|
||||
...
|
||||
...
|
||||
...
|
||||
>>>
|
||||
|
||||
This will toggle the LED at 1Hz (half a second on, half a second off). To stop
|
||||
the toggling press ctrl-C, which will raise a KeyboardInterrupt exception and
|
||||
break out of the loop.
|
||||
|
||||
The time module provides some useful functions for making delays and doing
|
||||
timing. Use tab completion to find out what they are and play around with them!
|
||||
|
||||
Paste mode
|
||||
~~~~~~~~~~
|
||||
|
||||
Pressing ctrl-E will enter a special paste mode. This allows you to copy and
|
||||
paste a chunk of text into the REPL. If you press ctrl-E you will see the
|
||||
paste-mode prompt::
|
||||
|
||||
paste mode; Ctrl-C to cancel, Ctrl-D to finish
|
||||
===
|
||||
|
||||
You can then paste (or type) your text in. Note that none of the special keys
|
||||
or commands work in paste mode (eg Tab or backspace), they are just accepted
|
||||
as-is. Press ctrl-D to finish entering the text and execute it.
|
||||
|
||||
Other control commands
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are four other control commands:
|
||||
|
||||
* Ctrl-A on a blank line will enter raw REPL mode. This is like a permanent
|
||||
paste mode, except that characters are not echoed back.
|
||||
|
||||
* Ctrl-B on a blank like goes to normal REPL mode.
|
||||
|
||||
* Ctrl-C cancels any input, or interrupts the currently running code.
|
||||
|
||||
* Ctrl-D on a blank line will do a soft reset.
|
||||
|
||||
Note that ctrl-A and ctrl-D do not work with WebREPL.
|
|
@ -0,0 +1,62 @@
|
|||
General information about the pyboard
|
||||
=====================================
|
||||
|
||||
Local filesystem and SD card
|
||||
----------------------------
|
||||
|
||||
There is a small internal filesystem (a drive) on the pyboard, called ``/flash``,
|
||||
which is stored within the microcontroller's flash memory. If a micro SD card
|
||||
is inserted into the slot, it is available as ``/sd``.
|
||||
|
||||
When the pyboard boots up, it needs to choose a filesystem to boot from. If
|
||||
there is no SD card, then it uses the internal filesystem ``/flash`` as the boot
|
||||
filesystem, otherwise, it uses the SD card ``/sd``.
|
||||
|
||||
(Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd``
|
||||
is called ``1:/``).
|
||||
|
||||
The boot filesystem is used for 2 things: it is the filesystem from which
|
||||
the ``boot.py`` and ``main.py`` files are searched for, and it is the filesystem
|
||||
which is made available on your PC over the USB cable.
|
||||
|
||||
The filesystem will be available as a USB flash drive on your PC. You can
|
||||
save files to the drive, and edit ``boot.py`` and ``main.py``.
|
||||
|
||||
*Remember to eject (on Linux, unmount) the USB drive before you reset your
|
||||
pyboard.*
|
||||
|
||||
Boot modes
|
||||
----------
|
||||
|
||||
If you power up normally, or press the reset button, the pyboard will boot
|
||||
into standard mode: the ``boot.py`` file will be executed first, then the
|
||||
USB will be configured, then ``main.py`` will run.
|
||||
|
||||
You can override this boot sequence by holding down the user switch as
|
||||
the board is booting up. Hold down user switch and press reset, and then
|
||||
as you continue to hold the user switch, the LEDs will count in binary.
|
||||
When the LEDs have reached the mode you want, let go of the user switch,
|
||||
the LEDs for the selected mode will flash quickly, and the board will boot.
|
||||
|
||||
The modes are:
|
||||
|
||||
1. Green LED only, *standard boot*: run ``boot.py`` then ``main.py``.
|
||||
2. Orange LED only, *safe boot*: don't run any scripts on boot-up.
|
||||
3. Green and orange LED together, *filesystem reset*: resets the flash
|
||||
filesystem to its factory state, then boots in safe mode.
|
||||
|
||||
If your filesystem becomes corrupt, boot into mode 3 to fix it.
|
||||
If resetting the filesystem while plugged into your compute doesn't work,
|
||||
you can try doing the same procedure while the board is plugged into a USB
|
||||
charger, or other USB power supply without data connection.
|
||||
|
||||
Errors: flashing LEDs
|
||||
---------------------
|
||||
|
||||
There are currently 2 kinds of errors that you might see:
|
||||
|
||||
1. If the red and green LEDs flash alternatively, then a Python script
|
||||
(eg ``main.py``) has an error. Use the REPL to debug it.
|
||||
2. If all 4 LEDs cycle on and off slowly, then there was a hard fault.
|
||||
This cannot be recovered from and you need to do a hard reset.
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
.. _hardware_index:
|
||||
|
||||
The pyboard hardware
|
||||
====================
|
||||
|
||||
For the pyboard:
|
||||
|
||||
* `PYBv1.0 schematics and layout <http://micropython.org/resources/PYBv10b.pdf>`_ (2.4MiB PDF)
|
||||
* `PYBv1.0 metric dimensions <http://micropython.org/resources/PYBv10b-metric-dimensions.pdf>`_ (360KiB PDF)
|
||||
* `PYBv1.0 imperial dimensions <http://micropython.org/resources/PYBv10b-imperial-dimensions.pdf>`_ (360KiB PDF)
|
||||
|
||||
For the official skin modules:
|
||||
|
||||
* `LCD32MKv1.0 schematics <http://micropython.org/resources/LCD32MKv10-schematics.pdf>`_ (194KiB PDF)
|
||||
* `AMPv1.0 schematics <http://micropython.org/resources/AMPv10-schematics.pdf>`_ (209KiB PDF)
|
||||
|
||||
Datasheets for the components on the pyboard
|
||||
============================================
|
||||
|
||||
* The microcontroller: `STM32F405RGT6 <http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144>`_ (link to manufacturer's site)
|
||||
* The accelerometer: `Freescale MMA7660 <http://micropython.org/resources/datasheets/MMA7660FC.pdf>`_ (800kiB PDF)
|
||||
* The LDO voltage regulator: `Microchip MCP1802 <http://micropython.org/resources/datasheets/MCP1802-22053C.pdf>`_ (400kiB PDF)
|
||||
|
||||
Datasheets for other components
|
||||
===============================
|
||||
|
||||
* The LCD display on the LCD touch-sensor skin: `Newhaven Display NHD-C12832A1Z-FSW-FBW-3V3 <http://micropython.org/resources/datasheets/NHD-C12832A1Z-FSW-FBW-3V3.pdf>`_ (460KiB PDF)
|
||||
* The touch sensor chip on the LCD touch-sensor skin: `Freescale MPR121 <http://micropython.org/resources/datasheets/MPR121.pdf>`_ (280KiB PDF)
|
||||
* The digital potentiometer on the audio skin: `Microchip MCP4541 <http://micropython.org/resources/datasheets/MCP4541-22107B.pdf>`_ (2.7MiB PDF)
|
|
@ -1,14 +1,19 @@
|
|||
MicroPython documentation and references
|
||||
========================================
|
||||
Micro Python documentation and references
|
||||
=========================================
|
||||
|
||||
.. toctree::
|
||||
|
||||
library/index.rst
|
||||
reference/index.rst
|
||||
genrst/index.rst
|
||||
develop/index.rst
|
||||
license.rst
|
||||
pyboard/quickref.rst
|
||||
esp8266/quickref.rst
|
||||
esp32/quickref.rst
|
||||
wipy/quickref.rst
|
||||
quickref.rst
|
||||
general.rst
|
||||
tutorial/index.rst
|
||||
library/index.rst
|
||||
hardware/index.rst
|
||||
license.rst
|
||||
contents.rst
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
:mod:`_thread` -- multithreading support
|
||||
========================================
|
||||
|
||||
.. module:: _thread
|
||||
:synopsis: multithreading support
|
||||
|
||||
|see_cpython_module| :mod:`python:_thread`.
|
||||
|
||||
This module implements multithreading support.
|
||||
|
||||
This module is highly experimental and its API is not yet fully settled
|
||||
and not yet described in this documentation.
|
|
@ -1,159 +0,0 @@
|
|||
:mod:`btree` -- simple BTree database
|
||||
=====================================
|
||||
|
||||
.. module:: btree
|
||||
:synopsis: simple BTree database
|
||||
|
||||
The ``btree`` module implements a simple key-value database using external
|
||||
storage (disk files, or in general case, a random-access `stream`). Keys are
|
||||
stored sorted in the database, and besides efficient retrieval by a key
|
||||
value, a database also supports efficient ordered range scans (retrieval
|
||||
of values with the keys in a given range). On the application interface
|
||||
side, BTree database work as close a possible to a way standard `dict`
|
||||
type works, one notable difference is that both keys and values must
|
||||
be `bytes` objects (so, if you want to store objects of other types, you
|
||||
need to serialize them to `bytes` first).
|
||||
|
||||
The module is based on the well-known BerkelyDB library, version 1.xx.
|
||||
|
||||
Example::
|
||||
|
||||
import btree
|
||||
|
||||
# First, we need to open a stream which holds a database
|
||||
# This is usually a file, but can be in-memory database
|
||||
# using uio.BytesIO, a raw flash partition, etc.
|
||||
# Oftentimes, you want to create a database file if it doesn't
|
||||
# exist and open if it exists. Idiom below takes care of this.
|
||||
# DO NOT open database with "a+b" access mode.
|
||||
try:
|
||||
f = open("mydb", "r+b")
|
||||
except OSError:
|
||||
f = open("mydb", "w+b")
|
||||
|
||||
# Now open a database itself
|
||||
db = btree.open(f)
|
||||
|
||||
# The keys you add will be sorted internally in the database
|
||||
db[b"3"] = b"three"
|
||||
db[b"1"] = b"one"
|
||||
db[b"2"] = b"two"
|
||||
|
||||
# Assume that any changes are cached in memory unless
|
||||
# explicitly flushed (or database closed). Flush database
|
||||
# at the end of each "transaction".
|
||||
db.flush()
|
||||
|
||||
# Prints b'two'
|
||||
print(db[b"2"])
|
||||
|
||||
# Iterate over sorted keys in the database, starting from b"2"
|
||||
# until the end of the database, returning only values.
|
||||
# Mind that arguments passed to values() method are *key* values.
|
||||
# Prints:
|
||||
# b'two'
|
||||
# b'three'
|
||||
for word in db.values(b"2"):
|
||||
print(word)
|
||||
|
||||
del db[b"2"]
|
||||
|
||||
# No longer true, prints False
|
||||
print(b"2" in db)
|
||||
|
||||
# Prints:
|
||||
# b"1"
|
||||
# b"3"
|
||||
for key in db:
|
||||
print(key)
|
||||
|
||||
db.close()
|
||||
|
||||
# Don't forget to close the underlying stream!
|
||||
f.close()
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: open(stream, \*, flags=0, pagesize=0, cachesize=0, minkeypage=0)
|
||||
|
||||
Open a database from a random-access `stream` (like an open file). All
|
||||
other parameters are optional and keyword-only, and allow to tweak advanced
|
||||
parameters of the database operation (most users will not need them):
|
||||
|
||||
* *flags* - Currently unused.
|
||||
* *pagesize* - Page size used for the nodes in BTree. Acceptable range
|
||||
is 512-65536. If 0, a port-specific default will be used, optimized for
|
||||
port's memory usage and/or performance.
|
||||
* *cachesize* - Suggested memory cache size in bytes. For a
|
||||
board with enough memory using larger values may improve performance.
|
||||
Cache policy is as follows: entire cache is not allocated at once;
|
||||
instead, accessing a new page in database will allocate a memory buffer
|
||||
for it, until value specified by *cachesize* is reached. Then, these
|
||||
buffers will be managed using LRU (least recently used) policy. More
|
||||
buffers may still be allocated if needed (e.g., if a database contains
|
||||
big keys and/or values). Allocated cache buffers aren't reclaimed.
|
||||
* *minkeypage* - Minimum number of keys to store per page. Default value
|
||||
of 0 equivalent to 2.
|
||||
|
||||
Returns a BTree object, which implements a dictionary protocol (set
|
||||
of methods), and some additional methods described below.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: btree.close()
|
||||
|
||||
Close the database. It's mandatory to close the database at the end of
|
||||
processing, as some unwritten data may be still in the cache. Note that
|
||||
this does not close underlying stream with which the database was opened,
|
||||
it should be closed separately (which is also mandatory to make sure that
|
||||
data flushed from buffer to the underlying storage).
|
||||
|
||||
.. method:: btree.flush()
|
||||
|
||||
Flush any data in cache to the underlying stream.
|
||||
|
||||
.. method:: btree.__getitem__(key)
|
||||
btree.get(key, default=None)
|
||||
btree.__setitem__(key, val)
|
||||
btree.__detitem__(key)
|
||||
btree.__contains__(key)
|
||||
|
||||
Standard dictionary methods.
|
||||
|
||||
.. method:: btree.__iter__()
|
||||
|
||||
A BTree object can be iterated over directly (similar to a dictionary)
|
||||
to get access to all keys in order.
|
||||
|
||||
.. method:: btree.keys([start_key, [end_key, [flags]]])
|
||||
btree.values([start_key, [end_key, [flags]]])
|
||||
btree.items([start_key, [end_key, [flags]]])
|
||||
|
||||
These methods are similar to standard dictionary methods, but also can
|
||||
take optional parameters to iterate over a key sub-range, instead of
|
||||
the entire database. Note that for all 3 methods, *start_key* and
|
||||
*end_key* arguments represent key values. For example, `values()`
|
||||
method will iterate over values corresponding to they key range
|
||||
given. None values for *start_key* means "from the first key", no
|
||||
*end_key* or its value of None means "until the end of database".
|
||||
By default, range is inclusive of *start_key* and exclusive of
|
||||
*end_key*, you can include *end_key* in iteration by passing *flags*
|
||||
of `btree.INCL`. You can iterate in descending key direction
|
||||
by passing *flags* of `btree.DESC`. The flags values can be ORed
|
||||
together.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: INCL
|
||||
|
||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
||||
scanning should be inclusive of the end key.
|
||||
|
||||
.. data:: DESC
|
||||
|
||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
||||
scanning should be in descending direction of keys.
|
|
@ -1,199 +0,0 @@
|
|||
Builtin functions and exceptions
|
||||
================================
|
||||
|
||||
All builtin functions and exceptions are described here. They are also
|
||||
available via ``builtins`` module.
|
||||
|
||||
Functions and types
|
||||
-------------------
|
||||
|
||||
.. function:: abs()
|
||||
|
||||
.. function:: all()
|
||||
|
||||
.. function:: any()
|
||||
|
||||
.. function:: bin()
|
||||
|
||||
.. class:: bool()
|
||||
|
||||
.. class:: bytearray()
|
||||
|
||||
.. class:: bytes()
|
||||
|
||||
|see_cpython| `python:bytes`.
|
||||
|
||||
.. function:: callable()
|
||||
|
||||
.. function:: chr()
|
||||
|
||||
.. function:: classmethod()
|
||||
|
||||
.. function:: compile()
|
||||
|
||||
.. class:: complex()
|
||||
|
||||
.. function:: delattr(obj, name)
|
||||
|
||||
The argument *name* should be a string, and this function deletes the named
|
||||
attribute from the object given by *obj*.
|
||||
|
||||
.. class:: dict()
|
||||
|
||||
.. function:: dir()
|
||||
|
||||
.. function:: divmod()
|
||||
|
||||
.. function:: enumerate()
|
||||
|
||||
.. function:: eval()
|
||||
|
||||
.. function:: exec()
|
||||
|
||||
.. function:: filter()
|
||||
|
||||
.. class:: float()
|
||||
|
||||
.. class:: frozenset()
|
||||
|
||||
.. function:: getattr()
|
||||
|
||||
.. function:: globals()
|
||||
|
||||
.. function:: hasattr()
|
||||
|
||||
.. function:: hash()
|
||||
|
||||
.. function:: hex()
|
||||
|
||||
.. function:: id()
|
||||
|
||||
.. function:: input()
|
||||
|
||||
.. class:: int()
|
||||
|
||||
.. classmethod:: from_bytes(bytes, byteorder)
|
||||
|
||||
In MicroPython, `byteorder` parameter must be positional (this is
|
||||
compatible with CPython).
|
||||
|
||||
.. method:: to_bytes(size, byteorder)
|
||||
|
||||
In MicroPython, `byteorder` parameter must be positional (this is
|
||||
compatible with CPython).
|
||||
|
||||
.. function:: isinstance()
|
||||
|
||||
.. function:: issubclass()
|
||||
|
||||
.. function:: iter()
|
||||
|
||||
.. function:: len()
|
||||
|
||||
.. class:: list()
|
||||
|
||||
.. function:: locals()
|
||||
|
||||
.. function:: map()
|
||||
|
||||
.. function:: max()
|
||||
|
||||
.. class:: memoryview()
|
||||
|
||||
.. function:: min()
|
||||
|
||||
.. function:: next()
|
||||
|
||||
.. class:: object()
|
||||
|
||||
.. function:: oct()
|
||||
|
||||
.. function:: open()
|
||||
|
||||
.. function:: ord()
|
||||
|
||||
.. function:: pow()
|
||||
|
||||
.. function:: print()
|
||||
|
||||
.. function:: property()
|
||||
|
||||
.. function:: range()
|
||||
|
||||
.. function:: repr()
|
||||
|
||||
.. function:: reversed()
|
||||
|
||||
.. function:: round()
|
||||
|
||||
.. class:: set()
|
||||
|
||||
.. function:: setattr()
|
||||
|
||||
.. class:: slice()
|
||||
|
||||
The *slice* builtin is the type that slice objects have.
|
||||
|
||||
.. function:: sorted()
|
||||
|
||||
.. function:: staticmethod()
|
||||
|
||||
.. class:: str()
|
||||
|
||||
.. function:: sum()
|
||||
|
||||
.. function:: super()
|
||||
|
||||
.. class:: tuple()
|
||||
|
||||
.. function:: type()
|
||||
|
||||
.. function:: zip()
|
||||
|
||||
|
||||
Exceptions
|
||||
----------
|
||||
|
||||
.. exception:: AssertionError
|
||||
|
||||
.. exception:: AttributeError
|
||||
|
||||
.. exception:: Exception
|
||||
|
||||
.. exception:: ImportError
|
||||
|
||||
.. exception:: IndexError
|
||||
|
||||
.. exception:: KeyboardInterrupt
|
||||
|
||||
.. exception:: KeyError
|
||||
|
||||
.. exception:: MemoryError
|
||||
|
||||
.. exception:: NameError
|
||||
|
||||
.. exception:: NotImplementedError
|
||||
|
||||
.. exception:: OSError
|
||||
|
||||
|see_cpython| `python:OSError`. MicroPython doesn't implement ``errno``
|
||||
attribute, instead use the standard way to access exception arguments:
|
||||
``exc.args[0]``.
|
||||
|
||||
.. exception:: RuntimeError
|
||||
|
||||
.. exception:: StopIteration
|
||||
|
||||
.. exception:: SyntaxError
|
||||
|
||||
.. exception:: SystemExit
|
||||
|
||||
|see_cpython| `python:SystemExit`.
|
||||
|
||||
.. exception:: TypeError
|
||||
|
||||
|see_cpython| `python:TypeError`.
|
||||
|
||||
.. exception:: ValueError
|
||||
|
||||
.. exception:: ZeroDivisionError
|
|
@ -4,14 +4,9 @@
|
|||
.. module:: cmath
|
||||
:synopsis: mathematical functions for complex numbers
|
||||
|
||||
|see_cpython_module| :mod:`python:cmath`.
|
||||
|
||||
The ``cmath`` module provides some basic mathematical functions for
|
||||
The ``cmath`` module provides some basic mathematical funtions for
|
||||
working with complex numbers.
|
||||
|
||||
Availability: not available on WiPy and ESP8266. Floating point support
|
||||
required for this module.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
:mod:`esp` --- functions related to the ESP8266 and ESP32
|
||||
=========================================================
|
||||
|
||||
.. module:: esp
|
||||
:synopsis: functions related to the ESP8266 and ESP32
|
||||
|
||||
The ``esp`` module contains specific functions related to both the ESP8266 and
|
||||
ESP32 modules. Some functions are only available on one or the other of these
|
||||
ports.
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: sleep_type([sleep_type])
|
||||
|
||||
**Note**: ESP8266 only
|
||||
|
||||
Get or set the sleep type.
|
||||
|
||||
If the *sleep_type* parameter is provided, sets the sleep type to its
|
||||
value. If the function is called without parameters, returns the current
|
||||
sleep type.
|
||||
|
||||
The possible sleep types are defined as constants:
|
||||
|
||||
* ``SLEEP_NONE`` -- all functions enabled,
|
||||
* ``SLEEP_MODEM`` -- modem sleep, shuts down the WiFi Modem circuit.
|
||||
* ``SLEEP_LIGHT`` -- light sleep, shuts down the WiFi Modem circuit
|
||||
and suspends the processor periodically.
|
||||
|
||||
The system enters the set sleep mode automatically when possible.
|
||||
|
||||
.. function:: deepsleep(time=0)
|
||||
|
||||
**Note**: ESP8266 only - use `machine.deepsleep()` on ESP32
|
||||
|
||||
Enter deep sleep.
|
||||
|
||||
The whole module powers down, except for the RTC clock circuit, which can
|
||||
be used to restart the module after the specified time if the pin 16 is
|
||||
connected to the reset pin. Otherwise the module will sleep until manually
|
||||
reset.
|
||||
|
||||
.. function:: flash_id()
|
||||
|
||||
**Note**: ESP8266 only
|
||||
|
||||
Read the device ID of the flash memory.
|
||||
|
||||
.. function:: flash_size()
|
||||
|
||||
Read the total size of the flash memory.
|
||||
|
||||
.. function:: flash_user_start()
|
||||
|
||||
Read the memory offset at which the user flash space begins.
|
||||
|
||||
.. function:: flash_read(byte_offset, length_or_buffer)
|
||||
|
||||
.. function:: flash_write(byte_offset, bytes)
|
||||
|
||||
.. function:: flash_erase(sector_no)
|
||||
|
||||
.. function:: set_native_code_location(start, length)
|
||||
|
||||
**Note**: ESP8266 only
|
||||
|
||||
Set the location that native code will be placed for execution after it is
|
||||
compiled. Native code is emitted when the ``@micropython.native``,
|
||||
``@micropython.viper`` and ``@micropython.asm_xtensa`` decorators are applied
|
||||
to a function. The ESP8266 must execute code from either iRAM or the lower
|
||||
1MByte of flash (which is memory mapped), and this function controls the
|
||||
location.
|
||||
|
||||
If *start* and *length* are both ``None`` then the native code location is
|
||||
set to the unused portion of memory at the end of the iRAM1 region. The
|
||||
size of this unused portion depends on the firmware and is typically quite
|
||||
small (around 500 bytes), and is enough to store a few very small
|
||||
functions. The advantage of using this iRAM1 region is that it does not
|
||||
get worn out by writing to it.
|
||||
|
||||
If neither *start* nor *length* are ``None`` then they should be integers.
|
||||
*start* should specify the byte offset from the beginning of the flash at
|
||||
which native code should be stored. *length* specifies how many bytes of
|
||||
flash from *start* can be used to store native code. *start* and *length*
|
||||
should be multiples of the sector size (being 4096 bytes). The flash will
|
||||
be automatically erased before writing to it so be sure to use a region of
|
||||
flash that is not otherwise used, for example by the firmware or the
|
||||
filesystem.
|
||||
|
||||
When using the flash to store native code *start+length* must be less
|
||||
than or equal to 1MByte. Note that the flash can be worn out if repeated
|
||||
erasures (and writes) are made so use this feature sparingly.
|
||||
In particular, native code needs to be recompiled and rewritten to flash
|
||||
on each boot (including wake from deepsleep).
|
||||
|
||||
In both cases above, using iRAM1 or flash, if there is no more room left
|
||||
in the specified region then the use of a native decorator on a function
|
||||
will lead to `MemoryError` exception being raised during compilation of
|
||||
that function.
|
|
@ -1,202 +0,0 @@
|
|||
.. currentmodule:: esp32
|
||||
|
||||
:mod:`esp32` --- functionality specific to the ESP32
|
||||
====================================================
|
||||
|
||||
.. module:: esp32
|
||||
:synopsis: functionality specific to the ESP32
|
||||
|
||||
The ``esp32`` module contains functions and classes specifically aimed at
|
||||
controlling ESP32 modules.
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: wake_on_touch(wake)
|
||||
|
||||
Configure whether or not a touch will wake the device from sleep.
|
||||
*wake* should be a boolean value.
|
||||
|
||||
.. function:: wake_on_ext0(pin, level)
|
||||
|
||||
Configure how EXT0 wakes the device from sleep. *pin* can be ``None``
|
||||
or a valid Pin object. *level* should be ``esp32.WAKEUP_ALL_LOW`` or
|
||||
``esp32.WAKEUP_ANY_HIGH``.
|
||||
|
||||
.. function:: wake_on_ext1(pins, level)
|
||||
|
||||
Configure how EXT1 wakes the device from sleep. *pins* can be ``None``
|
||||
or a tuple/list of valid Pin objects. *level* should be ``esp32.WAKEUP_ALL_LOW``
|
||||
or ``esp32.WAKEUP_ANY_HIGH``.
|
||||
|
||||
.. function:: raw_temperature()
|
||||
|
||||
Read the raw value of the internal temperature sensor, returning an integer.
|
||||
|
||||
.. function:: hall_sensor()
|
||||
|
||||
Read the raw value of the internal Hall sensor, returning an integer.
|
||||
|
||||
Flash partitions
|
||||
----------------
|
||||
|
||||
This class gives access to the partitions in the device's flash memory.
|
||||
|
||||
.. class:: Partition(id)
|
||||
|
||||
Create an object representing a partition. *id* can be a string which is the label
|
||||
of the partition to retrieve, or one of the constants: ``BOOT`` or ``RUNNING``.
|
||||
|
||||
.. classmethod:: Partition.find(type=TYPE_APP, subtype=0xff, label=None)
|
||||
|
||||
Find a partition specified by *type*, *subtype* and *label*. Returns a
|
||||
(possibly empty) list of Partition objects.
|
||||
|
||||
.. method:: Partition.info()
|
||||
|
||||
Returns a 6-tuple ``(type, subtype, addr, size, label, encrypted)``.
|
||||
|
||||
.. method:: Partition.readblocks(block_num, buf)
|
||||
.. method:: Partition.readblocks(block_num, buf, offset)
|
||||
.. method:: Partition.writeblocks(block_num, buf)
|
||||
.. method:: Partition.writeblocks(block_num, buf, offset)
|
||||
.. method:: Partition.ioctl(cmd, arg)
|
||||
|
||||
These methods implement the simple and :ref:`extended
|
||||
<block-device-interface>` block protocol defined by
|
||||
:class:`uos.AbstractBlockDev`.
|
||||
|
||||
.. method:: Partition.set_boot()
|
||||
|
||||
Sets the partition as the boot partition.
|
||||
|
||||
.. method:: Partition.get_next_update()
|
||||
|
||||
Gets the next update partition after this one, and returns a new Partition object.
|
||||
|
||||
Constants
|
||||
~~~~~~~~~
|
||||
|
||||
.. data:: Partition.BOOT
|
||||
Partition.RUNNING
|
||||
|
||||
Used in the `Partition` constructor to fetch various partitions.
|
||||
|
||||
.. data:: Partition.TYPE_APP
|
||||
Partition.TYPE_DATA
|
||||
|
||||
Used in `Partition.find` to specify the partition type.
|
||||
|
||||
|
||||
.. _esp32.RMT:
|
||||
|
||||
RMT
|
||||
---
|
||||
|
||||
The RMT (Remote Control) module, specific to the ESP32, was originally designed
|
||||
to send and receive infrared remote control signals. However, due to a flexible
|
||||
design and very accurate (as low as 12.5ns) pulse generation, it can also be
|
||||
used to transmit or receive many other types of digital signals::
|
||||
|
||||
import esp32
|
||||
from machine import Pin
|
||||
|
||||
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
|
||||
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
|
||||
# The channel resolution is 100ns (1/(source_freq/clock_div)).
|
||||
r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
|
||||
|
||||
The input to the RMT module is an 80MHz clock (in the future it may be able to
|
||||
configure the input clock but, for now, it's fixed). ``clock_div`` *divides*
|
||||
the clock input which determines the resolution of the RMT channel. The
|
||||
numbers specificed in ``write_pulses`` are multiplied by the resolution to
|
||||
define the pulses.
|
||||
|
||||
``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by
|
||||
multiplying the resolution by a 15-bit (0-32,768) number. There are eight
|
||||
channels (0-7) and each can have a different clock divider.
|
||||
|
||||
So, in the example above, the 80MHz clock is divided by 8. Thus the
|
||||
resolution is (1/(80Mhz/8)) 100ns. Since the ``start`` level is 0 and toggles
|
||||
with each number, the bitstream is ``0101`` with durations of [100ns, 2000ns,
|
||||
100ns, 4000ns].
|
||||
|
||||
For more details see Espressif's `ESP-IDF RMT documentation.
|
||||
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html>`_.
|
||||
|
||||
.. Warning::
|
||||
The current MicroPython RMT implementation lacks some features, most notably
|
||||
receiving pulses and carrier transmit. RMT should be considered a
|
||||
*beta feature* and the interface may change in the future.
|
||||
|
||||
|
||||
.. class:: RMT(channel, \*, pin=None, clock_div=8)
|
||||
|
||||
This class provides access to one of the eight RMT channels. *channel* is
|
||||
required and identifies which RMT channel (0-7) will be configured. *pin*,
|
||||
also required, configures which Pin is bound to the RMT channel. *clock_div*
|
||||
is an 8-bit clock divider that divides the source clock (80MHz) to the RMT
|
||||
channel allowing the resolution to be specified.
|
||||
|
||||
.. method:: RMT.source_freq()
|
||||
|
||||
Returns the source clock frequency. Currently the source clock is not
|
||||
configurable so this will always return 80MHz.
|
||||
|
||||
.. method:: RMT.clock_div()
|
||||
|
||||
Return the clock divider. Note that the channel resolution is
|
||||
``1 / (source_freq / clock_div)``.
|
||||
|
||||
.. method:: RMT.wait_done(timeout=0)
|
||||
|
||||
Returns True if `RMT.write_pulses` has completed.
|
||||
|
||||
If *timeout* (defined in ticks of ``source_freq / clock_div``) is specified
|
||||
the method will wait for *timeout* or until `RMT.write_pulses` is complete,
|
||||
returning ``False`` if the channel continues to transmit.
|
||||
|
||||
.. Warning::
|
||||
Avoid using ``wait_done()`` if looping is enabled.
|
||||
|
||||
.. method:: RMT.loop(enable_loop)
|
||||
|
||||
Configure looping on the channel, allowing a stream of pulses to be
|
||||
indefinitely repeated. *enable_loop* is bool, set to True to enable looping.
|
||||
|
||||
.. method:: RMT.write_pulses(pulses, start)
|
||||
|
||||
Begin sending *pulses*, a list or tuple defining the stream of pulses. The
|
||||
length of each pulse is defined by a number to be multiplied by the channel
|
||||
resolution ``(1 / (source_freq / clock_div))``. *start* defines whether the
|
||||
stream starts at 0 or 1.
|
||||
|
||||
|
||||
The Ultra-Low-Power co-processor
|
||||
--------------------------------
|
||||
|
||||
.. class:: ULP()
|
||||
|
||||
This class provides access to the Ultra-Low-Power co-processor.
|
||||
|
||||
.. method:: ULP.set_wakeup_period(period_index, period_us)
|
||||
|
||||
Set the wake-up period.
|
||||
|
||||
.. method:: ULP.load_binary(load_addr, program_binary)
|
||||
|
||||
Load a *program_binary* into the ULP at the given *load_addr*.
|
||||
|
||||
.. method:: ULP.run(entry_point)
|
||||
|
||||
Start the ULP running at the given *entry_point*.
|
||||
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: esp32.WAKEUP_ALL_LOW
|
||||
esp32.WAKEUP_ANY_HIGH
|
||||
|
||||
Selects the wake level for pins.
|
|
@ -1,161 +0,0 @@
|
|||
:mod:`framebuf` --- Frame buffer manipulation
|
||||
=============================================
|
||||
|
||||
.. module:: framebuf
|
||||
:synopsis: Frame buffer manipulation
|
||||
|
||||
This module provides a general frame buffer which can be used to create
|
||||
bitmap images, which can then be sent to a display.
|
||||
|
||||
class FrameBuffer
|
||||
-----------------
|
||||
|
||||
The FrameBuffer class provides a pixel buffer which can be drawn upon with
|
||||
pixels, lines, rectangles, text and even other FrameBuffer's. It is useful
|
||||
when generating output for displays.
|
||||
|
||||
For example::
|
||||
|
||||
import framebuf
|
||||
|
||||
# FrameBuffer needs 2 bytes for every RGB565 pixel
|
||||
fbuf = framebuf.FrameBuffer(bytearray(10 * 100 * 2), 10, 100, framebuf.RGB565)
|
||||
|
||||
fbuf.fill(0)
|
||||
fbuf.text('MicroPython!', 0, 0, 0xffff)
|
||||
fbuf.hline(0, 10, 96, 0xffff)
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: FrameBuffer(buffer, width, height, format, stride=width)
|
||||
|
||||
Construct a FrameBuffer object. The parameters are:
|
||||
|
||||
- *buffer* is an object with a buffer protocol which must be large
|
||||
enough to contain every pixel defined by the width, height and
|
||||
format of the FrameBuffer.
|
||||
- *width* is the width of the FrameBuffer in pixels
|
||||
- *height* is the height of the FrameBuffer in pixels
|
||||
- *format* specifies the type of pixel used in the FrameBuffer;
|
||||
permissible values are listed under Constants below. These set the
|
||||
number of bits used to encode a color value and the layout of these
|
||||
bits in *buffer*.
|
||||
Where a color value c is passed to a method, c is a small integer
|
||||
with an encoding that is dependent on the format of the FrameBuffer.
|
||||
- *stride* is the number of pixels between each horizontal line
|
||||
of pixels in the FrameBuffer. This defaults to *width* but may
|
||||
need adjustments when implementing a FrameBuffer within another
|
||||
larger FrameBuffer or screen. The *buffer* size must accommodate
|
||||
an increased step size.
|
||||
|
||||
One must specify valid *buffer*, *width*, *height*, *format* and
|
||||
optionally *stride*. Invalid *buffer* size or dimensions may lead to
|
||||
unexpected errors.
|
||||
|
||||
Drawing primitive shapes
|
||||
------------------------
|
||||
|
||||
The following methods draw shapes onto the FrameBuffer.
|
||||
|
||||
.. method:: FrameBuffer.fill(c)
|
||||
|
||||
Fill the entire FrameBuffer with the specified color.
|
||||
|
||||
.. method:: FrameBuffer.pixel(x, y[, c])
|
||||
|
||||
If *c* is not given, get the color value of the specified pixel.
|
||||
If *c* is given, set the specified pixel to the given color.
|
||||
|
||||
.. method:: FrameBuffer.hline(x, y, w, c)
|
||||
.. method:: FrameBuffer.vline(x, y, h, c)
|
||||
.. method:: FrameBuffer.line(x1, y1, x2, y2, c)
|
||||
|
||||
Draw a line from a set of coordinates using the given color and
|
||||
a thickness of 1 pixel. The `line` method draws the line up to
|
||||
a second set of coordinates whereas the `hline` and `vline`
|
||||
methods draw horizontal and vertical lines respectively up to
|
||||
a given length.
|
||||
|
||||
.. method:: FrameBuffer.rect(x, y, w, h, c)
|
||||
.. method:: FrameBuffer.fill_rect(x, y, w, h, c)
|
||||
|
||||
Draw a rectangle at the given location, size and color. The `rect`
|
||||
method draws only a 1 pixel outline whereas the `fill_rect` method
|
||||
draws both the outline and interior.
|
||||
|
||||
Drawing text
|
||||
------------
|
||||
|
||||
.. method:: FrameBuffer.text(s, x, y[, c])
|
||||
|
||||
Write text to the FrameBuffer using the the coordinates as the upper-left
|
||||
corner of the text. The color of the text can be defined by the optional
|
||||
argument but is otherwise a default value of 1. All characters have
|
||||
dimensions of 8x8 pixels and there is currently no way to change the font.
|
||||
|
||||
|
||||
Other methods
|
||||
-------------
|
||||
|
||||
.. method:: FrameBuffer.scroll(xstep, ystep)
|
||||
|
||||
Shift the contents of the FrameBuffer by the given vector. This may
|
||||
leave a footprint of the previous colors in the FrameBuffer.
|
||||
|
||||
.. method:: FrameBuffer.blit(fbuf, x, y[, key])
|
||||
|
||||
Draw another FrameBuffer on top of the current one at the given coordinates.
|
||||
If *key* is specified then it should be a color integer and the
|
||||
corresponding color will be considered transparent: all pixels with that
|
||||
color value will not be drawn.
|
||||
|
||||
This method works between FrameBuffer instances utilising different formats,
|
||||
but the resulting colors may be unexpected due to the mismatch in color
|
||||
formats.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: framebuf.MONO_VLSB
|
||||
|
||||
Monochrome (1-bit) color format
|
||||
This defines a mapping where the bits in a byte are vertically mapped with
|
||||
bit 0 being nearest the top of the screen. Consequently each byte occupies
|
||||
8 vertical pixels. Subsequent bytes appear at successive horizontal
|
||||
locations until the rightmost edge is reached. Further bytes are rendered
|
||||
at locations starting at the leftmost edge, 8 pixels lower.
|
||||
|
||||
.. data:: framebuf.MONO_HLSB
|
||||
|
||||
Monochrome (1-bit) color format
|
||||
This defines a mapping where the bits in a byte are horizontally mapped.
|
||||
Each byte occupies 8 horizontal pixels with bit 0 being the leftmost.
|
||||
Subsequent bytes appear at successive horizontal locations until the
|
||||
rightmost edge is reached. Further bytes are rendered on the next row, one
|
||||
pixel lower.
|
||||
|
||||
.. data:: framebuf.MONO_HMSB
|
||||
|
||||
Monochrome (1-bit) color format
|
||||
This defines a mapping where the bits in a byte are horizontally mapped.
|
||||
Each byte occupies 8 horizontal pixels with bit 7 being the leftmost.
|
||||
Subsequent bytes appear at successive horizontal locations until the
|
||||
rightmost edge is reached. Further bytes are rendered on the next row, one
|
||||
pixel lower.
|
||||
|
||||
.. data:: framebuf.RGB565
|
||||
|
||||
Red Green Blue (16-bit, 5+6+5) color format
|
||||
|
||||
.. data:: framebuf.GS2_HMSB
|
||||
|
||||
Grayscale (2-bit) color format
|
||||
|
||||
.. data:: framebuf.GS4_HMSB
|
||||
|
||||
Grayscale (4-bit) color format
|
||||
|
||||
.. data:: framebuf.GS8
|
||||
|
||||
Grayscale (8-bit) color format
|
|
@ -4,8 +4,6 @@
|
|||
.. module:: gc
|
||||
:synopsis: control the garbage collector
|
||||
|
||||
|see_cpython_module| :mod:`python:gc`.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
|
@ -26,41 +24,6 @@ Functions
|
|||
|
||||
Return the number of bytes of heap RAM that are allocated.
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
This function is MicroPython extension.
|
||||
|
||||
.. function:: mem_free()
|
||||
|
||||
Return the number of bytes of available heap RAM, or -1 if this amount
|
||||
is not known.
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
This function is MicroPython extension.
|
||||
|
||||
.. function:: threshold([amount])
|
||||
|
||||
Set or query the additional GC allocation threshold. Normally, a collection
|
||||
is triggered only when a new allocation cannot be satisfied, i.e. on an
|
||||
out-of-memory (OOM) condition. If this function is called, in addition to
|
||||
OOM, a collection will be triggered each time after *amount* bytes have been
|
||||
allocated (in total, since the previous time such an amount of bytes
|
||||
have been allocated). *amount* is usually specified as less than the
|
||||
full heap size, with the intention to trigger a collection earlier than when the
|
||||
heap becomes exhausted, and in the hope that an early collection will prevent
|
||||
excessive memory fragmentation. This is a heuristic measure, the effect
|
||||
of which will vary from application to application, as well as
|
||||
the optimal value of the *amount* parameter.
|
||||
|
||||
Calling the function without argument will return the current value of
|
||||
the threshold. A value of -1 means a disabled allocation threshold.
|
||||
|
||||
.. admonition:: Difference to CPython
|
||||
:class: attention
|
||||
|
||||
This function is a MicroPython extension. CPython has a similar
|
||||
function - ``set_threshold()``, but due to different GC
|
||||
implementations, its signature and semantics are different.
|
||||
Return the number of bytes of available heap RAM.
|
||||
|
|
|
@ -1,133 +1,50 @@
|
|||
.. _micropython_lib:
|
||||
Micro Python libraries
|
||||
======================
|
||||
|
||||
MicroPython libraries
|
||||
=====================
|
||||
Python standard libraries
|
||||
-------------------------
|
||||
|
||||
.. warning::
|
||||
The following standard Python libraries are built in to Micro Python.
|
||||
|
||||
Important summary of this section
|
||||
For additional libraries, please download them from the `micropython-lib repository
|
||||
<https://github.com/micropython/micropython-lib>`_.
|
||||
|
||||
* MicroPython implements a subset of Python functionality for each module.
|
||||
* To ease extensibility, MicroPython versions of standard Python modules
|
||||
usually have ``u`` ("micro") prefix.
|
||||
* Any particular MicroPython variant or port may miss any feature/function
|
||||
described in this general documentation (due to resource constraints or
|
||||
other limitations).
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
cmath.rst
|
||||
gc.rst
|
||||
math.rst
|
||||
os.rst
|
||||
select.rst
|
||||
struct.rst
|
||||
sys.rst
|
||||
time.rst
|
||||
|
||||
This chapter describes modules (function and class libraries) which are built
|
||||
into MicroPython. There are a few categories of such modules:
|
||||
|
||||
* Modules which implement a subset of standard Python functionality and are not
|
||||
intended to be extended by the user.
|
||||
* Modules which implement a subset of Python functionality, with a provision
|
||||
for extension by the user (via Python code).
|
||||
* Modules which implement MicroPython extensions to the Python standard libraries.
|
||||
* Modules specific to a particular `MicroPython port` and thus not portable.
|
||||
|
||||
Note about the availability of the modules and their contents: This documentation
|
||||
in general aspires to describe all modules and functions/classes which are
|
||||
implemented in MicroPython project. However, MicroPython is highly configurable, and
|
||||
each port to a particular board/embedded system makes available only a subset
|
||||
of MicroPython libraries. For officially supported ports, there is an effort
|
||||
to either filter out non-applicable items, or mark individual descriptions
|
||||
with "Availability:" clauses describing which ports provide a given feature.
|
||||
|
||||
With that in mind, please still be warned that some functions/classes
|
||||
in a module (or even the entire module) described in this documentation **may be
|
||||
unavailable** in a particular build of MicroPython on a particular system. The
|
||||
best place to find general information of the availability/non-availability
|
||||
of a particular feature is the "General Information" section which contains
|
||||
information pertaining to a specific `MicroPython port`.
|
||||
|
||||
On some ports you are able to discover the available, built-in libraries that
|
||||
can be imported by entering the following at the REPL::
|
||||
|
||||
help('modules')
|
||||
|
||||
Beyond the built-in libraries described in this documentation, many more
|
||||
modules from the Python standard library, as well as further MicroPython
|
||||
extensions to it, can be found in `micropython-lib`.
|
||||
|
||||
Python standard libraries and micro-libraries
|
||||
---------------------------------------------
|
||||
Python micro-libraries
|
||||
----------------------
|
||||
|
||||
The following standard Python libraries have been "micro-ified" to fit in with
|
||||
the philosophy of MicroPython. They provide the core functionality of that
|
||||
the philosophy of Micro Python. They provide the core functionality of that
|
||||
module and are intended to be a drop-in replacement for the standard Python
|
||||
library. Some modules below use a standard Python name, but prefixed with "u",
|
||||
e.g. ``ujson`` instead of ``json``. This is to signify that such a module is
|
||||
micro-library, i.e. implements only a subset of CPython module functionality.
|
||||
By naming them differently, a user has a choice to write a Python-level module
|
||||
to extend functionality for better compatibility with CPython (indeed, this is
|
||||
what done by the `micropython-lib` project mentioned above).
|
||||
library.
|
||||
|
||||
On some embedded platforms, where it may be cumbersome to add Python-level
|
||||
wrapper modules to achieve naming compatibility with CPython, micro-modules
|
||||
are available both by their u-name, and also by their non-u-name. The
|
||||
non-u-name can be overridden by a file of that name in your library path (``sys.path``).
|
||||
For example, ``import json`` will first search for a file ``json.py`` (or package
|
||||
directory ``json``) and load that module if it is found. If nothing is found,
|
||||
The modules are available by their u-name, and also by their non-u-name. The
|
||||
non-u-name can be overridden by a file of that name in your package path.
|
||||
For example, ``import json`` will first search for a file ``json.py`` or
|
||||
directory ``json`` and load that package if it is found. If nothing is found,
|
||||
it will fallback to loading the built-in ``ujson`` module.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
builtins.rst
|
||||
cmath.rst
|
||||
gc.rst
|
||||
math.rst
|
||||
sys.rst
|
||||
uarray.rst
|
||||
ubinascii.rst
|
||||
ucollections.rst
|
||||
uerrno.rst
|
||||
uhashlib.rst
|
||||
uheapq.rst
|
||||
uio.rst
|
||||
ujson.rst
|
||||
uos.rst
|
||||
ure.rst
|
||||
uselect.rst
|
||||
usocket.rst
|
||||
ussl.rst
|
||||
ustruct.rst
|
||||
utime.rst
|
||||
uzlib.rst
|
||||
_thread.rst
|
||||
|
||||
|
||||
MicroPython-specific libraries
|
||||
------------------------------
|
||||
|
||||
Functionality specific to the MicroPython implementation is available in
|
||||
the following libraries.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
btree.rst
|
||||
framebuf.rst
|
||||
machine.rst
|
||||
micropython.rst
|
||||
network.rst
|
||||
ubluetooth.rst
|
||||
ucryptolib.rst
|
||||
uctypes.rst
|
||||
|
||||
|
||||
Port-specific libraries
|
||||
-----------------------
|
||||
|
||||
In some cases the following port/board-specific libraries have functions or
|
||||
classes similar to those in the :mod:`machine` library. Where this occurs, the
|
||||
entry in the port specific library exposes hardware functionality unique to
|
||||
that platform.
|
||||
|
||||
To write portable code use functions and classes from the :mod:`machine` module.
|
||||
To access platform-specific hardware use the appropriate library, e.g.
|
||||
:mod:`pyb` in the case of the Pyboard.
|
||||
|
||||
|
||||
Libraries specific to the pyboard
|
||||
---------------------------------
|
||||
|
@ -135,32 +52,7 @@ Libraries specific to the pyboard
|
|||
The following libraries are specific to the pyboard.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 2
|
||||
|
||||
pyb.rst
|
||||
lcd160cr.rst
|
||||
|
||||
|
||||
Libraries specific to the WiPy
|
||||
------------------------------
|
||||
|
||||
The following libraries and classes are specific to the WiPy.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
wipy.rst
|
||||
machine.ADCWiPy.rst
|
||||
machine.TimerWiPy.rst
|
||||
|
||||
|
||||
Libraries specific to the ESP8266 and ESP32
|
||||
-------------------------------------------
|
||||
|
||||
The following libraries are specific to the ESP8266 and ESP32.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
esp.rst
|
||||
esp32.rst
|
||||
pyb.rst
|
||||
network.rst
|
||||
|
|
|
@ -1,394 +0,0 @@
|
|||
:mod:`lcd160cr` --- control of LCD160CR display
|
||||
===============================================
|
||||
|
||||
.. module:: lcd160cr
|
||||
:synopsis: control of LCD160CR display
|
||||
|
||||
This module provides control of the MicroPython LCD160CR display.
|
||||
|
||||
.. image:: http://micropython.org/resources/LCD160CRv10-persp.jpg
|
||||
:alt: LCD160CRv1.0 picture
|
||||
:width: 640px
|
||||
|
||||
Further resources are available via the following links:
|
||||
|
||||
* `LCD160CRv1.0 reference manual <http://micropython.org/resources/LCD160CRv10-refmanual.pdf>`_ (100KiB PDF)
|
||||
* `LCD160CRv1.0 schematics <http://micropython.org/resources/LCD160CRv10-schematics.pdf>`_ (1.6MiB PDF)
|
||||
|
||||
class LCD160CR
|
||||
--------------
|
||||
|
||||
The LCD160CR class provides an interface to the display. Create an
|
||||
instance of this class and use its methods to draw to the LCD and get
|
||||
the status of the touch panel.
|
||||
|
||||
For example::
|
||||
|
||||
import lcd160cr
|
||||
|
||||
lcd = lcd160cr.LCD160CR('X')
|
||||
lcd.set_orient(lcd160cr.PORTRAIT)
|
||||
lcd.set_pos(0, 0)
|
||||
lcd.set_text_color(lcd.rgb(255, 0, 0), lcd.rgb(0, 0, 0))
|
||||
lcd.set_font(1)
|
||||
lcd.write('Hello MicroPython!')
|
||||
print('touch:', lcd.get_touch())
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: LCD160CR(connect=None, \*, pwr=None, i2c=None, spi=None, i2c_addr=98)
|
||||
|
||||
Construct an LCD160CR object. The parameters are:
|
||||
|
||||
- *connect* is a string specifying the physical connection of the LCD
|
||||
display to the board; valid values are "X", "Y", "XY", "YX".
|
||||
Use "X" when the display is connected to a pyboard in the X-skin
|
||||
position, and "Y" when connected in the Y-skin position. "XY"
|
||||
and "YX" are used when the display is connected to the right or
|
||||
left side of the pyboard, respectively.
|
||||
- *pwr* is a Pin object connected to the LCD's power/enabled pin.
|
||||
- *i2c* is an I2C object connected to the LCD's I2C interface.
|
||||
- *spi* is an SPI object connected to the LCD's SPI interface.
|
||||
- *i2c_addr* is the I2C address of the display.
|
||||
|
||||
One must specify either a valid *connect* or all of *pwr*, *i2c* and *spi*.
|
||||
If a valid *connect* is given then any of *pwr*, *i2c* or *spi* which are
|
||||
not passed as parameters (i.e. they are ``None``) will be created based on the
|
||||
value of *connect*. This allows to override the default interface to the
|
||||
display if needed.
|
||||
|
||||
The default values are:
|
||||
|
||||
- "X" is for the X-skin and uses:
|
||||
``pwr=Pin("X4")``, ``i2c=I2C("X")``, ``spi=SPI("X")``
|
||||
- "Y" is for the Y-skin and uses:
|
||||
``pwr=Pin("Y4")``, ``i2c=I2C("Y")``, ``spi=SPI("Y")``
|
||||
- "XY" is for the right-side and uses:
|
||||
``pwr=Pin("X4")``, ``i2c=I2C("Y")``, ``spi=SPI("X")``
|
||||
- "YX" is for the left-side and uses:
|
||||
``pwr=Pin("Y4")``, ``i2c=I2C("X")``, ``spi=SPI("Y")``
|
||||
|
||||
See `this image <http://micropython.org/resources/LCD160CRv10-positions.jpg>`_
|
||||
for how the display can be connected to the pyboard.
|
||||
|
||||
Static methods
|
||||
--------------
|
||||
|
||||
.. staticmethod:: LCD160CR.rgb(r, g, b)
|
||||
|
||||
Return a 16-bit integer representing the given rgb color values. The
|
||||
16-bit value can be used to set the font color (see
|
||||
:meth:`LCD160CR.set_text_color`) pen color (see :meth:`LCD160CR.set_pen`)
|
||||
and draw individual pixels.
|
||||
|
||||
.. staticmethod:: LCD160CR.clip_line(data, w, h):
|
||||
|
||||
Clip the given line data. This is for internal use.
|
||||
|
||||
Instance members
|
||||
----------------
|
||||
|
||||
The following instance members are publicly accessible.
|
||||
|
||||
.. data:: LCD160CR.w
|
||||
.. data:: LCD160CR.h
|
||||
|
||||
The width and height of the display, respectively, in pixels. These
|
||||
members are updated when calling :meth:`LCD160CR.set_orient` and should
|
||||
be considered read-only.
|
||||
|
||||
Setup commands
|
||||
--------------
|
||||
|
||||
.. method:: LCD160CR.set_power(on)
|
||||
|
||||
Turn the display on or off, depending on the given value of *on*: 0 or ``False``
|
||||
will turn the display off, and 1 or ``True`` will turn it on.
|
||||
|
||||
.. method:: LCD160CR.set_orient(orient)
|
||||
|
||||
Set the orientation of the display. The *orient* parameter can be one
|
||||
of `PORTRAIT`, `LANDSCAPE`, `PORTRAIT_UPSIDEDOWN`, `LANDSCAPE_UPSIDEDOWN`.
|
||||
|
||||
.. method:: LCD160CR.set_brightness(value)
|
||||
|
||||
Set the brightness of the display, between 0 and 31.
|
||||
|
||||
.. method:: LCD160CR.set_i2c_addr(addr)
|
||||
|
||||
Set the I2C address of the display. The *addr* value must have the
|
||||
lower 2 bits cleared.
|
||||
|
||||
.. method:: LCD160CR.set_uart_baudrate(baudrate)
|
||||
|
||||
Set the baudrate of the UART interface.
|
||||
|
||||
.. method:: LCD160CR.set_startup_deco(value)
|
||||
|
||||
Set the start-up decoration of the display. The *value* parameter can be a
|
||||
logical or of `STARTUP_DECO_NONE`, `STARTUP_DECO_MLOGO`, `STARTUP_DECO_INFO`.
|
||||
|
||||
.. method:: LCD160CR.save_to_flash()
|
||||
|
||||
Save the following parameters to flash so they persist on restart and power up:
|
||||
initial decoration, orientation, brightness, UART baud rate, I2C address.
|
||||
|
||||
Pixel access methods
|
||||
--------------------
|
||||
|
||||
The following methods manipulate individual pixels on the display.
|
||||
|
||||
.. method:: LCD160CR.set_pixel(x, y, c)
|
||||
|
||||
Set the specified pixel to the given color. The color should be a 16-bit
|
||||
integer and can be created by :meth:`LCD160CR.rgb`.
|
||||
|
||||
.. method:: LCD160CR.get_pixel(x, y)
|
||||
|
||||
Get the 16-bit value of the specified pixel.
|
||||
|
||||
.. method:: LCD160CR.get_line(x, y, buf)
|
||||
|
||||
Low-level method to get a line of pixels into the given buffer.
|
||||
To read *n* pixels *buf* should be *2*n+1* bytes in length. The first byte
|
||||
is a dummy byte and should be ignored, and subsequent bytes represent the
|
||||
pixels in the line starting at coordinate *(x, y)*.
|
||||
|
||||
.. method:: LCD160CR.screen_dump(buf, x=0, y=0, w=None, h=None)
|
||||
|
||||
Dump the contents of the screen to the given buffer. The parameters *x* and *y*
|
||||
specify the starting coordinate, and *w* and *h* the size of the region. If *w*
|
||||
or *h* are ``None`` then they will take on their maximum values, set by the size
|
||||
of the screen minus the given *x* and *y* values. *buf* should be large enough
|
||||
to hold ``2*w*h`` bytes. If it's smaller then only the initial horizontal lines
|
||||
will be stored.
|
||||
|
||||
.. method:: LCD160CR.screen_load(buf)
|
||||
|
||||
Load the entire screen from the given buffer.
|
||||
|
||||
Drawing text
|
||||
------------
|
||||
|
||||
To draw text one sets the position, color and font, and then uses
|
||||
`LCD160CR.write` to draw the text.
|
||||
|
||||
.. method:: LCD160CR.set_pos(x, y)
|
||||
|
||||
Set the position for text output using :meth:`LCD160CR.write`. The position
|
||||
is the upper-left corner of the text.
|
||||
|
||||
.. method:: LCD160CR.set_text_color(fg, bg)
|
||||
|
||||
Set the foreground and background color of the text.
|
||||
|
||||
.. method:: LCD160CR.set_font(font, scale=0, bold=0, trans=0, scroll=0)
|
||||
|
||||
Set the font for the text. Subsequent calls to `write` will use the newly
|
||||
configured font. The parameters are:
|
||||
|
||||
- *font* is the font family to use, valid values are 0, 1, 2, 3.
|
||||
- *scale* is a scaling value for each character pixel, where the pixels
|
||||
are drawn as a square with side length equal to *scale + 1*. The value
|
||||
can be between 0 and 63.
|
||||
- *bold* controls the number of pixels to overdraw each character pixel,
|
||||
making a bold effect. The lower 2 bits of *bold* are the number of
|
||||
pixels to overdraw in the horizontal direction, and the next 2 bits are
|
||||
for the vertical direction. For example, a *bold* value of 5 will
|
||||
overdraw 1 pixel in both the horizontal and vertical directions.
|
||||
- *trans* can be either 0 or 1 and if set to 1 the characters will be
|
||||
drawn with a transparent background.
|
||||
- *scroll* can be either 0 or 1 and if set to 1 the display will do a
|
||||
soft scroll if the text moves to the next line.
|
||||
|
||||
.. method:: LCD160CR.write(s)
|
||||
|
||||
Write text to the display, using the current position, color and font.
|
||||
As text is written the position is automatically incremented. The
|
||||
display supports basic VT100 control codes such as newline and backspace.
|
||||
|
||||
Drawing primitive shapes
|
||||
------------------------
|
||||
|
||||
Primitive drawing commands use a foreground and background color set by the
|
||||
`set_pen` method.
|
||||
|
||||
.. method:: LCD160CR.set_pen(line, fill)
|
||||
|
||||
Set the line and fill color for primitive shapes.
|
||||
|
||||
.. method:: LCD160CR.erase()
|
||||
|
||||
Erase the entire display to the pen fill color.
|
||||
|
||||
.. method:: LCD160CR.dot(x, y)
|
||||
|
||||
Draw a single pixel at the given location using the pen line color.
|
||||
|
||||
.. method:: LCD160CR.rect(x, y, w, h)
|
||||
.. method:: LCD160CR.rect_outline(x, y, w, h)
|
||||
.. method:: LCD160CR.rect_interior(x, y, w, h)
|
||||
|
||||
Draw a rectangle at the given location and size using the pen line
|
||||
color for the outline, and the pen fill color for the interior.
|
||||
The `rect` method draws the outline and interior, while the other methods
|
||||
just draw one or the other.
|
||||
|
||||
.. method:: LCD160CR.line(x1, y1, x2, y2)
|
||||
|
||||
Draw a line between the given coordinates using the pen line color.
|
||||
|
||||
.. method:: LCD160CR.dot_no_clip(x, y)
|
||||
.. method:: LCD160CR.rect_no_clip(x, y, w, h)
|
||||
.. method:: LCD160CR.rect_outline_no_clip(x, y, w, h)
|
||||
.. method:: LCD160CR.rect_interior_no_clip(x, y, w, h)
|
||||
.. method:: LCD160CR.line_no_clip(x1, y1, x2, y2)
|
||||
|
||||
These methods are as above but don't do any clipping on the input
|
||||
coordinates. They are faster than the clipping versions and can be
|
||||
used when you know that the coordinates are within the display.
|
||||
|
||||
.. method:: LCD160CR.poly_dot(data)
|
||||
|
||||
Draw a sequence of dots using the pen line color.
|
||||
The *data* should be a buffer of bytes, with each successive pair of
|
||||
bytes corresponding to coordinate pairs (x, y).
|
||||
|
||||
.. method:: LCD160CR.poly_line(data)
|
||||
|
||||
Similar to :meth:`LCD160CR.poly_dot` but draws lines between the dots.
|
||||
|
||||
Touch screen methods
|
||||
--------------------
|
||||
|
||||
.. method:: LCD160CR.touch_config(calib=False, save=False, irq=None)
|
||||
|
||||
Configure the touch panel:
|
||||
|
||||
- If *calib* is ``True`` then the call will trigger a touch calibration of
|
||||
the resistive touch sensor. This requires the user to touch various
|
||||
parts of the screen.
|
||||
- If *save* is ``True`` then the touch parameters will be saved to NVRAM
|
||||
to persist across reset/power up.
|
||||
- If *irq* is ``True`` then the display will be configured to pull the IRQ
|
||||
line low when a touch force is detected. If *irq* is ``False`` then this
|
||||
feature is disabled. If *irq* is ``None`` (the default value) then no
|
||||
change is made to this setting.
|
||||
|
||||
.. method:: LCD160CR.is_touched()
|
||||
|
||||
Returns a boolean: ``True`` if there is currently a touch force on the screen,
|
||||
``False`` otherwise.
|
||||
|
||||
.. method:: LCD160CR.get_touch()
|
||||
|
||||
Returns a 3-tuple of: *(active, x, y)*. If there is currently a touch force
|
||||
on the screen then *active* is 1, otherwise it is 0. The *x* and *y* values
|
||||
indicate the position of the current or most recent touch.
|
||||
|
||||
Advanced commands
|
||||
-----------------
|
||||
|
||||
.. method:: LCD160CR.set_spi_win(x, y, w, h)
|
||||
|
||||
Set the window that SPI data is written to.
|
||||
|
||||
.. method:: LCD160CR.fast_spi(flush=True)
|
||||
|
||||
Ready the display to accept RGB pixel data on the SPI bus, resetting the location
|
||||
of the first byte to go to the top-left corner of the window set by
|
||||
:meth:`LCD160CR.set_spi_win`.
|
||||
The method returns an SPI object which can be used to write the pixel data.
|
||||
|
||||
Pixels should be sent as 16-bit RGB values in the 5-6-5 format. The destination
|
||||
counter will increase as data is sent, and data can be sent in arbitrary sized
|
||||
chunks. Once the destination counter reaches the end of the window specified by
|
||||
:meth:`LCD160CR.set_spi_win` it will wrap around to the top-left corner of that window.
|
||||
|
||||
.. method:: LCD160CR.show_framebuf(buf)
|
||||
|
||||
Show the given buffer on the display. *buf* should be an array of bytes containing
|
||||
the 16-bit RGB values for the pixels, and they will be written to the area
|
||||
specified by :meth:`LCD160CR.set_spi_win`, starting from the top-left corner.
|
||||
|
||||
The `framebuf <framebuf.html>`_ module can be used to construct frame buffers
|
||||
and provides drawing primitives. Using a frame buffer will improve
|
||||
performance of animations when compared to drawing directly to the screen.
|
||||
|
||||
.. method:: LCD160CR.set_scroll(on)
|
||||
|
||||
Turn scrolling on or off. This controls globally whether any window regions will
|
||||
scroll.
|
||||
|
||||
.. method:: LCD160CR.set_scroll_win(win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0)
|
||||
|
||||
Configure a window region for scrolling:
|
||||
|
||||
- *win* is the window id to configure. There are 0..7 standard windows for
|
||||
general purpose use. Window 8 is the text scroll window (the ticker).
|
||||
- *x*, *y*, *w*, *h* specify the location of the window in the display.
|
||||
- *vec* specifies the direction and speed of scroll: it is a 16-bit value
|
||||
of the form ``0bF.ddSSSSSSSSSSSS``. *dd* is 0, 1, 2, 3 for +x, +y, -x,
|
||||
-y scrolling. *F* sets the speed format, with 0 meaning that the window
|
||||
is shifted *S % 256* pixel every frame, and 1 meaning that the window
|
||||
is shifted 1 pixel every *S* frames.
|
||||
- *pat* is a 16-bit pattern mask for the background.
|
||||
- *fill* is the fill color.
|
||||
- *color* is the extra color, either of the text or pattern foreground.
|
||||
|
||||
.. method:: LCD160CR.set_scroll_win_param(win, param, value)
|
||||
|
||||
Set a single parameter of a scrolling window region:
|
||||
|
||||
- *win* is the window id, 0..8.
|
||||
- *param* is the parameter number to configure, 0..7, and corresponds
|
||||
to the parameters in the `set_scroll_win` method.
|
||||
- *value* is the value to set.
|
||||
|
||||
.. method:: LCD160CR.set_scroll_buf(s)
|
||||
|
||||
Set the string for scrolling in window 8. The parameter *s* must be a string
|
||||
with length 32 or less.
|
||||
|
||||
.. method:: LCD160CR.jpeg(buf)
|
||||
|
||||
Display a JPEG. *buf* should contain the entire JPEG data. JPEG data should
|
||||
not include EXIF information. The following encodings are supported: Baseline
|
||||
DCT, Huffman coding, 8 bits per sample, 3 color components, YCbCr4:2:2.
|
||||
The origin of the JPEG is set by :meth:`LCD160CR.set_pos`.
|
||||
|
||||
.. method:: LCD160CR.jpeg_start(total_len)
|
||||
.. method:: LCD160CR.jpeg_data(buf)
|
||||
|
||||
Display a JPEG with the data split across multiple buffers. There must be
|
||||
a single call to `jpeg_start` to begin with, specifying the total number of
|
||||
bytes in the JPEG. Then this number of bytes must be transferred to the
|
||||
display using one or more calls to the `jpeg_data` command.
|
||||
|
||||
.. method:: LCD160CR.feed_wdt()
|
||||
|
||||
The first call to this method will start the display's internal watchdog
|
||||
timer. Subsequent calls will feed the watchdog. The timeout is roughly 30
|
||||
seconds.
|
||||
|
||||
.. method:: LCD160CR.reset()
|
||||
|
||||
Reset the display.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: lcd160cr.PORTRAIT
|
||||
lcd160cr.LANDSCAPE
|
||||
lcd160cr.PORTRAIT_UPSIDEDOWN
|
||||
lcd160cr.LANDSCAPE_UPSIDEDOWN
|
||||
|
||||
Orientations of the display, used by :meth:`LCD160CR.set_orient`.
|
||||
|
||||
.. data:: lcd160cr.STARTUP_DECO_NONE
|
||||
lcd160cr.STARTUP_DECO_MLOGO
|
||||
lcd160cr.STARTUP_DECO_INFO
|
||||
|
||||
Types of start-up decoration, can be OR'ed together, used by
|
||||
:meth:`LCD160CR.set_startup_deco`.
|
|
@ -1,35 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.ADC:
|
||||
|
||||
class ADC -- analog to digital conversion
|
||||
=========================================
|
||||
|
||||
The ADC class provides an interface to analog-to-digital convertors, and
|
||||
represents a single endpoint that can sample a continuous voltage and
|
||||
convert it to a discretised value.
|
||||
|
||||
Example usage::
|
||||
|
||||
import machine
|
||||
|
||||
adc = machine.ADC(pin) # create an ADC object acting on a pin
|
||||
val = adc.read_u16() # read a raw analog value in the range 0-65535
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: ADC(id)
|
||||
|
||||
Access the ADC associated with a source identified by *id*. This
|
||||
*id* may be an integer (usually specifying a channel number), a
|
||||
:ref:`Pin <machine.Pin>` object, or other value supported by the
|
||||
underlying machine.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: ADC.read_u16()
|
||||
|
||||
Take an analog reading and return an integer in the range 0-65535.
|
||||
The return value represents the raw reading taken by the ADC, scaled
|
||||
such that the minimum value is 0 and the maximum value is 65535.
|
|
@ -1,81 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.ADCWiPy:
|
||||
|
||||
class ADCWiPy -- analog to digital conversion
|
||||
=============================================
|
||||
|
||||
.. note::
|
||||
|
||||
This class is a non-standard ADC implementation for the WiPy.
|
||||
It is available simply as ``machine.ADC`` on the WiPy but is named in the
|
||||
documentation below as ``machine.ADCWiPy`` to distinguish it from the
|
||||
more general :ref:`machine.ADC <machine.ADC>` class.
|
||||
|
||||
Usage::
|
||||
|
||||
import machine
|
||||
|
||||
adc = machine.ADC() # create an ADC object
|
||||
apin = adc.channel(pin='GP3') # create an analog pin on GP3
|
||||
val = apin() # read an analog value
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: ADCWiPy(id=0, \*, bits=12)
|
||||
|
||||
Create an ADC object associated with the given pin.
|
||||
This allows you to then read analog values on that pin.
|
||||
For more info check the `pinout and alternate functions
|
||||
table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
|
||||
|
||||
.. warning::
|
||||
|
||||
ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it
|
||||
can withstand). When GP2, GP3, GP4 or GP5 are remapped to the
|
||||
ADC block, 1.8 V is the maximum. If these pins are used in digital mode,
|
||||
then the maximum allowed input is 3.6V.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: ADCWiPy.channel(id, \*, pin)
|
||||
|
||||
Create an analog pin. If only channel ID is given, the correct pin will
|
||||
be selected. Alternatively, only the pin can be passed and the correct
|
||||
channel will be selected. Examples::
|
||||
|
||||
# all of these are equivalent and enable ADC channel 1 on GP3
|
||||
apin = adc.channel(1)
|
||||
apin = adc.channel(pin='GP3')
|
||||
apin = adc.channel(id=1, pin='GP3')
|
||||
|
||||
.. method:: ADCWiPy.init()
|
||||
|
||||
Enable the ADC block.
|
||||
|
||||
.. method:: ADCWiPy.deinit()
|
||||
|
||||
Disable the ADC block.
|
||||
|
||||
class ADCChannel --- read analog values from internal or external sources
|
||||
=========================================================================
|
||||
|
||||
ADC channels can be connected to internal points of the MCU or to GPIO pins.
|
||||
ADC channels are created using the ADC.channel method.
|
||||
|
||||
.. method:: adcchannel()
|
||||
|
||||
Fast method to read the channel value.
|
||||
|
||||
.. method:: adcchannel.value()
|
||||
|
||||
Read the channel value.
|
||||
|
||||
.. method:: adcchannel.init()
|
||||
|
||||
Re-init (and effectively enable) the ADC channel.
|
||||
|
||||
.. method:: adcchannel.deinit()
|
||||
|
||||
Disable the ADC channel.
|
|
@ -1,180 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.I2C:
|
||||
|
||||
class I2C -- a two-wire serial protocol
|
||||
=======================================
|
||||
|
||||
I2C is a two-wire protocol for communicating between devices. At the physical
|
||||
level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
|
||||
|
||||
I2C objects are created attached to a specific bus. They can be initialised
|
||||
when created, or initialised later on.
|
||||
|
||||
Printing the I2C object gives you information about its configuration.
|
||||
|
||||
Example usage::
|
||||
|
||||
from machine import I2C
|
||||
|
||||
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
|
||||
# depending on the port, extra parameters may be required
|
||||
# to select the peripheral and/or pins to use
|
||||
|
||||
i2c.scan() # scan for slaves, returning a list of 7-bit addresses
|
||||
|
||||
i2c.writeto(42, b'123') # write 3 bytes to slave with 7-bit address 42
|
||||
i2c.readfrom(42, 4) # read 4 bytes from slave with 7-bit address 42
|
||||
|
||||
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of slave 42,
|
||||
# starting at memory-address 8 in the slave
|
||||
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42
|
||||
# starting at address 2 in the slave
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: I2C(id=-1, \*, scl, sda, freq=400000)
|
||||
|
||||
Construct and return a new I2C object using the following parameters:
|
||||
|
||||
- *id* identifies a particular I2C peripheral. The default
|
||||
value of -1 selects a software implementation of I2C which can
|
||||
work (in most cases) with arbitrary pins for SCL and SDA.
|
||||
If *id* is -1 then *scl* and *sda* must be specified. Other
|
||||
allowed values for *id* depend on the particular port/board,
|
||||
and specifying *scl* and *sda* may or may not be required or
|
||||
allowed in this case.
|
||||
- *scl* should be a pin object specifying the pin to use for SCL.
|
||||
- *sda* should be a pin object specifying the pin to use for SDA.
|
||||
- *freq* should be an integer which sets the maximum frequency
|
||||
for SCL.
|
||||
|
||||
General Methods
|
||||
---------------
|
||||
|
||||
.. method:: I2C.init(scl, sda, \*, freq=400000)
|
||||
|
||||
Initialise the I2C bus with the given arguments:
|
||||
|
||||
- *scl* is a pin object for the SCL line
|
||||
- *sda* is a pin object for the SDA line
|
||||
- *freq* is the SCL clock rate
|
||||
|
||||
.. method:: I2C.deinit()
|
||||
|
||||
Turn off the I2C bus.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. method:: I2C.scan()
|
||||
|
||||
Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of
|
||||
those that respond. A device responds if it pulls the SDA line low after
|
||||
its address (including a write bit) is sent on the bus.
|
||||
|
||||
Primitive I2C operations
|
||||
------------------------
|
||||
|
||||
The following methods implement the primitive I2C master bus operations and can
|
||||
be combined to make any I2C transaction. They are provided if you need more
|
||||
control over the bus, otherwise the standard methods (see below) can be used.
|
||||
|
||||
These methods are available on software I2C only.
|
||||
|
||||
.. method:: I2C.start()
|
||||
|
||||
Generate a START condition on the bus (SDA transitions to low while SCL is high).
|
||||
|
||||
.. method:: I2C.stop()
|
||||
|
||||
Generate a STOP condition on the bus (SDA transitions to high while SCL is high).
|
||||
|
||||
.. method:: I2C.readinto(buf, nack=True)
|
||||
|
||||
Reads bytes from the bus and stores them into *buf*. The number of bytes
|
||||
read is the length of *buf*. An ACK will be sent on the bus after
|
||||
receiving all but the last byte. After the last byte is received, if *nack*
|
||||
is true then a NACK will be sent, otherwise an ACK will be sent (and in this
|
||||
case the slave assumes more bytes are going to be read in a later call).
|
||||
|
||||
.. method:: I2C.write(buf)
|
||||
|
||||
Write the bytes from *buf* to the bus. Checks that an ACK is received
|
||||
after each byte and stops transmitting the remaining bytes if a NACK is
|
||||
received. The function returns the number of ACKs that were received.
|
||||
|
||||
Standard bus operations
|
||||
-----------------------
|
||||
|
||||
The following methods implement the standard I2C master read and write
|
||||
operations that target a given slave device.
|
||||
|
||||
.. method:: I2C.readfrom(addr, nbytes, stop=True)
|
||||
|
||||
Read *nbytes* from the slave specified by *addr*.
|
||||
If *stop* is true then a STOP condition is generated at the end of the transfer.
|
||||
Returns a `bytes` object with the data read.
|
||||
|
||||
.. method:: I2C.readfrom_into(addr, buf, stop=True)
|
||||
|
||||
Read into *buf* from the slave specified by *addr*.
|
||||
The number of bytes read will be the length of *buf*.
|
||||
If *stop* is true then a STOP condition is generated at the end of the transfer.
|
||||
|
||||
The method returns ``None``.
|
||||
|
||||
.. method:: I2C.writeto(addr, buf, stop=True)
|
||||
|
||||
Write the bytes from *buf* to the slave specified by *addr*. If a
|
||||
NACK is received following the write of a byte from *buf* then the
|
||||
remaining bytes are not sent. If *stop* is true then a STOP condition is
|
||||
generated at the end of the transfer, even if a NACK is received.
|
||||
The function returns the number of ACKs that were received.
|
||||
|
||||
.. method:: I2C.writevto(addr, vector, stop=True)
|
||||
|
||||
Write the bytes contained in *vector* to the slave specified by *addr*.
|
||||
*vector* should be a tuple or list of objects with the buffer protocol.
|
||||
The *addr* is sent once and then the bytes from each object in *vector*
|
||||
are written out sequentially. The objects in *vector* may be zero bytes
|
||||
in length in which case they don't contribute to the output.
|
||||
|
||||
If a NACK is received following the write of a byte from one of the
|
||||
objects in *vector* then the remaining bytes, and any remaining objects,
|
||||
are not sent. If *stop* is true then a STOP condition is generated at
|
||||
the end of the transfer, even if a NACK is received. The function
|
||||
returns the number of ACKs that were received.
|
||||
|
||||
Memory operations
|
||||
-----------------
|
||||
|
||||
Some I2C devices act as a memory device (or set of registers) that can be read
|
||||
from and written to. In this case there are two addresses associated with an
|
||||
I2C transaction: the slave address and the memory address. The following
|
||||
methods are convenience functions to communicate with such devices.
|
||||
|
||||
.. method:: I2C.readfrom_mem(addr, memaddr, nbytes, \*, addrsize=8)
|
||||
|
||||
Read *nbytes* from the slave specified by *addr* starting from the memory
|
||||
address specified by *memaddr*.
|
||||
The argument *addrsize* specifies the address size in bits.
|
||||
Returns a `bytes` object with the data read.
|
||||
|
||||
.. method:: I2C.readfrom_mem_into(addr, memaddr, buf, \*, addrsize=8)
|
||||
|
||||
Read into *buf* from the slave specified by *addr* starting from the
|
||||
memory address specified by *memaddr*. The number of bytes read is the
|
||||
length of *buf*.
|
||||
The argument *addrsize* specifies the address size in bits (on ESP8266
|
||||
this argument is not recognised and the address size is always 8 bits).
|
||||
|
||||
The method returns ``None``.
|
||||
|
||||
.. method:: I2C.writeto_mem(addr, memaddr, buf, \*, addrsize=8)
|
||||
|
||||
Write *buf* to the slave specified by *addr* starting from the
|
||||
memory address specified by *memaddr*.
|
||||
The argument *addrsize* specifies the address size in bits (on ESP8266
|
||||
this argument is not recognised and the address size is always 8 bits).
|
||||
|
||||
The method returns ``None``.
|
|
@ -1,254 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.Pin:
|
||||
|
||||
class Pin -- control I/O pins
|
||||
=============================
|
||||
|
||||
A pin object is used to control I/O pins (also known as GPIO - general-purpose
|
||||
input/output). Pin objects are commonly associated with a physical pin that can
|
||||
drive an output voltage and read input voltages. The pin class has methods to set the mode of
|
||||
the pin (IN, OUT, etc) and methods to get and set the digital logic level.
|
||||
For analog control of a pin, see the :class:`ADC` class.
|
||||
|
||||
A pin object is constructed by using an identifier which unambiguously
|
||||
specifies a certain I/O pin. The allowed forms of the identifier and the
|
||||
physical pin that the identifier maps to are port-specific. Possibilities
|
||||
for the identifier are an integer, a string or a tuple with port and pin
|
||||
number.
|
||||
|
||||
Usage Model::
|
||||
|
||||
from machine import Pin
|
||||
|
||||
# create an output pin on pin #0
|
||||
p0 = Pin(0, Pin.OUT)
|
||||
|
||||
# set the value low then high
|
||||
p0.value(0)
|
||||
p0.value(1)
|
||||
|
||||
# create an input pin on pin #2, with a pull up resistor
|
||||
p2 = Pin(2, Pin.IN, Pin.PULL_UP)
|
||||
|
||||
# read and print the pin value
|
||||
print(p2.value())
|
||||
|
||||
# reconfigure pin #0 in input mode
|
||||
p0.mode(p0.IN)
|
||||
|
||||
# configure an irq callback
|
||||
p0.irq(lambda p:print(p))
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Pin(id, mode=-1, pull=-1, \*, value, drive, alt)
|
||||
|
||||
Access the pin peripheral (GPIO pin) associated with the given ``id``. If
|
||||
additional arguments are given in the constructor then they are used to initialise
|
||||
the pin. Any settings that are not specified will remain in their previous state.
|
||||
|
||||
The arguments are:
|
||||
|
||||
- ``id`` is mandatory and can be an arbitrary object. Among possible value
|
||||
types are: int (an internal Pin identifier), str (a Pin name), and tuple
|
||||
(pair of [port, pin]).
|
||||
|
||||
- ``mode`` specifies the pin mode, which can be one of:
|
||||
|
||||
- ``Pin.IN`` - Pin is configured for input. If viewed as an output the pin
|
||||
is in high-impedance state.
|
||||
|
||||
- ``Pin.OUT`` - Pin is configured for (normal) output.
|
||||
|
||||
- ``Pin.OPEN_DRAIN`` - Pin is configured for open-drain output. Open-drain
|
||||
output works in the following way: if the output value is set to 0 the pin
|
||||
is active at a low level; if the output value is 1 the pin is in a high-impedance
|
||||
state. Not all ports implement this mode, or some might only on certain pins.
|
||||
|
||||
- ``Pin.ALT`` - Pin is configured to perform an alternative function, which is
|
||||
port specific. For a pin configured in such a way any other Pin methods
|
||||
(except :meth:`Pin.init`) are not applicable (calling them will lead to undefined,
|
||||
or a hardware-specific, result). Not all ports implement this mode.
|
||||
|
||||
- ``Pin.ALT_OPEN_DRAIN`` - The Same as ``Pin.ALT``, but the pin is configured as
|
||||
open-drain. Not all ports implement this mode.
|
||||
|
||||
- ``pull`` specifies if the pin has a (weak) pull resistor attached, and can be
|
||||
one of:
|
||||
|
||||
- ``None`` - No pull up or down resistor.
|
||||
- ``Pin.PULL_UP`` - Pull up resistor enabled.
|
||||
- ``Pin.PULL_DOWN`` - Pull down resistor enabled.
|
||||
|
||||
- ``value`` is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial
|
||||
output pin value if given, otherwise the state of the pin peripheral remains
|
||||
unchanged.
|
||||
|
||||
- ``drive`` specifies the output power of the pin and can be one of: ``Pin.LOW_POWER``,
|
||||
``Pin.MED_POWER`` or ``Pin.HIGH_POWER``. The actual current driving capabilities
|
||||
are port dependent. Not all ports implement this argument.
|
||||
|
||||
- ``alt`` specifies an alternate function for the pin and the values it can take are
|
||||
port dependent. This argument is valid only for ``Pin.ALT`` and ``Pin.ALT_OPEN_DRAIN``
|
||||
modes. It may be used when a pin supports more than one alternate function. If only
|
||||
one pin alternate function is supported the this argument is not required. Not all
|
||||
ports implement this argument.
|
||||
|
||||
As specified above, the Pin class allows to set an alternate function for a particular
|
||||
pin, but it does not specify any further operations on such a pin. Pins configured in
|
||||
alternate-function mode are usually not used as GPIO but are instead driven by other
|
||||
hardware peripherals. The only operation supported on such a pin is re-initialising,
|
||||
by calling the constructor or :meth:`Pin.init` method. If a pin that is configured in
|
||||
alternate-function mode is re-initialised with ``Pin.IN``, ``Pin.OUT``, or
|
||||
``Pin.OPEN_DRAIN``, the alternate function will be removed from the pin.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Pin.init(mode=-1, pull=-1, \*, value, drive, alt)
|
||||
|
||||
Re-initialise the pin using the given parameters. Only those arguments that
|
||||
are specified will be set. The rest of the pin peripheral state will remain
|
||||
unchanged. See the constructor documentation for details of the arguments.
|
||||
|
||||
Returns ``None``.
|
||||
|
||||
.. method:: Pin.value([x])
|
||||
|
||||
This method allows to set and get the value of the pin, depending on whether
|
||||
the argument ``x`` is supplied or not.
|
||||
|
||||
If the argument is omitted then this method gets the digital logic level of
|
||||
the pin, returning 0 or 1 corresponding to low and high voltage signals
|
||||
respectively. The behaviour of this method depends on the mode of the pin:
|
||||
|
||||
- ``Pin.IN`` - The method returns the actual input value currently present
|
||||
on the pin.
|
||||
- ``Pin.OUT`` - The behaviour and return value of the method is undefined.
|
||||
- ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and
|
||||
return value of the method is undefined. Otherwise, if the pin is in
|
||||
state '1', the method returns the actual input value currently present
|
||||
on the pin.
|
||||
|
||||
If the argument is supplied then this method sets the digital logic level of
|
||||
the pin. The argument ``x`` can be anything that converts to a boolean.
|
||||
If it converts to ``True``, the pin is set to state '1', otherwise it is set
|
||||
to state '0'. The behaviour of this method depends on the mode of the pin:
|
||||
|
||||
- ``Pin.IN`` - The value is stored in the output buffer for the pin. The
|
||||
pin state does not change, it remains in the high-impedance state. The
|
||||
stored value will become active on the pin as soon as it is changed to
|
||||
``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode.
|
||||
- ``Pin.OUT`` - The output buffer is set to the given value immediately.
|
||||
- ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage
|
||||
state. Otherwise the pin is set to high-impedance state.
|
||||
|
||||
When setting the value this method returns ``None``.
|
||||
|
||||
.. method:: Pin.__call__([x])
|
||||
|
||||
Pin objects are callable. The call method provides a (fast) shortcut to set
|
||||
and get the value of the pin. It is equivalent to Pin.value([x]).
|
||||
See :meth:`Pin.value` for more details.
|
||||
|
||||
.. method:: Pin.on()
|
||||
|
||||
Set pin to "1" output level.
|
||||
|
||||
.. method:: Pin.off()
|
||||
|
||||
Set pin to "0" output level.
|
||||
|
||||
.. method:: Pin.mode([mode])
|
||||
|
||||
Get or set the pin mode.
|
||||
See the constructor documentation for details of the ``mode`` argument.
|
||||
|
||||
.. method:: Pin.pull([pull])
|
||||
|
||||
Get or set the pin pull state.
|
||||
See the constructor documentation for details of the ``pull`` argument.
|
||||
|
||||
.. method:: Pin.drive([drive])
|
||||
|
||||
Get or set the pin drive strength.
|
||||
See the constructor documentation for details of the ``drive`` argument.
|
||||
|
||||
Not all ports implement this method.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. method:: Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), \*, priority=1, wake=None, hard=False)
|
||||
|
||||
Configure an interrupt handler to be called when the trigger source of the
|
||||
pin is active. If the pin mode is ``Pin.IN`` then the trigger source is
|
||||
the external value on the pin. If the pin mode is ``Pin.OUT`` then the
|
||||
trigger source is the output buffer of the pin. Otherwise, if the pin mode
|
||||
is ``Pin.OPEN_DRAIN`` then the trigger source is the output buffer for
|
||||
state '0' and the external pin value for state '1'.
|
||||
|
||||
The arguments are:
|
||||
|
||||
- ``handler`` is an optional function to be called when the interrupt
|
||||
triggers. The handler must take exactly one argument which is the
|
||||
``Pin`` instance.
|
||||
|
||||
- ``trigger`` configures the event which can generate an interrupt.
|
||||
Possible values are:
|
||||
|
||||
- ``Pin.IRQ_FALLING`` interrupt on falling edge.
|
||||
- ``Pin.IRQ_RISING`` interrupt on rising edge.
|
||||
- ``Pin.IRQ_LOW_LEVEL`` interrupt on low level.
|
||||
- ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level.
|
||||
|
||||
These values can be OR'ed together to trigger on multiple events.
|
||||
|
||||
- ``priority`` sets the priority level of the interrupt. The values it
|
||||
can take are port-specific, but higher values always represent higher
|
||||
priorities.
|
||||
|
||||
- ``wake`` selects the power mode in which this interrupt can wake up the
|
||||
system. It can be ``machine.IDLE``, ``machine.SLEEP`` or ``machine.DEEPSLEEP``.
|
||||
These values can also be OR'ed together to make a pin generate interrupts in
|
||||
more than one power mode.
|
||||
|
||||
- ``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`.
|
||||
|
||||
This method returns a callback object.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
The following constants are used to configure the pin objects. Note that
|
||||
not all constants are available on all ports.
|
||||
|
||||
.. data:: Pin.IN
|
||||
Pin.OUT
|
||||
Pin.OPEN_DRAIN
|
||||
Pin.ALT
|
||||
Pin.ALT_OPEN_DRAIN
|
||||
|
||||
Selects the pin mode.
|
||||
|
||||
.. data:: Pin.PULL_UP
|
||||
Pin.PULL_DOWN
|
||||
Pin.PULL_HOLD
|
||||
|
||||
Selects whether there is a pull up/down resistor. Use the value
|
||||
``None`` for no pull.
|
||||
|
||||
.. data:: Pin.LOW_POWER
|
||||
Pin.MED_POWER
|
||||
Pin.HIGH_POWER
|
||||
|
||||
Selects the pin drive strength.
|
||||
|
||||
.. data:: Pin.IRQ_FALLING
|
||||
Pin.IRQ_RISING
|
||||
Pin.IRQ_LOW_LEVEL
|
||||
Pin.IRQ_HIGH_LEVEL
|
||||
|
||||
Selects the IRQ trigger type.
|
|
@ -1,69 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.RTC:
|
||||
|
||||
class RTC -- real time clock
|
||||
============================
|
||||
|
||||
The RTC is and independent clock that keeps track of the date
|
||||
and time.
|
||||
|
||||
Example usage::
|
||||
|
||||
rtc = machine.RTC()
|
||||
rtc.init((2014, 5, 1, 4, 13, 0, 0, 0))
|
||||
print(rtc.now())
|
||||
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: RTC(id=0, ...)
|
||||
|
||||
Create an RTC object. See init for parameters of initialization.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: RTC.init(datetime)
|
||||
|
||||
Initialise the RTC. Datetime is a tuple of the form:
|
||||
|
||||
``(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])``
|
||||
|
||||
.. method:: RTC.now()
|
||||
|
||||
Get get the current datetime tuple.
|
||||
|
||||
.. method:: RTC.deinit()
|
||||
|
||||
Resets the RTC to the time of January 1, 2015 and starts running it again.
|
||||
|
||||
.. method:: RTC.alarm(id, time, \*, repeat=False)
|
||||
|
||||
Set the RTC alarm. Time might be either a millisecond value to program the alarm to
|
||||
current time + time_in_ms in the future, or a datetimetuple. If the time passed is in
|
||||
milliseconds, repeat can be set to ``True`` to make the alarm periodic.
|
||||
|
||||
.. method:: RTC.alarm_left(alarm_id=0)
|
||||
|
||||
Get the number of milliseconds left before the alarm expires.
|
||||
|
||||
.. method:: RTC.cancel(alarm_id=0)
|
||||
|
||||
Cancel a running alarm.
|
||||
|
||||
.. method:: RTC.irq(\*, trigger, handler=None, wake=machine.IDLE)
|
||||
|
||||
Create an irq object triggered by a real time clock alarm.
|
||||
|
||||
- ``trigger`` must be ``RTC.ALARM0``
|
||||
- ``handler`` is the function to be called when the callback is triggered.
|
||||
- ``wake`` specifies the sleep mode from where this interrupt can wake
|
||||
up the system.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: RTC.ALARM0
|
||||
|
||||
irq trigger source
|
|
@ -1,47 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.SD:
|
||||
|
||||
class SD -- secure digital memory card (cc3200 port only)
|
||||
=========================================================
|
||||
|
||||
.. warning::
|
||||
|
||||
This is a non-standard class and is only available on the cc3200 port.
|
||||
|
||||
|
||||
The SD card class allows to configure and enable the memory card
|
||||
module of the WiPy and automatically mount it as ``/sd`` as part
|
||||
of the file system. There are several pin combinations that can be
|
||||
used to wire the SD card socket to the WiPy and the pins used can
|
||||
be specified in the constructor. Please check the `pinout and alternate functions
|
||||
table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ for
|
||||
more info regarding the pins which can be remapped to be used with a SD card.
|
||||
|
||||
Example usage::
|
||||
|
||||
from machine import SD
|
||||
import os
|
||||
# clk cmd and dat0 pins must be passed along with
|
||||
# their respective alternate functions
|
||||
sd = machine.SD(pins=('GP10', 'GP11', 'GP15'))
|
||||
os.mount(sd, '/sd')
|
||||
# do normal file operations
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: SD(id,... )
|
||||
|
||||
Create a SD card object. See ``init()`` for parameters if initialization.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: SD.init(id=0, pins=('GP10', 'GP11', 'GP15'))
|
||||
|
||||
Enable the SD card. In order to initialize the card, give it a 3-tuple:
|
||||
``(clk_pin, cmd_pin, dat0_pin)``.
|
||||
|
||||
.. method:: SD.deinit()
|
||||
|
||||
Disable the SD card.
|
|
@ -1,122 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.SDCard:
|
||||
|
||||
class SDCard -- secure digital memory card
|
||||
==========================================
|
||||
|
||||
SD cards are one of the most common small form factor removable storage media.
|
||||
SD cards come in a variety of sizes and physical form factors. MMC cards are
|
||||
similar removable storage devices while eMMC devices are electrically similar
|
||||
storage devices designed to be embedded into other systems. All three form
|
||||
share a common protocol for communication with their host system and high-level
|
||||
support looks the same for them all. As such in MicroPython they are implemented
|
||||
in a single class called :class:`machine.SDCard` .
|
||||
|
||||
Both SD and MMC interfaces support being accessed with a variety of bus widths.
|
||||
When being accessed with a 1-bit wide interface they can be accessed using the
|
||||
SPI protocol. Different MicroPython hardware platforms support different widths
|
||||
and pin configurations but for most platforms there is a standard configuration
|
||||
for any given hardware. In general constructing an ``SDCard`` object with without
|
||||
passing any parameters will initialise the interface to the default card slot
|
||||
for the current hardware. The arguments listed below represent the common
|
||||
arguments that might need to be set in order to use either a non-standard slot
|
||||
or a non-standard pin assignment. The exact subset of arguments supported will
|
||||
vary from platform to platform.
|
||||
|
||||
.. class:: SDCard(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None, cs=None)
|
||||
|
||||
This class provides access to SD or MMC storage cards using either
|
||||
a dedicated SD/MMC interface hardware or through an SPI channel.
|
||||
The class implements the block protocol defined by :class:`uos.AbstractBlockDev`.
|
||||
This allows the mounting of an SD card to be as simple as::
|
||||
|
||||
uos.mount(machine.SDCard(), "/sd")
|
||||
|
||||
The constructor takes the following parameters:
|
||||
|
||||
- *slot* selects which of the available interfaces to use. Leaving this
|
||||
unset will select the default interface.
|
||||
|
||||
- *width* selects the bus width for the SD/MMC interface.
|
||||
|
||||
- *cd* can be used to specify a card-detect pin.
|
||||
|
||||
- *wp* can be used to specify a write-protect pin.
|
||||
|
||||
- *sck* can be used to specify an SPI clock pin.
|
||||
|
||||
- *miso* can be used to specify an SPI miso pin.
|
||||
|
||||
- *mosi* can be used to specify an SPI mosi pin.
|
||||
|
||||
- *cs* can be used to specify an SPI chip select pin.
|
||||
|
||||
Implementation-specific details
|
||||
-------------------------------
|
||||
|
||||
Different implementations of the ``SDCard`` class on different hardware support
|
||||
varying subsets of the options above.
|
||||
|
||||
PyBoard
|
||||
```````
|
||||
|
||||
The standard PyBoard has just one slot. No arguments are necessary or supported.
|
||||
|
||||
ESP32
|
||||
`````
|
||||
|
||||
The ESP32 provides two channels of SD/MMC hardware and also supports
|
||||
access to SD Cards through either of the two SPI ports that are
|
||||
generally available to the user. As a result the *slot* argument can
|
||||
take a value between 0 and 3, inclusive. Slots 0 and 1 use the
|
||||
built-in SD/MMC hardware while slots 2 and 3 use the SPI ports. Slot 0
|
||||
supports 1, 4 or 8-bit wide access while slot 1 supports 1 or 4-bit
|
||||
access; the SPI slots only support 1-bit access.
|
||||
|
||||
.. note:: Slot 0 is used to communicate with on-board flash memory
|
||||
on most ESP32 modules and so will be unavailable to the
|
||||
user.
|
||||
|
||||
.. note:: Most ESP32 modules that provide an SD card slot using the
|
||||
dedicated hardware only wire up 1 data pin, so the default
|
||||
value for *width* is 1.
|
||||
|
||||
The pins used by the dedicated SD/MMC hardware are fixed. The pins
|
||||
used by the SPI hardware can be reassigned.
|
||||
|
||||
.. note:: If any of the SPI signals are remapped then all of the SPI
|
||||
signals will pass through a GPIO multiplexer unit which
|
||||
can limit the performance of high frequency signals. Since
|
||||
the normal operating speed for SD cards is 40MHz this can
|
||||
cause problems on some cards.
|
||||
|
||||
The default (and preferred) pin assignment are as follows:
|
||||
|
||||
====== ====== ====== ====== ======
|
||||
Slot 0 1 2 3
|
||||
------ ------ ------ ------ ------
|
||||
Signal Pin Pin Pin Pin
|
||||
====== ====== ====== ====== ======
|
||||
sck 6 14 18 14
|
||||
cmd 11 15
|
||||
cs 5 15
|
||||
miso 19 12
|
||||
mosi 23 13
|
||||
D0 7 2
|
||||
D1 8 4
|
||||
D2 9 12
|
||||
D3 10 13
|
||||
D4 16
|
||||
D5 17
|
||||
D6 5
|
||||
D7 18
|
||||
====== ====== ====== ====== ======
|
||||
|
||||
cc3200
|
||||
``````
|
||||
|
||||
You can set the pins used for SPI access by passing a tuple as the
|
||||
*pins* argument.
|
||||
|
||||
*Note:* The current cc3200 SD card implementation names the this class
|
||||
:class:`machine.SD` rather than :class:`machine.SDCard` .
|
|
@ -1,101 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.SPI:
|
||||
|
||||
class SPI -- a Serial Peripheral Interface bus protocol (master side)
|
||||
=====================================================================
|
||||
|
||||
SPI is a synchronous serial protocol that is driven by a master. At the
|
||||
physical level, a bus consists of 3 lines: SCK, MOSI, MISO. Multiple devices
|
||||
can share the same bus. Each device should have a separate, 4th signal,
|
||||
SS (Slave Select), to select a particular device on a bus with which
|
||||
communication takes place. Management of an SS signal should happen in
|
||||
user code (via machine.Pin class).
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: SPI(id, ...)
|
||||
|
||||
Construct an SPI object on the given bus, ``id``. Values of ``id`` depend
|
||||
on a particular port and its hardware. Values 0, 1, etc. are commonly used
|
||||
to select hardware SPI block #0, #1, etc. Value -1 can be used for
|
||||
bitbanging (software) implementation of SPI (if supported by a port).
|
||||
|
||||
With no additional parameters, the SPI object is created but not
|
||||
initialised (it has the settings from the last initialisation of
|
||||
the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
See ``init`` for parameters of initialisation.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: SPI.init(baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))
|
||||
|
||||
Initialise the SPI bus with the given parameters:
|
||||
|
||||
- ``baudrate`` is the SCK clock rate.
|
||||
- ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
|
||||
- ``phase`` can be 0 or 1 to sample data on the first or second clock edge
|
||||
respectively.
|
||||
- ``bits`` is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware.
|
||||
- ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
|
||||
- ``sck``, ``mosi``, ``miso`` are pins (machine.Pin) objects to use for bus signals. For most
|
||||
hardware SPI blocks (as selected by ``id`` parameter to the constructor), pins are fixed
|
||||
and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for
|
||||
a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver
|
||||
(``id`` = -1).
|
||||
- ``pins`` - WiPy port doesn't ``sck``, ``mosi``, ``miso`` arguments, and instead allows to
|
||||
specify them as a tuple of ``pins`` parameter.
|
||||
|
||||
In the case of hardware SPI the actual clock frequency may be lower than the
|
||||
requested baudrate. This is dependant on the platform hardware. The actual
|
||||
rate may be determined by printing the SPI object.
|
||||
|
||||
.. method:: SPI.deinit()
|
||||
|
||||
Turn off the SPI bus.
|
||||
|
||||
.. method:: SPI.read(nbytes, write=0x00)
|
||||
|
||||
Read a number of bytes specified by ``nbytes`` while continuously writing
|
||||
the single byte given by ``write``.
|
||||
Returns a ``bytes`` object with the data that was read.
|
||||
|
||||
.. method:: SPI.readinto(buf, write=0x00)
|
||||
|
||||
Read into the buffer specified by ``buf`` while continuously writing the
|
||||
single byte given by ``write``.
|
||||
Returns ``None``.
|
||||
|
||||
Note: on WiPy this function returns the number of bytes read.
|
||||
|
||||
.. method:: SPI.write(buf)
|
||||
|
||||
Write the bytes contained in ``buf``.
|
||||
Returns ``None``.
|
||||
|
||||
Note: on WiPy this function returns the number of bytes written.
|
||||
|
||||
.. method:: SPI.write_readinto(write_buf, read_buf)
|
||||
|
||||
Write the bytes from ``write_buf`` while reading into ``read_buf``. The
|
||||
buffers can be the same or different, but both buffers must have the
|
||||
same length.
|
||||
Returns ``None``.
|
||||
|
||||
Note: on WiPy this function returns the number of bytes written.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: SPI.MASTER
|
||||
|
||||
for initialising the SPI bus to master; this is only used for the WiPy
|
||||
|
||||
.. data:: SPI.MSB
|
||||
|
||||
set the first bit to be the most significant bit
|
||||
|
||||
.. data:: SPI.LSB
|
||||
|
||||
set the first bit to be the least significant bit
|
|
@ -1,123 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.Signal:
|
||||
|
||||
class Signal -- control and sense external I/O devices
|
||||
======================================================
|
||||
|
||||
The Signal class is a simple extension of the `Pin` class. Unlike Pin, which
|
||||
can be only in "absolute" 0 and 1 states, a Signal can be in "asserted"
|
||||
(on) or "deasserted" (off) states, while being inverted (active-low) or
|
||||
not. In other words, it adds logical inversion support to Pin functionality.
|
||||
While this may seem a simple addition, it is exactly what is needed to
|
||||
support wide array of simple digital devices in a way portable across
|
||||
different boards, which is one of the major MicroPython goals. Regardless
|
||||
of whether different users have an active-high or active-low LED, a normally
|
||||
open or normally closed relay - you can develop a single, nicely looking
|
||||
application which works with each of them, and capture hardware
|
||||
configuration differences in few lines in the config file of your app.
|
||||
|
||||
Example::
|
||||
|
||||
from machine import Pin, Signal
|
||||
|
||||
# Suppose you have an active-high LED on pin 0
|
||||
led1_pin = Pin(0, Pin.OUT)
|
||||
# ... and active-low LED on pin 1
|
||||
led2_pin = Pin(1, Pin.OUT)
|
||||
|
||||
# Now to light up both of them using Pin class, you'll need to set
|
||||
# them to different values
|
||||
led1_pin.value(1)
|
||||
led2_pin.value(0)
|
||||
|
||||
# Signal class allows to abstract away active-high/active-low
|
||||
# difference
|
||||
led1 = Signal(led1_pin, invert=False)
|
||||
led2 = Signal(led2_pin, invert=True)
|
||||
|
||||
# Now lighting up them looks the same
|
||||
led1.value(1)
|
||||
led2.value(1)
|
||||
|
||||
# Even better:
|
||||
led1.on()
|
||||
led2.on()
|
||||
|
||||
Following is the guide when Signal vs Pin should be used:
|
||||
|
||||
* Use Signal: If you want to control a simple on/off (including software
|
||||
PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or
|
||||
read simple binary sensors, like normally open or normally closed buttons,
|
||||
pulled high or low, Reed switches, moisture/flame detectors, etc. etc.
|
||||
Summing up, if you have a real physical device/sensor requiring GPIO
|
||||
access, you likely should use a Signal.
|
||||
|
||||
* Use Pin: If you implement a higher-level protocol or bus to communicate
|
||||
with more complex devices.
|
||||
|
||||
The split between Pin and Signal come from the usecases above and the
|
||||
architecture of MicroPython: Pin offers the lowest overhead, which may
|
||||
be important when bit-banging protocols. But Signal adds additional
|
||||
flexibility on top of Pin, at the cost of minor overhead (much smaller
|
||||
than if you implemented active-high vs active-low device differences in
|
||||
Python manually!). Also, Pin is a low-level object which needs to be
|
||||
implemented for each support board, while Signal is a high-level object
|
||||
which comes for free once Pin is implemented.
|
||||
|
||||
If in doubt, give the Signal a try! Once again, it is offered to save
|
||||
developers from the need to handle unexciting differences like active-low
|
||||
vs active-high signals, and allow other users to share and enjoy your
|
||||
application, instead of being frustrated by the fact that it doesn't
|
||||
work for them simply because their LEDs or relays are wired in a slightly
|
||||
different way.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Signal(pin_obj, invert=False)
|
||||
Signal(pin_arguments..., \*, invert=False)
|
||||
|
||||
Create a Signal object. There're two ways to create it:
|
||||
|
||||
* By wrapping existing Pin object - universal method which works for
|
||||
any board.
|
||||
* By passing required Pin parameters directly to Signal constructor,
|
||||
skipping the need to create intermediate Pin object. Available on
|
||||
many, but not all boards.
|
||||
|
||||
The arguments are:
|
||||
|
||||
- ``pin_obj`` is existing Pin object.
|
||||
|
||||
- ``pin_arguments`` are the same arguments as can be passed to Pin constructor.
|
||||
|
||||
- ``invert`` - if True, the signal will be inverted (active low).
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Signal.value([x])
|
||||
|
||||
This method allows to set and get the value of the signal, depending on whether
|
||||
the argument ``x`` is supplied or not.
|
||||
|
||||
If the argument is omitted then this method gets the signal level, 1 meaning
|
||||
signal is asserted (active) and 0 - signal inactive.
|
||||
|
||||
If the argument is supplied then this method sets the signal level. The
|
||||
argument ``x`` can be anything that converts to a boolean. If it converts
|
||||
to ``True``, the signal is active, otherwise it is inactive.
|
||||
|
||||
Correspondence between signal being active and actual logic level on the
|
||||
underlying pin depends on whether signal is inverted (active-low) or not.
|
||||
For non-inverted signal, active status corresponds to logical 1, inactive -
|
||||
to logical 0. For inverted/active-low signal, active status corresponds
|
||||
to logical 0, while inactive - to logical 1.
|
||||
|
||||
.. method:: Signal.on()
|
||||
|
||||
Activate signal.
|
||||
|
||||
.. method:: Signal.off()
|
||||
|
||||
Deactivate signal.
|
|
@ -1,64 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.Timer:
|
||||
|
||||
class Timer -- control hardware timers
|
||||
======================================
|
||||
|
||||
Hardware timers deal with timing of periods and events. Timers are perhaps
|
||||
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
|
||||
differently greatly from a model to a model. MicroPython's Timer class
|
||||
defines a baseline operation of executing a callback with a given period
|
||||
(or once after some delay), and allow specific boards to define more
|
||||
non-standard behavior (which thus won't be portable to other boards).
|
||||
|
||||
See discussion of :ref:`important constraints <machine_callbacks>` on
|
||||
Timer callbacks.
|
||||
|
||||
.. note::
|
||||
|
||||
Memory can't be allocated inside irq handlers (an interrupt) and so
|
||||
exceptions raised within a handler don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
|
||||
If you are using a WiPy board please refer to :ref:`machine.TimerWiPy <machine.TimerWiPy>`
|
||||
instead of this class.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: Timer(id, ...)
|
||||
|
||||
Construct a new timer object of the given id. Id of -1 constructs a
|
||||
virtual timer (if supported by a board).
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Timer.init(\*, mode=Timer.PERIODIC, period=-1, callback=None)
|
||||
|
||||
Initialise the timer. Example::
|
||||
|
||||
tim.init(period=100) # periodic with 100ms period
|
||||
tim.init(mode=Timer.ONE_SHOT, period=1000) # one shot firing after 1000ms
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``Timer.ONE_SHOT`` - The timer runs once until the configured
|
||||
period of the channel expires.
|
||||
- ``Timer.PERIODIC`` - The timer runs periodically at the configured
|
||||
frequency of the channel.
|
||||
|
||||
.. method:: Timer.deinit()
|
||||
|
||||
Deinitialises the timer. Stops the timer, and disables the timer peripheral.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: Timer.ONE_SHOT
|
||||
Timer.PERIODIC
|
||||
|
||||
Timer operating mode.
|
|
@ -1,159 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.TimerWiPy:
|
||||
|
||||
class TimerWiPy -- control hardware timers
|
||||
==========================================
|
||||
|
||||
.. note::
|
||||
|
||||
This class is a non-standard Timer implementation for the WiPy.
|
||||
It is available simply as ``machine.Timer`` on the WiPy but is named in the
|
||||
documentation below as ``machine.TimerWiPy`` to distinguish it from the
|
||||
more general :ref:`machine.Timer <machine.Timer>` class.
|
||||
|
||||
Hardware timers deal with timing of periods and events. Timers are perhaps
|
||||
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
|
||||
differently greatly from a model to a model. MicroPython's Timer class
|
||||
defines a baseline operation of executing a callback with a given period
|
||||
(or once after some delay), and allow specific boards to define more
|
||||
non-standard behavior (which thus won't be portable to other boards).
|
||||
|
||||
See discussion of :ref:`important constraints <machine_callbacks>` on
|
||||
Timer callbacks.
|
||||
|
||||
.. note::
|
||||
|
||||
Memory can't be allocated inside irq handlers (an interrupt) and so
|
||||
exceptions raised within a handler don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: TimerWiPy(id, ...)
|
||||
|
||||
Construct a new timer object of the given id. Id of -1 constructs a
|
||||
virtual timer (if supported by a board).
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: TimerWiPy.init(mode, \*, width=16)
|
||||
|
||||
Initialise the timer. Example::
|
||||
|
||||
tim.init(Timer.PERIODIC) # periodic 16-bit timer
|
||||
tim.init(Timer.ONE_SHOT, width=32) # one shot 32-bit timer
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``TimerWiPy.ONE_SHOT`` - The timer runs once until the configured
|
||||
period of the channel expires.
|
||||
- ``TimerWiPy.PERIODIC`` - The timer runs periodically at the configured
|
||||
frequency of the channel.
|
||||
- ``TimerWiPy.PWM`` - Output a PWM signal on a pin.
|
||||
|
||||
- ``width`` must be either 16 or 32 (bits). For really low frequencies < 5Hz
|
||||
(or large periods), 32-bit timers should be used. 32-bit mode is only available
|
||||
for ``ONE_SHOT`` AND ``PERIODIC`` modes.
|
||||
|
||||
.. method:: TimerWiPy.deinit()
|
||||
|
||||
Deinitialises the timer. Stops the timer, and disables the timer peripheral.
|
||||
|
||||
.. method:: TimerWiPy.channel(channel, \**, freq, period, polarity=TimerWiPy.POSITIVE, duty_cycle=0)
|
||||
|
||||
If only a channel identifier passed, then a previously initialized channel
|
||||
object is returned (or ``None`` if there is no previous channel).
|
||||
|
||||
Otherwise, a TimerChannel object is initialized and returned.
|
||||
|
||||
The operating mode is is the one configured to the Timer object that was used to
|
||||
create the channel.
|
||||
|
||||
- ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``.
|
||||
If the width is 32-bit then it **must be** ``TIMER.A | TIMER.B``.
|
||||
|
||||
Keyword only arguments:
|
||||
|
||||
- ``freq`` sets the frequency in Hz.
|
||||
- ``period`` sets the period in microseconds.
|
||||
|
||||
.. note::
|
||||
|
||||
Either ``freq`` or ``period`` must be given, never both.
|
||||
|
||||
- ``polarity`` this is applicable for ``PWM``, and defines the polarity of the duty cycle
|
||||
- ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0.00-100.00). Since the WiPy
|
||||
doesn't support floating point numbers the duty cycle must be specified in the range 0-10000,
|
||||
where 10000 would represent 100.00, 5050 represents 50.50, and so on.
|
||||
|
||||
.. note::
|
||||
|
||||
When the channel is in PWM mode, the corresponding pin is assigned automatically, therefore
|
||||
there's no need to assign the alternate function of the pin via the ``Pin`` class. The pins which
|
||||
support PWM functionality are the following:
|
||||
|
||||
- ``GP24`` on Timer 0 channel A.
|
||||
- ``GP25`` on Timer 1 channel A.
|
||||
- ``GP9`` on Timer 2 channel B.
|
||||
- ``GP10`` on Timer 3 channel A.
|
||||
- ``GP11`` on Timer 3 channel B.
|
||||
|
||||
class TimerChannel --- setup a channel for a timer
|
||||
==================================================
|
||||
|
||||
Timer channels are used to generate/capture a signal using a timer.
|
||||
|
||||
TimerChannel objects are created using the Timer.channel() method.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: timerchannel.irq(\*, trigger, priority=1, handler=None)
|
||||
|
||||
The behavior of this callback is heavily dependent on the operating
|
||||
mode of the timer channel:
|
||||
|
||||
- If mode is ``TimerWiPy.PERIODIC`` the callback is executed periodically
|
||||
with the configured frequency or period.
|
||||
- If mode is ``TimerWiPy.ONE_SHOT`` the callback is executed once when
|
||||
the configured timer expires.
|
||||
- If mode is ``TimerWiPy.PWM`` the callback is executed when reaching the duty
|
||||
cycle value.
|
||||
|
||||
The accepted params are:
|
||||
|
||||
- ``priority`` level of the interrupt. Can take values in the range 1-7.
|
||||
Higher values represent higher priorities.
|
||||
- ``handler`` is an optional function to be called when the interrupt is triggered.
|
||||
- ``trigger`` must be ``TimerWiPy.TIMEOUT`` when the operating mode is either ``TimerWiPy.PERIODIC`` or
|
||||
``TimerWiPy.ONE_SHOT``. In the case that mode is ``TimerWiPy.PWM`` then trigger must be equal to
|
||||
``TimerWiPy.MATCH``.
|
||||
|
||||
Returns a callback object.
|
||||
|
||||
.. method:: timerchannel.freq([value])
|
||||
|
||||
Get or set the timer channel frequency (in Hz).
|
||||
|
||||
.. method:: timerchannel.period([value])
|
||||
|
||||
Get or set the timer channel period (in microseconds).
|
||||
|
||||
.. method:: timerchannel.duty_cycle([value])
|
||||
|
||||
Get or set the duty cycle of the PWM signal. It's a percentage (0.00-100.00). Since the WiPy
|
||||
doesn't support floating point numbers the duty cycle must be specified in the range 0-10000,
|
||||
where 10000 would represent 100.00, 5050 represents 50.50, and so on.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: TimerWiPy.ONE_SHOT
|
||||
.. data:: TimerWiPy.PERIODIC
|
||||
|
||||
Timer operating mode.
|
|
@ -1,152 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.UART:
|
||||
|
||||
class UART -- duplex serial communication bus
|
||||
=============================================
|
||||
|
||||
UART implements the standard UART/USART duplex serial communications protocol. At
|
||||
the physical level it consists of 2 lines: RX and TX. The unit of communication
|
||||
is a character (not to be confused with a string character) which can be 8 or 9
|
||||
bits wide.
|
||||
|
||||
UART objects can be created and initialised using::
|
||||
|
||||
from machine import UART
|
||||
|
||||
uart = UART(1, 9600) # init with given baudrate
|
||||
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
|
||||
|
||||
Supported parameters differ on a board:
|
||||
|
||||
Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With *parity=None*,
|
||||
only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits
|
||||
are supported.
|
||||
|
||||
WiPy/CC3200: Bits can be 5, 6, 7, 8. Stop can be 1 or 2.
|
||||
|
||||
A UART object acts like a `stream` object and reading and writing is done
|
||||
using the standard stream methods::
|
||||
|
||||
uart.read(10) # read 10 characters, returns a bytes object
|
||||
uart.read() # read all available characters
|
||||
uart.readline() # read a line
|
||||
uart.readinto(buf) # read and store into the given buffer
|
||||
uart.write('abc') # write the 3 characters
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: UART(id, ...)
|
||||
|
||||
Construct a UART object of the given id.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: UART.init(baudrate=9600, bits=8, parity=None, stop=1, \*, ...)
|
||||
|
||||
Initialise the UART bus with the given parameters:
|
||||
|
||||
- *baudrate* is the clock rate.
|
||||
- *bits* is the number of bits per character, 7, 8 or 9.
|
||||
- *parity* is the parity, ``None``, 0 (even) or 1 (odd).
|
||||
- *stop* is the number of stop bits, 1 or 2.
|
||||
|
||||
Additional keyword-only parameters that may be supported by a port are:
|
||||
|
||||
- *tx* specifies the TX pin to use.
|
||||
- *rx* specifies the RX pin to use.
|
||||
- *txbuf* specifies the length in characters of the TX buffer.
|
||||
- *rxbuf* specifies the length in characters of the RX buffer.
|
||||
|
||||
On the WiPy only the following keyword-only parameter is supported:
|
||||
|
||||
- *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
|
||||
Any of the pins can be None if one wants the UART to operate with limited functionality.
|
||||
If the RTS pin is given the the RX pin must be given as well. The same applies to CTS.
|
||||
When no pins are given, then the default set of TX and RX pins is taken, and hardware
|
||||
flow control will be disabled. If *pins* is ``None``, no pin assignment will be made.
|
||||
|
||||
.. method:: UART.deinit()
|
||||
|
||||
Turn off the UART bus.
|
||||
|
||||
.. method:: UART.any()
|
||||
|
||||
Returns an integer counting the number of characters that can be read without
|
||||
blocking. It will return 0 if there are no characters available and a positive
|
||||
number if there are characters. The method may return 1 even if there is more
|
||||
than one character available for reading.
|
||||
|
||||
For more sophisticated querying of available characters use select.poll::
|
||||
|
||||
poll = select.poll()
|
||||
poll.register(uart, select.POLLIN)
|
||||
poll.poll(timeout)
|
||||
|
||||
.. method:: UART.read([nbytes])
|
||||
|
||||
Read characters. 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 in. Returns ``None``
|
||||
on timeout.
|
||||
|
||||
.. method:: UART.readinto(buf[, nbytes])
|
||||
|
||||
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
|
||||
that many bytes. Otherwise, read at most ``len(buf)`` bytes.
|
||||
|
||||
Return value: number of bytes read and stored into ``buf`` or ``None`` on
|
||||
timeout.
|
||||
|
||||
.. method:: UART.readline()
|
||||
|
||||
Read a line, ending in a newline character.
|
||||
|
||||
Return value: the line read or ``None`` on timeout.
|
||||
|
||||
.. method:: UART.write(buf)
|
||||
|
||||
Write the buffer of bytes to the bus.
|
||||
|
||||
Return value: number of bytes written or ``None`` on timeout.
|
||||
|
||||
.. method:: UART.sendbreak()
|
||||
|
||||
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.
|
||||
|
||||
.. 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.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: UART.RX_ANY
|
||||
|
||||
IRQ trigger sources
|
||||
|
||||
Availability: WiPy.
|
|
@ -1,36 +0,0 @@
|
|||
.. currentmodule:: machine
|
||||
.. _machine.WDT:
|
||||
|
||||
class WDT -- watchdog timer
|
||||
===========================
|
||||
|
||||
The WDT is used to restart the system when the application crashes and ends
|
||||
up into a non recoverable state. Once started it cannot be stopped or
|
||||
reconfigured in any way. After enabling, the application must "feed" the
|
||||
watchdog periodically to prevent it from expiring and resetting the system.
|
||||
|
||||
Example usage::
|
||||
|
||||
from machine import WDT
|
||||
wdt = WDT(timeout=2000) # enable it with a timeout of 2s
|
||||
wdt.feed()
|
||||
|
||||
Availability of this class: pyboard, WiPy.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: WDT(id=0, timeout=5000)
|
||||
|
||||
Create a WDT object and start it. The timeout must be given in seconds and
|
||||
the minimum value that is accepted is 1 second. Once it is running the timeout
|
||||
cannot be changed and the WDT cannot be stopped either.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: wdt.feed()
|
||||
|
||||
Feed the WDT to prevent it from resetting the system. The application
|
||||
should place this call in a sensible place ensuring that the WDT is
|
||||
only fed after verifying that everything is functioning correctly.
|
|
@ -1,171 +0,0 @@
|
|||
:mod:`machine` --- functions related to the hardware
|
||||
====================================================
|
||||
|
||||
.. module:: machine
|
||||
:synopsis: functions related to the hardware
|
||||
|
||||
The ``machine`` module contains specific functions related to the hardware
|
||||
on a particular board. Most functions in this module allow to achieve direct
|
||||
and unrestricted access to and control of hardware blocks on a system
|
||||
(like CPU, timers, buses, etc.). Used incorrectly, this can lead to
|
||||
malfunction, lockups, crashes of your board, and in extreme cases, hardware
|
||||
damage.
|
||||
|
||||
.. _machine_callbacks:
|
||||
|
||||
A note of callbacks used by functions and class methods of :mod:`machine` module:
|
||||
all these callbacks should be considered as executing in an interrupt context.
|
||||
This is true for both physical devices with IDs >= 0 and "virtual" devices
|
||||
with negative IDs like -1 (these "virtual" devices are still thin shims on
|
||||
top of real hardware and real hardware interrupts). See :ref:`isr_rules`.
|
||||
|
||||
Reset related functions
|
||||
-----------------------
|
||||
|
||||
.. function:: reset()
|
||||
|
||||
Resets the device in a manner similar to pushing the external RESET
|
||||
button.
|
||||
|
||||
.. function:: reset_cause()
|
||||
|
||||
Get the reset cause. See :ref:`constants <machine_constants>` for the possible return values.
|
||||
|
||||
Interrupt related functions
|
||||
---------------------------
|
||||
|
||||
.. function:: disable_irq()
|
||||
|
||||
Disable interrupt requests.
|
||||
Returns the previous IRQ state which should be considered an opaque value.
|
||||
This return value should be passed to the `enable_irq()` function to restore
|
||||
interrupts to their original state, before `disable_irq()` was called.
|
||||
|
||||
.. function:: enable_irq(state)
|
||||
|
||||
Re-enable interrupt requests.
|
||||
The *state* parameter should be the value that was returned from the most
|
||||
recent call to the `disable_irq()` function.
|
||||
|
||||
Power related functions
|
||||
-----------------------
|
||||
|
||||
.. function:: freq()
|
||||
|
||||
Returns CPU frequency in hertz.
|
||||
|
||||
.. function:: idle()
|
||||
|
||||
Gates the clock to the CPU, useful to reduce power consumption at any time during
|
||||
short or long periods. Peripherals continue working and execution resumes as soon
|
||||
as any interrupt is triggered (on many ports this includes system timer
|
||||
interrupt occurring at regular intervals on the order of millisecond).
|
||||
|
||||
.. function:: sleep()
|
||||
|
||||
.. note:: This function is deprecated, use `lightsleep()` instead with no arguments.
|
||||
|
||||
.. function:: lightsleep([time_ms])
|
||||
deepsleep([time_ms])
|
||||
|
||||
Stops execution in an attempt to enter a low power state.
|
||||
|
||||
If *time_ms* is specified then this will be the maximum time in milliseconds that
|
||||
the sleep will last for. Otherwise the sleep can last indefinitely.
|
||||
|
||||
With or without a timout, execution may resume at any time if there are events
|
||||
that require processing. Such events, or wake sources, should be configured before
|
||||
sleeping, like `Pin` change or `RTC` timeout.
|
||||
|
||||
The precise behaviour and power-saving capabilities of lightsleep and deepsleep is
|
||||
highly dependent on the underlying hardware, but the general properties are:
|
||||
|
||||
* A lightsleep has full RAM and state retention. Upon wake execution is resumed
|
||||
from the point where the sleep was requested, with all subsystems operational.
|
||||
|
||||
* A deepsleep may not retain RAM or any other state of the system (for example
|
||||
peripherals or network interfaces). Upon wake execution is resumed from the main
|
||||
script, similar to a hard or power-on reset. The `reset_cause()` function will
|
||||
return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake
|
||||
from other resets.
|
||||
|
||||
.. function:: wake_reason()
|
||||
|
||||
Get the wake reason. See :ref:`constants <machine_constants>` for the possible return values.
|
||||
|
||||
Availability: ESP32, WiPy.
|
||||
|
||||
Miscellaneous functions
|
||||
-----------------------
|
||||
|
||||
.. function:: unique_id()
|
||||
|
||||
Returns a byte string with a unique identifier of a board/SoC. It will vary
|
||||
from a board/SoC instance to another, if underlying hardware allows. Length
|
||||
varies by hardware (so use substring of a full value if you expect a short
|
||||
ID). In some MicroPython ports, ID corresponds to the network MAC address.
|
||||
|
||||
.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000)
|
||||
|
||||
Time a pulse on the given *pin*, and return the duration of the pulse in
|
||||
microseconds. The *pulse_level* argument should be 0 to time a low pulse
|
||||
or 1 to time a high pulse.
|
||||
|
||||
If the current input value of the pin is different to *pulse_level*,
|
||||
the function first (*) waits until the pin input becomes equal to *pulse_level*,
|
||||
then (**) times the duration that the pin is equal to *pulse_level*.
|
||||
If the pin is already equal to *pulse_level* then timing starts straight away.
|
||||
|
||||
The function will return -2 if there was timeout waiting for condition marked
|
||||
(*) above, and -1 if there was timeout during the main measurement, marked (**)
|
||||
above. The timeout is the same for both cases and given by *timeout_us* (which
|
||||
is in microseconds).
|
||||
|
||||
.. function:: rng()
|
||||
|
||||
Return a 24-bit software generated random number.
|
||||
|
||||
Availability: WiPy.
|
||||
|
||||
.. _machine_constants:
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: machine.IDLE
|
||||
machine.SLEEP
|
||||
machine.DEEPSLEEP
|
||||
|
||||
IRQ wake values.
|
||||
|
||||
.. data:: machine.PWRON_RESET
|
||||
machine.HARD_RESET
|
||||
machine.WDT_RESET
|
||||
machine.DEEPSLEEP_RESET
|
||||
machine.SOFT_RESET
|
||||
|
||||
Reset causes.
|
||||
|
||||
.. data:: machine.WLAN_WAKE
|
||||
machine.PIN_WAKE
|
||||
machine.RTC_WAKE
|
||||
|
||||
Wake-up reasons.
|
||||
|
||||
Classes
|
||||
-------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
machine.Pin.rst
|
||||
machine.Signal.rst
|
||||
machine.ADC.rst
|
||||
machine.UART.rst
|
||||
machine.SPI.rst
|
||||
machine.I2C.rst
|
||||
machine.RTC.rst
|
||||
machine.Timer.rst
|
||||
machine.WDT.rst
|
||||
machine.SD.rst
|
||||
machine.SDCard.rst
|
|
@ -4,16 +4,11 @@
|
|||
.. module:: math
|
||||
:synopsis: mathematical functions
|
||||
|
||||
|see_cpython_module| :mod:`python:math`.
|
||||
|
||||
The ``math`` module provides some basic mathematical functions for
|
||||
The ``math`` module provides some basic mathematical funtions for
|
||||
working with floating-point numbers.
|
||||
|
||||
*Note:* On the pyboard, floating-point numbers have 32-bit precision.
|
||||
|
||||
Availability: not available on WiPy. Floating point support required
|
||||
for this module.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
|
@ -95,10 +90,7 @@ Functions
|
|||
|
||||
.. function:: frexp(x)
|
||||
|
||||
Decomposes a floating-point number into its mantissa and exponent.
|
||||
The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e``
|
||||
exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise
|
||||
the relation ``0.5 <= abs(m) < 1`` holds.
|
||||
Converts a floating-point number to fractional and integral components.
|
||||
|
||||
.. function:: gamma(x)
|
||||
|
||||
|
|
|
@ -1,140 +0,0 @@
|
|||
:mod:`micropython` -- access and control MicroPython internals
|
||||
==============================================================
|
||||
|
||||
.. module:: micropython
|
||||
:synopsis: access and control MicroPython internals
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: const(expr)
|
||||
|
||||
Used to declare that the expression is a constant so that the compile can
|
||||
optimise it. The use of this function should be as follows::
|
||||
|
||||
from micropython import const
|
||||
|
||||
CONST_X = const(123)
|
||||
CONST_Y = const(2 * CONST_X + 1)
|
||||
|
||||
Constants declared this way are still accessible as global variables from
|
||||
outside the module they are declared in. On the other hand, if a constant
|
||||
begins with an underscore then it is hidden, it is not available as a global
|
||||
variable, and does not take up any memory during execution.
|
||||
|
||||
This `const` function is recognised directly by the MicroPython parser and is
|
||||
provided as part of the :mod:`micropython` module mainly so that scripts can be
|
||||
written which run under both CPython and MicroPython, by following the above
|
||||
pattern.
|
||||
|
||||
.. function:: opt_level([level])
|
||||
|
||||
If *level* is given then this function sets the optimisation level for subsequent
|
||||
compilation of scripts, and returns ``None``. Otherwise it returns the current
|
||||
optimisation level.
|
||||
|
||||
The optimisation level controls the following compilation features:
|
||||
|
||||
- Assertions: at level 0 assertion statements are enabled and compiled into the
|
||||
bytecode; at levels 1 and higher assertions are not compiled.
|
||||
- Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``;
|
||||
at levels 1 and higher it expands to ``False``.
|
||||
- Source-code line numbers: at levels 0, 1 and 2 source-code line number are
|
||||
stored along with the bytecode so that exceptions can report the line number
|
||||
they occurred at; at levels 3 and higher line numbers are not stored.
|
||||
|
||||
The default optimisation level is usually level 0.
|
||||
|
||||
.. function:: alloc_emergency_exception_buf(size)
|
||||
|
||||
Allocate *size* bytes of RAM for the emergency exception buffer (a good
|
||||
size is around 100 bytes). The buffer is used to create exceptions in cases
|
||||
when normal RAM allocation would fail (eg within an interrupt handler) and
|
||||
therefore give useful traceback information in these situations.
|
||||
|
||||
A good way to use this function is to put it at the start of your main script
|
||||
(eg ``boot.py`` or ``main.py``) and then the emergency exception buffer will be active
|
||||
for all the code following it.
|
||||
|
||||
.. function:: mem_info([verbose])
|
||||
|
||||
Print information about currently used memory. If the *verbose* argument
|
||||
is given then extra information is printed.
|
||||
|
||||
The information that is printed is implementation dependent, but currently
|
||||
includes the amount of stack and heap used. In verbose mode it prints out
|
||||
the entire heap indicating which blocks are used and which are free.
|
||||
|
||||
.. function:: qstr_info([verbose])
|
||||
|
||||
Print information about currently interned strings. If the *verbose*
|
||||
argument is given then extra information is printed.
|
||||
|
||||
The information that is printed is implementation dependent, but currently
|
||||
includes the number of interned strings and the amount of RAM they use. In
|
||||
verbose mode it prints out the names of all RAM-interned strings.
|
||||
|
||||
.. function:: stack_use()
|
||||
|
||||
Return an integer representing the current amount of stack that is being
|
||||
used. The absolute value of this is not particularly useful, rather it
|
||||
should be used to compute differences in stack usage at different points.
|
||||
|
||||
.. function:: heap_lock()
|
||||
.. function:: heap_unlock()
|
||||
|
||||
Lock or unlock the heap. When locked no memory allocation can occur and a
|
||||
`MemoryError` will be raised if any heap allocation is attempted.
|
||||
|
||||
These functions can be nested, ie `heap_lock()` can be called multiple times
|
||||
in a row and the lock-depth will increase, and then `heap_unlock()` must be
|
||||
called the same number of times to make the heap available again.
|
||||
|
||||
If the REPL becomes active with the heap locked then it will be forcefully
|
||||
unlocked.
|
||||
|
||||
.. function:: kbd_intr(chr)
|
||||
|
||||
Set the character that will raise a `KeyboardInterrupt` exception. By
|
||||
default this is set to 3 during script execution, corresponding to Ctrl-C.
|
||||
Passing -1 to this function will disable capture of Ctrl-C, and passing 3
|
||||
will restore it.
|
||||
|
||||
This function can be used to prevent the capturing of Ctrl-C on the
|
||||
incoming stream of characters that is usually used for the REPL, in case
|
||||
that stream is used for other purposes.
|
||||
|
||||
.. function:: schedule(func, arg)
|
||||
|
||||
Schedule the function *func* to be executed "very soon". The function
|
||||
is passed the value *arg* as its single argument. "Very soon" means that
|
||||
the MicroPython runtime will do its best to execute the function at the
|
||||
earliest possible time, given that it is also trying to be efficient, and
|
||||
that the following conditions hold:
|
||||
|
||||
- A scheduled function will never preempt another scheduled function.
|
||||
- Scheduled functions are always executed "between opcodes" which means
|
||||
that all fundamental Python operations (such as appending to a list)
|
||||
are guaranteed to be atomic.
|
||||
- A given port may define "critical regions" within which scheduled
|
||||
functions will never be executed. Functions may be scheduled within
|
||||
a critical region but they will not be executed until that region
|
||||
is exited. An example of a critical region is a preempting interrupt
|
||||
handler (an IRQ).
|
||||
|
||||
A use for this function is to schedule a callback from a preempting IRQ.
|
||||
Such an IRQ puts restrictions on the code that runs in the IRQ (for example
|
||||
the heap may be locked) and scheduling a function to call later will lift
|
||||
those restrictions.
|
||||
|
||||
Note: If `schedule()` is called from a preempting IRQ, when memory
|
||||
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
|
||||
reference to a bound method causes memory allocation. A solution is to
|
||||
create a reference to the method in the class constructor and to pass that
|
||||
reference to `schedule()`. This is discussed in detail here
|
||||
:ref:`reference documentation <isr_rules>` under "Creation of Python
|
||||
objects".
|
||||
|
||||
There is a finite queue to hold the scheduled functions and `schedule()`
|
||||
will raise a `RuntimeError` if the queue is full.
|
|
@ -1,89 +0,0 @@
|
|||
.. currentmodule:: network
|
||||
.. _network.CC3K:
|
||||
|
||||
class CC3K -- control CC3000 WiFi modules
|
||||
=========================================
|
||||
|
||||
This class provides a driver for CC3000 WiFi modules. Example usage::
|
||||
|
||||
import network
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
nic.connect('your-ssid', 'your-password')
|
||||
while not nic.isconnected():
|
||||
pyb.delay(50)
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
For this example to work the CC3000 module must have the following connections:
|
||||
|
||||
- MOSI connected to Y8
|
||||
- MISO connected to Y7
|
||||
- CLK connected to Y6
|
||||
- CS connected to Y5
|
||||
- VBEN connected to Y4
|
||||
- IRQ connected to Y3
|
||||
|
||||
It is possible to use other SPI busses and other pins for CS, VBEN and IRQ.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: CC3K(spi, pin_cs, pin_en, pin_irq)
|
||||
|
||||
Create a CC3K driver object, initialise the CC3000 module using the given SPI bus
|
||||
and pins, and return the CC3K object.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- *spi* is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the CC3000 is
|
||||
connected to (the MOSI, MISO and CLK pins).
|
||||
- *pin_cs* is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 CS pin.
|
||||
- *pin_en* is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 VBEN pin.
|
||||
- *pin_irq* is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 IRQ pin.
|
||||
|
||||
All of these objects will be initialised by the driver, so there is no need to
|
||||
initialise them yourself. For example, you can use::
|
||||
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: CC3K.connect(ssid, key=None, \*, security=WPA2, bssid=None)
|
||||
|
||||
Connect to a WiFi access point using the given SSID, and other security
|
||||
parameters.
|
||||
|
||||
.. method:: CC3K.disconnect()
|
||||
|
||||
Disconnect from the WiFi access point.
|
||||
|
||||
.. method:: CC3K.isconnected()
|
||||
|
||||
Returns True if connected to a WiFi access point and has a valid IP address,
|
||||
False otherwise.
|
||||
|
||||
.. method:: CC3K.ifconfig()
|
||||
|
||||
Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server,
|
||||
MAC address, SSID).
|
||||
|
||||
.. method:: CC3K.patch_version()
|
||||
|
||||
Return the version of the patch program (firmware) on the CC3000.
|
||||
|
||||
.. method:: CC3K.patch_program('pgm')
|
||||
|
||||
Upload the current firmware to the CC3000. You must pass 'pgm' as the first
|
||||
argument in order for the upload to proceed.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: CC3K.WEP
|
||||
.. data:: CC3K.WPA
|
||||
.. data:: CC3K.WPA2
|
||||
|
||||
security type to use
|
|
@ -1,71 +0,0 @@
|
|||
.. currentmodule:: network
|
||||
.. _network.WIZNET5K:
|
||||
|
||||
class WIZNET5K -- control WIZnet5x00 Ethernet modules
|
||||
=====================================================
|
||||
|
||||
This class allows you to control WIZnet5x00 Ethernet adaptors based on
|
||||
the W5200 and W5500 chipsets. The particular chipset that is supported
|
||||
by the firmware is selected at compile-time via the MICROPY_PY_WIZNET5K
|
||||
option.
|
||||
|
||||
Example usage::
|
||||
|
||||
import network
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
For this example to work the WIZnet5x00 module must have the following connections:
|
||||
|
||||
- MOSI connected to X8
|
||||
- MISO connected to X7
|
||||
- SCLK connected to X6
|
||||
- nSS connected to X5
|
||||
- nRESET connected to X4
|
||||
|
||||
It is possible to use other SPI busses and other pins for nSS and nRESET.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: WIZNET5K(spi, pin_cs, pin_rst)
|
||||
|
||||
Create a WIZNET5K driver object, initialise the WIZnet5x00 module using the given
|
||||
SPI bus and pins, and return the WIZNET5K object.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- *spi* is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the WIZnet5x00 is
|
||||
connected to (the MOSI, MISO and SCLK pins).
|
||||
- *pin_cs* is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nSS pin.
|
||||
- *pin_rst* is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nRESET pin.
|
||||
|
||||
All of these objects will be initialised by the driver, so there is no need to
|
||||
initialise them yourself. For example, you can use::
|
||||
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. 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()
|
||||
|
||||
Dump the WIZnet5x00 registers. Useful for debugging.
|
|
@ -1,132 +0,0 @@
|
|||
.. currentmodule:: network
|
||||
.. _network.WLAN:
|
||||
|
||||
class WLAN -- control built-in WiFi interfaces
|
||||
==============================================
|
||||
|
||||
This class provides a driver for WiFi network processors. Example usage::
|
||||
|
||||
import network
|
||||
# enable station interface and connect to WiFi access point
|
||||
nic = network.WLAN(network.STA_IF)
|
||||
nic.active(True)
|
||||
nic.connect('your-ssid', 'your-password')
|
||||
# now use sockets as usual
|
||||
|
||||
Constructors
|
||||
------------
|
||||
.. class:: WLAN(interface_id)
|
||||
|
||||
Create a WLAN network interface object. Supported interfaces are
|
||||
``network.STA_IF`` (station aka client, connects to upstream WiFi access
|
||||
points) and ``network.AP_IF`` (access point, allows other WiFi clients to
|
||||
connect). Availability of the methods below depends on interface type.
|
||||
For example, only STA interface may `WLAN.connect()` to an access point.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: WLAN.active([is_active])
|
||||
|
||||
Activate ("up") or deactivate ("down") network interface, if boolean
|
||||
argument is passed. Otherwise, query current state if no argument is
|
||||
provided. Most other methods require active interface.
|
||||
|
||||
.. method:: WLAN.connect(ssid=None, password=None, \*, bssid=None)
|
||||
|
||||
Connect to the specified wireless network, using the specified password.
|
||||
If *bssid* is given then the connection will be restricted to the
|
||||
access-point with that MAC address (the *ssid* must also be specified
|
||||
in this case).
|
||||
|
||||
.. method:: WLAN.disconnect()
|
||||
|
||||
Disconnect from the currently connected wireless network.
|
||||
|
||||
.. method:: WLAN.scan()
|
||||
|
||||
Scan for the available wireless networks.
|
||||
|
||||
Scanning is only possible on STA interface. Returns list of tuples with
|
||||
the information about WiFi access points:
|
||||
|
||||
(ssid, bssid, channel, RSSI, authmode, hidden)
|
||||
|
||||
*bssid* is hardware address of an access point, in binary form, returned as
|
||||
bytes object. You can use `ubinascii.hexlify()` to convert it to ASCII form.
|
||||
|
||||
There are five values for authmode:
|
||||
|
||||
* 0 -- open
|
||||
* 1 -- WEP
|
||||
* 2 -- WPA-PSK
|
||||
* 3 -- WPA2-PSK
|
||||
* 4 -- WPA/WPA2-PSK
|
||||
|
||||
and two for hidden:
|
||||
|
||||
* 0 -- visible
|
||||
* 1 -- hidden
|
||||
|
||||
.. method:: WLAN.status([param])
|
||||
|
||||
Return the current status of the wireless connection.
|
||||
|
||||
When called with no argument the return value describes the network link status.
|
||||
The possible statuses are defined as constants:
|
||||
|
||||
* ``STAT_IDLE`` -- no connection and no activity,
|
||||
* ``STAT_CONNECTING`` -- connecting in progress,
|
||||
* ``STAT_WRONG_PASSWORD`` -- failed due to incorrect password,
|
||||
* ``STAT_NO_AP_FOUND`` -- failed because no access point replied,
|
||||
* ``STAT_CONNECT_FAIL`` -- failed due to other problems,
|
||||
* ``STAT_GOT_IP`` -- connection successful.
|
||||
|
||||
When called with one argument *param* should be a string naming the status
|
||||
parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``.
|
||||
|
||||
.. method:: WLAN.isconnected()
|
||||
|
||||
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. Returns ``False`` otherwise.
|
||||
|
||||
.. method:: WLAN.ifconfig([(ip, subnet, gateway, dns)])
|
||||
|
||||
Get/set IP-level network interface parameters: IP address, subnet mask,
|
||||
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
|
||||
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:: WLAN.config('param')
|
||||
.. method:: WLAN.config(param=value, ...)
|
||||
|
||||
Get or set general network interface parameters. These methods allow to work
|
||||
with additional parameters beyond standard IP configuration (as dealt with by
|
||||
`WLAN.ifconfig()`). These include network-specific and hardware-specific
|
||||
parameters. For setting parameters, keyword argument syntax should be used,
|
||||
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::
|
||||
|
||||
# Set WiFi access point name (formally known as ESSID) and WiFi channel
|
||||
ap.config(essid='My AP', channel=11)
|
||||
# Query params one by one
|
||||
print(ap.config('essid'))
|
||||
print(ap.config('channel'))
|
||||
|
||||
Following are commonly supported parameters (availability of a specific parameter
|
||||
depends on network technology type, driver, and `MicroPython port`).
|
||||
|
||||
============= ===========
|
||||
Parameter Description
|
||||
============= ===========
|
||||
mac MAC address (bytes)
|
||||
essid WiFi access point name (string)
|
||||
channel WiFi channel (integer)
|
||||
hidden Whether ESSID is hidden (boolean)
|
||||
authmode Authentication mode supported (enumeration, see module constants)
|
||||
password Access password (string)
|
||||
dhcp_hostname The DHCP hostname to use
|
||||
============= ===========
|
|
@ -1,161 +0,0 @@
|
|||
.. currentmodule:: network
|
||||
.. _network.WLANWiPy:
|
||||
|
||||
class WLANWiPy -- WiPy specific WiFi control
|
||||
============================================
|
||||
|
||||
.. note::
|
||||
|
||||
This class is a non-standard WLAN implementation for the WiPy.
|
||||
It is available simply as ``network.WLAN`` on the WiPy but is named in the
|
||||
documentation below as ``network.WLANWiPy`` to distinguish it from the
|
||||
more general :ref:`network.WLAN <network.WLAN>` class.
|
||||
|
||||
This class provides a driver for the WiFi network processor in the WiPy. Example usage::
|
||||
|
||||
import network
|
||||
import time
|
||||
# setup as a station
|
||||
wlan = network.WLAN(mode=WLAN.STA)
|
||||
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
|
||||
while not wlan.isconnected():
|
||||
time.sleep_ms(50)
|
||||
print(wlan.ifconfig())
|
||||
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: WLANWiPy(id=0, ...)
|
||||
|
||||
Create a WLAN object, and optionally configure it. See `init()` for params of configuration.
|
||||
|
||||
.. note::
|
||||
|
||||
The ``WLAN`` constructor is special in the sense that if no arguments besides the id are given,
|
||||
it will return the already existing ``WLAN`` instance without re-configuring it. This is
|
||||
because ``WLAN`` is a system feature of the WiPy. If the already existing instance is not
|
||||
initialized it will do the same as the other constructors an will initialize it with default
|
||||
values.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: WLANWiPy.init(mode, \*, ssid, auth, channel, antenna)
|
||||
|
||||
Set or get the WiFi network processor configuration.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- *mode* can be either ``WLAN.STA`` or ``WLAN.AP``.
|
||||
- *ssid* is a string with the ssid name. Only needed when mode is ``WLAN.AP``.
|
||||
- *auth* is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``,
|
||||
``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password.
|
||||
If ``sec`` is ``WLAN.WEP`` the key must be a string representing hexadecimal
|
||||
values (e.g. 'ABC1DE45BF'). Only needed when mode is ``WLAN.AP``.
|
||||
- *channel* a number in the range 1-11. Only needed when mode is ``WLAN.AP``.
|
||||
- *antenna* selects between the internal and the external antenna. Can be either
|
||||
``WLAN.INT_ANT`` or ``WLAN.EXT_ANT``.
|
||||
|
||||
For example, you can do::
|
||||
|
||||
# create and configure as an access point
|
||||
wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channel=7, antenna=WLAN.INT_ANT)
|
||||
|
||||
or::
|
||||
|
||||
# configure as an station
|
||||
wlan.init(mode=WLAN.STA)
|
||||
|
||||
.. method:: WLANWiPy.connect(ssid, \*, auth=None, bssid=None, timeout=None)
|
||||
|
||||
Connect to a WiFi access point using the given SSID, and other security
|
||||
parameters.
|
||||
|
||||
- *auth* is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``,
|
||||
``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password.
|
||||
If ``sec`` is ``WLAN.WEP`` the key must be a string representing hexadecimal
|
||||
values (e.g. 'ABC1DE45BF').
|
||||
- *bssid* is the MAC address of the AP to connect to. Useful when there are several
|
||||
APs with the same ssid.
|
||||
- *timeout* is the maximum time in milliseconds to wait for the connection to succeed.
|
||||
|
||||
.. method:: WLANWiPy.scan()
|
||||
|
||||
Performs a network scan and returns a list of named tuples with (ssid, bssid, sec, channel, rssi).
|
||||
Note that channel is always ``None`` since this info is not provided by the WiPy.
|
||||
|
||||
.. method:: WLANWiPy.disconnect()
|
||||
|
||||
Disconnect from the WiFi access point.
|
||||
|
||||
.. method:: WLANWiPy.isconnected()
|
||||
|
||||
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.
|
||||
|
||||
.. method:: WLANWiPy.ifconfig(if_id=0, config=['dhcp' or configtuple])
|
||||
|
||||
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])
|
||||
|
||||
Get or set the WLAN mode.
|
||||
|
||||
.. method:: WLANWiPy.ssid([ssid])
|
||||
|
||||
Get or set the SSID when in AP mode.
|
||||
|
||||
.. method:: WLANWiPy.auth([auth])
|
||||
|
||||
Get or set the authentication type when in AP mode.
|
||||
|
||||
.. method:: WLANWiPy.channel([channel])
|
||||
|
||||
Get or set the channel (only applicable in AP mode).
|
||||
|
||||
.. method:: WLANWiPy.antenna([antenna])
|
||||
|
||||
Get or set the antenna type (external or internal).
|
||||
|
||||
.. method:: WLANWiPy.mac([mac_addr])
|
||||
|
||||
Get or set a 6-byte long bytes object with the MAC address.
|
||||
|
||||
.. method:: WLANWiPy.irq(\*, handler, wake)
|
||||
|
||||
Create a callback to be triggered when a WLAN event occurs during ``machine.SLEEP``
|
||||
mode. Events are triggered by socket activity or by WLAN connection/disconnection.
|
||||
|
||||
- *handler* is the function that gets called when the IRQ is triggered.
|
||||
- *wake* must be ``machine.SLEEP``.
|
||||
|
||||
Returns an IRQ object.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: WLANWiPy.STA
|
||||
.. data:: WLANWiPy.AP
|
||||
|
||||
selects the WLAN mode
|
||||
|
||||
.. data:: WLANWiPy.WEP
|
||||
.. data:: WLANWiPy.WPA
|
||||
.. data:: WLANWiPy.WPA2
|
||||
|
||||
selects the network security
|
||||
|
||||
.. data:: WLANWiPy.INT_ANT
|
||||
.. data:: WLANWiPy.EXT_ANT
|
||||
|
||||
selects the antenna type
|
|
@ -5,29 +5,21 @@
|
|||
.. module:: network
|
||||
:synopsis: network configuration
|
||||
|
||||
This module provides network drivers and routing configuration. To use this
|
||||
module, a MicroPython variant/build with network capabilities must be installed.
|
||||
Network drivers for specific hardware are available within this module and are
|
||||
used to configure hardware network interface(s). Network services provided
|
||||
by configured interfaces are then available for use via the :mod:`usocket`
|
||||
module.
|
||||
This module provides network drivers and routing configuration. Network
|
||||
drivers for specific hardware are available within this module and are
|
||||
used to configure a hardware network interface. Configured interfaces
|
||||
are then available for use via the :mod:`socket` module.
|
||||
|
||||
For example::
|
||||
|
||||
# connect/ show IP config a specific network interface
|
||||
# configure a specific network interface
|
||||
# see below for examples of specific drivers
|
||||
import network
|
||||
import utime
|
||||
nic = network.Driver(...)
|
||||
if not nic.isconnected():
|
||||
nic.connect()
|
||||
print("Waiting for connection...")
|
||||
while not nic.isconnected():
|
||||
utime.sleep(1)
|
||||
print(nic.ifconfig())
|
||||
|
||||
# now use usocket as usual
|
||||
import usocket as socket
|
||||
# now use socket as usual
|
||||
import socket
|
||||
addr = socket.getaddrinfo('micropython.org', 80)[0][-1]
|
||||
s = socket.socket()
|
||||
s.connect(addr)
|
||||
|
@ -35,139 +27,151 @@ For example::
|
|||
data = s.recv(1000)
|
||||
s.close()
|
||||
|
||||
Common network adapter interface
|
||||
================================
|
||||
class CC3K
|
||||
==========
|
||||
|
||||
This section describes an (implied) abstract base class for all network
|
||||
interface classes implemented by `MicroPython ports <MicroPython port>`
|
||||
for different hardware. This means that MicroPython does not actually
|
||||
provide ``AbstractNIC`` class, but any actual NIC class, as described
|
||||
in the following sections, implements methods as described here.
|
||||
This class provides a driver for CC3000 wifi modules. Example usage::
|
||||
|
||||
.. class:: AbstractNIC(id=None, ...)
|
||||
import network
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
nic.connect('your-ssid', 'your-password')
|
||||
while not nic.isconnected():
|
||||
pyb.delay(50)
|
||||
print(nic.ifconfig())
|
||||
|
||||
Instantiate a network interface object. Parameters are network interface
|
||||
dependent. If there are more than one interface of the same type, the first
|
||||
parameter should be `id`.
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
.. method:: AbstractNIC.active([is_active])
|
||||
For this example to work the CC3000 module must have the following connections:
|
||||
|
||||
Activate ("up") or deactivate ("down") the network interface, if
|
||||
a boolean argument is passed. Otherwise, query current state if
|
||||
no argument is provided. Most other methods require an active
|
||||
interface (behavior of calling them on inactive interface is
|
||||
undefined).
|
||||
- MOSI connected to Y8
|
||||
- MISO connected to Y7
|
||||
- CLK connected to Y6
|
||||
- CS connected to Y5
|
||||
- VBEN connected to Y4
|
||||
- IRQ connected to Y3
|
||||
|
||||
.. method:: AbstractNIC.connect([service_id, key=None, \*, ...])
|
||||
It is possible to use other SPI busses and other pins for CS, VBEN and IRQ.
|
||||
|
||||
Connect the interface to a network. This method is optional, and
|
||||
available only for interfaces which are not "always connected".
|
||||
If no parameters are given, connect to the default (or the only)
|
||||
service. If a single parameter is given, it is the primary identifier
|
||||
of a service to connect to. It may be accompanied by a key
|
||||
(password) required to access said service. There can be further
|
||||
arbitrary keyword-only parameters, depending on the networking medium
|
||||
type and/or particular device. Parameters can be used to: a)
|
||||
specify alternative service identifier types; b) provide additional
|
||||
connection parameters. For various medium types, there are different
|
||||
sets of predefined/recommended parameters, among them:
|
||||
Constructors
|
||||
------------
|
||||
|
||||
* WiFi: *bssid* keyword to connect to a specific BSSID (MAC address)
|
||||
.. class:: CC3K(spi, pin_cs, pin_en, pin_irq)
|
||||
|
||||
.. method:: AbstractNIC.disconnect()
|
||||
Create a CC3K driver object, initialise the CC3000 module using the given SPI bus
|
||||
and pins, and return the CC3K object.
|
||||
|
||||
Disconnect from network.
|
||||
Arguments are:
|
||||
|
||||
.. method:: AbstractNIC.isconnected()
|
||||
- ``spi`` is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the CC3000 is
|
||||
connected to (the MOSI, MISO and CLK pins).
|
||||
- ``pin_cs`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 CS pin.
|
||||
- ``pin_en`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 VBEN pin.
|
||||
- ``pin_irq`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 IRQ pin.
|
||||
|
||||
Returns ``True`` if connected to network, otherwise returns ``False``.
|
||||
All of these objects will be initialised by the driver, so there is no need to
|
||||
initialise them yourself. For example, you can use::
|
||||
|
||||
.. method:: AbstractNIC.scan(\*, ...)
|
||||
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
|
||||
|
||||
Scan for the available network services/connections. Returns a
|
||||
list of tuples with discovered service parameters. For various
|
||||
network media, there are different variants of predefined/
|
||||
recommended tuple formats, among them:
|
||||
Methods
|
||||
-------
|
||||
|
||||
* WiFi: (ssid, bssid, channel, RSSI, authmode, hidden). There
|
||||
may be further fields, specific to a particular device.
|
||||
.. method:: cc3k.connect(ssid, key=None, \*, security=WPA2, bssid=None)
|
||||
|
||||
The function may accept additional keyword arguments to filter scan
|
||||
results (e.g. scan for a particular service, on a particular channel,
|
||||
for services of a particular set, etc.), and to affect scan
|
||||
duration and other parameters. Where possible, parameter names
|
||||
should match those in connect().
|
||||
Connect to a wifi access point using the given SSID, and other security
|
||||
parameters.
|
||||
|
||||
.. method:: AbstractNIC.status([param])
|
||||
.. method:: cc3k.disconnect()
|
||||
|
||||
Query dynamic status information of the interface. When called with no
|
||||
argument the return value describes the network link status. Otherwise
|
||||
*param* should be a string naming the particular status parameter to
|
||||
retrieve.
|
||||
Disconnect from the wifi access point.
|
||||
|
||||
The return types and values are dependent on the network
|
||||
medium/technology. Some of the parameters that may be supported are:
|
||||
.. method:: cc3k.isconnected()
|
||||
|
||||
* WiFi STA: use ``'rssi'`` to retrieve the RSSI of the AP signal
|
||||
* WiFi AP: use ``'stations'`` to retrieve a list of all the STAs
|
||||
connected to the AP. The list contains tuples of the form
|
||||
(MAC, RSSI).
|
||||
Returns True if connected to a wifi access point and has a valid IP address,
|
||||
False otherwise.
|
||||
|
||||
.. method:: AbstractNIC.ifconfig([(ip, subnet, gateway, dns)])
|
||||
.. method:: cc3k.ifconfig()
|
||||
|
||||
Get/set IP-level network interface parameters: IP address, subnet mask,
|
||||
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
|
||||
4-tuple with the required information. For example::
|
||||
Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server,
|
||||
MAC address, SSID).
|
||||
|
||||
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
|
||||
.. method:: cc3k.patch_version()
|
||||
|
||||
.. method:: AbstractNIC.config('param')
|
||||
AbstractNIC.config(param=value, ...)
|
||||
Return the version of the patch program (firmware) on the CC3000.
|
||||
|
||||
Get or set general network interface parameters. These methods allow to work
|
||||
with additional parameters beyond standard IP configuration (as dealt with by
|
||||
`ifconfig()`). These include network-specific and hardware-specific
|
||||
parameters. For setting parameters, the keyword argument
|
||||
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
|
||||
parameter can be queried at a time::
|
||||
.. method:: cc3k.patch_program('pgm')
|
||||
|
||||
# Set WiFi access point name (formally known as ESSID) and WiFi channel
|
||||
ap.config(essid='My AP', channel=11)
|
||||
# Query params one by one
|
||||
print(ap.config('essid'))
|
||||
print(ap.config('channel'))
|
||||
Upload the current firmware to the CC3000. You must pass 'pgm' as the first
|
||||
argument in order for the upload to proceed.
|
||||
|
||||
Specific network class implementations
|
||||
======================================
|
||||
Constants
|
||||
---------
|
||||
|
||||
The following concrete classes implement the AbstractNIC interface and
|
||||
provide a way to control networking interfaces of various kinds.
|
||||
.. data:: CC3K.WEP
|
||||
.. data:: CC3K.WPA
|
||||
.. data:: CC3K.WPA2
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
security type to use
|
||||
|
||||
network.WLAN.rst
|
||||
network.WLANWiPy.rst
|
||||
network.CC3K.rst
|
||||
network.WIZNET5K.rst
|
||||
class WIZNET5K
|
||||
==============
|
||||
|
||||
Network functions
|
||||
=================
|
||||
This class allows you to control WIZnet5x00 Ethernet adaptors based on
|
||||
the W5200 and W5500 chipsets (only W5200 tested).
|
||||
|
||||
The following are functions available in the network module.
|
||||
Example usage::
|
||||
|
||||
.. function:: phy_mode([mode])
|
||||
import network
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
print(nic.ifconfig())
|
||||
|
||||
Get or set the PHY mode.
|
||||
# now use socket as usual
|
||||
...
|
||||
|
||||
If the *mode* parameter is provided, sets the mode to its value. If
|
||||
the function is called without parameters, returns the current mode.
|
||||
For this example to work the WIZnet5x00 module must have the following connections:
|
||||
|
||||
The possible modes are defined as constants:
|
||||
* ``MODE_11B`` -- IEEE 802.11b,
|
||||
* ``MODE_11G`` -- IEEE 802.11g,
|
||||
* ``MODE_11N`` -- IEEE 802.11n.
|
||||
- MOSI connected to X8
|
||||
- MISO connected to X7
|
||||
- SCLK connected to X6
|
||||
- nSS connected to X5
|
||||
- nRESET connected to X4
|
||||
|
||||
Availability: ESP8266.
|
||||
It is possible to use other SPI busses and other pins for nSS and nRESET.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: WIZNET5K(spi, pin_cs, pin_rst)
|
||||
|
||||
Create a WIZNET5K driver object, initialise the WIZnet5x00 module using the given
|
||||
SPI bus and pins, and return the WIZNET5K object.
|
||||
|
||||
Arguments are:
|
||||
|
||||
- ``spi`` is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the WIZnet5x00 is
|
||||
connected to (the MOSI, MISO and SCLK pins).
|
||||
- ``pin_cs`` is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nSS pin.
|
||||
- ``pin_rst`` is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nRESET pin.
|
||||
|
||||
All of these objects will be initialised by the driver, so there is no need to
|
||||
initialise them yourself. For example, you can use::
|
||||
|
||||
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. 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()
|
||||
|
||||
Dump the WIZnet5x00 registers. Useful for debugging.
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
:mod:`os` -- basic "operating system" services
|
||||
==============================================
|
||||
|
||||
.. module:: os
|
||||
:synopsis: basic "operating system" services
|
||||
|
||||
The ``os`` module contains functions for filesystem access and ``urandom``.
|
||||
|
||||
Pyboard specifics
|
||||
-----------------
|
||||
|
||||
The filesystem on the pyboard has ``/`` as the root directory and the
|
||||
available physical drives are accessible from here. They are currently:
|
||||
|
||||
``/flash`` -- the internal flash filesystem
|
||||
|
||||
``/sd`` -- the SD card (if it exists)
|
||||
|
||||
On boot up, the current directory is ``/flash`` if no SD card is inserted,
|
||||
otherwise it is ``/sd``.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: chdir(path)
|
||||
|
||||
Change current directory.
|
||||
|
||||
.. function:: getcwd()
|
||||
|
||||
Get the current directory.
|
||||
|
||||
.. function:: listdir([dir])
|
||||
|
||||
With no argument, list the current directory. Otherwise list the given directory.
|
||||
|
||||
.. function:: mkdir(path)
|
||||
|
||||
Create a new directory.
|
||||
|
||||
.. function:: remove(path)
|
||||
|
||||
Remove a file.
|
||||
|
||||
.. function:: rmdir(path)
|
||||
|
||||
Remove a directory.
|
||||
|
||||
.. function:: stat(path)
|
||||
|
||||
Get the status of a file or directory.
|
||||
|
||||
.. function:: sync()
|
||||
|
||||
Sync all filesystems.
|
||||
|
||||
.. function:: urandom(n)
|
||||
|
||||
Return a bytes object with n random bytes, generated by the hardware
|
||||
random number generator.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: sep
|
||||
|
||||
separation character used in paths
|
|
@ -1,23 +1,20 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.ADC:
|
||||
|
||||
class ADC -- analog to digital conversion
|
||||
=========================================
|
||||
class ADC -- analog to digital conversion: read analog values on a pin
|
||||
======================================================================
|
||||
|
||||
Usage::
|
||||
|
||||
import pyb
|
||||
|
||||
adc = pyb.ADC(pin) # create an analog object from a pin
|
||||
val = adc.read() # read an analog value
|
||||
adc = pyb.ADC(pin) # create an analog object from a pin
|
||||
val = adc.read() # read an analog value
|
||||
|
||||
adc = pyb.ADCAll(resolution) # create an ADCAll object
|
||||
adc = pyb.ADCAll(resolution, mask) # create an ADCAll object for selected analog channels
|
||||
val = adc.read_channel(channel) # read the given channel
|
||||
val = adc.read_core_temp() # read MCU temperature
|
||||
val = adc.read_core_vbat() # read MCU VBAT
|
||||
val = adc.read_core_vref() # read MCU VREF
|
||||
val = adc.read_vref() # read MCU supply voltage
|
||||
adc = pyb.ADCAll(resolution) # creale an ADCAll object
|
||||
val = adc.read_channel(channel) # read the given channel
|
||||
val = adc.read_core_temp() # read MCU temperature
|
||||
val = adc.read_core_vbat() # read MCU VBAT
|
||||
val = adc.read_core_vref() # read MCU VREF
|
||||
|
||||
|
||||
Constructors
|
||||
|
@ -28,140 +25,28 @@ Constructors
|
|||
Create an ADC object associated with the given pin.
|
||||
This allows you to then read analog values on that pin.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: ADC.read()
|
||||
.. method:: adc.read()
|
||||
|
||||
Read the value on the analog pin and return it. The returned value
|
||||
will be between 0 and 4095.
|
||||
|
||||
.. method:: ADC.read_timed(buf, timer)
|
||||
|
||||
Read analog values into ``buf`` at a rate set by the ``timer`` object.
|
||||
|
||||
``buf`` can be bytearray or array.array for example. The ADC values have
|
||||
12-bit resolution and are stored directly into ``buf`` if its element size is
|
||||
16 bits or greater. If ``buf`` has only 8-bit elements (eg a bytearray) then
|
||||
the sample resolution will be reduced to 8 bits.
|
||||
|
||||
``timer`` should be a Timer object, and a sample is read each time the timer
|
||||
triggers. The timer must already be initialised and running at the desired
|
||||
sampling frequency.
|
||||
|
||||
To support previous behaviour of this function, ``timer`` can also be an
|
||||
integer which specifies the frequency (in Hz) to sample at. In this case
|
||||
Timer(6) will be automatically configured to run at the given frequency.
|
||||
|
||||
Example using a Timer object (preferred way)::
|
||||
|
||||
adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
|
||||
tim = pyb.Timer(6, freq=10) # create a timer running at 10Hz
|
||||
buf = bytearray(100) # creat a buffer to store the samples
|
||||
adc.read_timed(buf, tim) # sample 100 values, taking 10s
|
||||
|
||||
Example using an integer for the frequency::
|
||||
.. method:: adc.read_timed(buf, freq)
|
||||
|
||||
Read analog values into the given buffer at the given frequency. Buffer
|
||||
can be bytearray or array.array for example. If a buffer with 8-bit elements
|
||||
is used, sample resolution will be reduced to 8 bits.
|
||||
|
||||
Example::
|
||||
|
||||
adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
|
||||
buf = bytearray(100) # create a buffer of 100 bytes
|
||||
adc.read_timed(buf, 10) # read analog values into buf at 10Hz
|
||||
# this will take 10 seconds to finish
|
||||
for val in buf: # loop over all values
|
||||
print(val) # print the value out
|
||||
|
||||
This function does not allocate any heap memory. It has blocking behaviour:
|
||||
it does not return to the calling program until the buffer is full.
|
||||
|
||||
.. method:: ADC.read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer)
|
||||
|
||||
This is a static method. It can be used to extract relative timing or
|
||||
phase data from multiple ADC's.
|
||||
|
||||
It reads analog values from multiple ADC's into buffers at a rate set by
|
||||
the *timer* object. Each time the timer triggers a sample is rapidly
|
||||
read from each ADC in turn.
|
||||
|
||||
ADC and buffer instances are passed in tuples with each ADC having an
|
||||
associated buffer. All buffers must be of the same type and length and
|
||||
the number of buffers must equal the number of ADC's.
|
||||
|
||||
Buffers can be ``bytearray`` or ``array.array`` for example. The ADC values
|
||||
have 12-bit resolution and are stored directly into the buffer if its element
|
||||
size is 16 bits or greater. If buffers have only 8-bit elements (eg a
|
||||
``bytearray``) then the sample resolution will be reduced to 8 bits.
|
||||
|
||||
*timer* must be a Timer object. The timer must already be initialised
|
||||
and running at the desired sampling frequency.
|
||||
|
||||
Example reading 3 ADC's::
|
||||
|
||||
adc0 = pyb.ADC(pyb.Pin.board.X1) # Create ADC's
|
||||
adc1 = pyb.ADC(pyb.Pin.board.X2)
|
||||
adc2 = pyb.ADC(pyb.Pin.board.X3)
|
||||
tim = pyb.Timer(8, freq=100) # Create timer
|
||||
rx0 = array.array('H', (0 for i in range(100))) # ADC buffers of
|
||||
rx1 = array.array('H', (0 for i in range(100))) # 100 16-bit words
|
||||
rx2 = array.array('H', (0 for i in range(100)))
|
||||
# read analog values into buffers at 100Hz (takes one second)
|
||||
pyb.ADC.read_timed_multi((adc0, adc1, adc2), (rx0, rx1, rx2), tim)
|
||||
for n in range(len(rx0)):
|
||||
print(rx0[n], rx1[n], rx2[n])
|
||||
|
||||
This function does not allocate any heap memory. It has blocking behaviour:
|
||||
it does not return to the calling program until the buffers are full.
|
||||
|
||||
The function returns ``True`` if all samples were acquired with correct
|
||||
timing. At high sample rates the time taken to acquire a set of samples
|
||||
can exceed the timer period. In this case the function returns ``False``,
|
||||
indicating a loss of precision in the sample interval. In extreme cases
|
||||
samples may be missed.
|
||||
|
||||
The maximum rate depends on factors including the data width and the
|
||||
number of ADC's being read. In testing two ADC's were sampled at a timer
|
||||
rate of 210kHz without overrun. Samples were missed at 215kHz. For three
|
||||
ADC's the limit is around 140kHz, and for four it is around 110kHz.
|
||||
At high sample rates disabling interrupts for the duration can reduce the
|
||||
risk of sporadic data loss.
|
||||
|
||||
The ADCAll Object
|
||||
-----------------
|
||||
|
||||
Instantiating this changes all masked ADC pins to analog inputs. The preprocessed MCU temperature,
|
||||
VREF and VBAT data can be accessed on ADC channels 16, 17 and 18 respectively.
|
||||
Appropriate scaling is handled according to reference voltage used (usually 3.3V).
|
||||
The temperature sensor on the chip is factory calibrated and allows to read the die temperature
|
||||
to +/- 1 degree centigrade. Although this sounds pretty accurate, don't forget that the MCU's internal
|
||||
temperature is measured. Depending on processing loads and I/O subsystems active the die temperature
|
||||
may easily be tens of degrees above ambient temperature. On the other hand a pyboard woken up after a
|
||||
long standby period will show correct ambient temperature within limits mentioned above.
|
||||
|
||||
The ``ADCAll`` ``read_core_vbat()``, ``read_vref()`` and ``read_core_vref()`` methods read
|
||||
the backup battery voltage, reference voltage and the (1.21V nominal) reference voltage using the
|
||||
actual supply as a reference. All results are floating point numbers giving direct voltage values.
|
||||
|
||||
``read_core_vbat()`` returns the voltage of the backup battery. This voltage is also adjusted according
|
||||
to the actual supply voltage. To avoid analog input overload the battery voltage is measured
|
||||
via a voltage divider and scaled according to the divider value. To prevent excessive loads
|
||||
to the backup battery, the voltage divider is only active during ADC conversion.
|
||||
|
||||
``read_vref()`` is evaluated by measuring the internal voltage reference and backscale it using
|
||||
factory calibration value of the internal voltage reference. In most cases the reading would be close
|
||||
to 3.3V. If the pyboard is operated from a battery, the supply voltage may drop to values below 3.3V.
|
||||
The pyboard will still operate fine as long as the operating conditions are met. With proper settings
|
||||
of MCU clock, flash access speed and programming mode it is possible to run the pyboard down to
|
||||
2 V and still get useful ADC conversion.
|
||||
|
||||
It is very important to make sure analog input voltages never exceed actual supply voltage.
|
||||
|
||||
Other analog input channels (0..15) will return unscaled integer values according to the selected
|
||||
precision.
|
||||
|
||||
To avoid unwanted activation of analog inputs (channel 0..15) a second parameter can be specified.
|
||||
This parameter is a binary pattern where each requested analog input has the corresponding bit set.
|
||||
The default value is 0xffffffff which means all analog inputs are active. If just the internal
|
||||
channels (16..18) are required, the mask value should be 0x70000.
|
||||
|
||||
Example::
|
||||
|
||||
adcall = pyb.ADCAll(12, 0x70000) # 12 bit resolution, internal channels
|
||||
temp = adcall.read_core_temp()
|
||||
|
||||
This function does not allocate any memory.
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Accel:
|
||||
|
||||
class Accel -- accelerometer control
|
||||
====================================
|
||||
|
||||
|
@ -19,39 +16,36 @@ Constructors
|
|||
.. class:: pyb.Accel()
|
||||
|
||||
Create and return an accelerometer object.
|
||||
|
||||
Note: if you read accelerometer values immediately after creating this object
|
||||
you will get 0. It takes around 20ms for the first sample to be ready, so,
|
||||
unless you have some other code between creating this object and reading its
|
||||
values, you should put a ``pyb.delay(20)`` after creating it. For example::
|
||||
|
||||
accel = pyb.Accel()
|
||||
pyb.delay(20)
|
||||
print(accel.x())
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Accel.filtered_xyz()
|
||||
.. method:: accel.filtered_xyz()
|
||||
|
||||
Get a 3-tuple of filtered x, y and z values.
|
||||
|
||||
Implementation note: this method is currently implemented as taking the
|
||||
sum of 4 samples, sampled from the 3 previous calls to this function along
|
||||
with the sample from the current call. Returned values are therefore 4
|
||||
times the size of what they would be from the raw x(), y() and z() calls.
|
||||
|
||||
.. method:: Accel.tilt()
|
||||
.. method:: accel.tilt()
|
||||
|
||||
Get the tilt register.
|
||||
|
||||
.. method:: Accel.x()
|
||||
.. method:: accel.x()
|
||||
|
||||
Get the x-axis value.
|
||||
|
||||
.. method:: Accel.y()
|
||||
.. method:: accel.y()
|
||||
|
||||
Get the y-axis value.
|
||||
|
||||
.. method:: Accel.z()
|
||||
.. method:: accel.z()
|
||||
|
||||
Get the z-axis value.
|
||||
|
||||
Hardware Note
|
||||
-------------
|
||||
|
||||
The accelerometer uses I2C bus 1 to communicate with the processor. Consequently
|
||||
when readings are being taken pins X9 and X10 should be unused (other than for
|
||||
I2C). Other devices using those pins, and which therefore cannot be used
|
||||
concurrently, are UART 1 and Timer 4 channels 1 and 2.
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.CAN:
|
||||
|
||||
class CAN -- controller area network communication bus
|
||||
======================================================
|
||||
|
||||
|
@ -24,49 +21,46 @@ Constructors
|
|||
|
||||
.. class:: pyb.CAN(bus, ...)
|
||||
|
||||
Construct a CAN object on the given bus. *bus* can be 1-2, or ``'YA'`` or ``'YB'``.
|
||||
Construct a CAN object on the given bus. ``bus`` can be 1-2, or 'YA' or 'YB'.
|
||||
With no additional parameters, the CAN object is created but not
|
||||
initialised (it has the settings from the last initialisation of
|
||||
the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
See :meth:`CAN.init` for parameters of initialisation.
|
||||
|
||||
See ``init`` for parameters of initialisation.
|
||||
|
||||
The physical pins of the CAN busses are:
|
||||
|
||||
|
||||
- ``CAN(1)`` is on ``YA``: ``(RX, TX) = (Y3, Y4) = (PB8, PB9)``
|
||||
- ``CAN(2)`` is on ``YB``: ``(RX, TX) = (Y5, Y6) = (PB12, PB13)``
|
||||
|
||||
Class Methods
|
||||
-------------
|
||||
.. classmethod:: CAN.initfilterbanks(nr)
|
||||
|
||||
.. method:: CAN.initfilterbanks(nr)
|
||||
|
||||
Reset and disable all filter banks and assign how many banks should be available for CAN(1).
|
||||
|
||||
|
||||
STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers.
|
||||
This function configures how many filter banks should be assigned to each. *nr* is the number of banks
|
||||
that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2).
|
||||
This function configures how many filter banks should be assigned to each. ``nr`` is the number of banks
|
||||
that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2).
|
||||
At boot, 14 banks are assigned to each controller.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: CAN.init(mode, extframe=False, prescaler=100, \*, sjw=1, bs1=6, bs2=8, auto_restart=False)
|
||||
.. method:: can.init(mode, extframe=False, prescaler=100, \*, sjw=1, bs1=6, bs2=8)
|
||||
|
||||
Initialise the CAN bus with the given parameters:
|
||||
|
||||
- *mode* is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
|
||||
- if *extframe* is True then the bus uses extended identifiers in the frames
|
||||
|
||||
- ``mode`` is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
|
||||
- if ``extframe`` is True then the bus uses extended identifiers in the frames
|
||||
(29 bits); otherwise it uses standard 11 bit identifiers
|
||||
- *prescaler* is used to set the duration of 1 time quanta; the time quanta
|
||||
- ``prescaler`` is used to set the duration of 1 time quanta; the time quanta
|
||||
will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler
|
||||
- *sjw* is the resynchronisation jump width in units of the time quanta;
|
||||
- ``sjw`` is the resynchronisation jump width in units of the time quanta;
|
||||
it can be 1, 2, 3, 4
|
||||
- *bs1* defines the location of the sample point in units of the time quanta;
|
||||
- ``bs1`` defines the location of the sample point in units of the time quanta;
|
||||
it can be between 1 and 1024 inclusive
|
||||
- *bs2* defines the location of the transmit point in units of the time quanta;
|
||||
- ``bs2`` defines the location of the transmit point in units of the time quanta;
|
||||
it can be between 1 and 16 inclusive
|
||||
- *auto_restart* sets whether the controller will automatically try and restart
|
||||
communications after entering the bus-off state; if this is disabled then
|
||||
:meth:`~CAN.restart()` can be used to leave the bus-off state
|
||||
|
||||
The time quanta tq is the basic unit of time for the CAN bus. tq is the CAN
|
||||
prescaler value divided by PCLK1 (the frequency of internal peripheral bus 1);
|
||||
|
@ -84,68 +78,21 @@ Methods
|
|||
|
||||
See page 680 of the STM32F405 datasheet for more details.
|
||||
|
||||
.. method:: CAN.deinit()
|
||||
.. method:: can.deinit()
|
||||
|
||||
Turn off the CAN bus.
|
||||
|
||||
.. method:: CAN.restart()
|
||||
|
||||
Force a software restart of the CAN controller without resetting its
|
||||
configuration.
|
||||
|
||||
If the controller enters the bus-off state then it will no longer participate
|
||||
in bus activity. If the controller is not configured to automatically restart
|
||||
(see :meth:`~CAN.init()`) then this method can be used to trigger a restart,
|
||||
and the controller will follow the CAN protocol to leave the bus-off state and
|
||||
go into the error active state.
|
||||
|
||||
.. method:: CAN.state()
|
||||
|
||||
Return the state of the controller. The return value can be one of:
|
||||
|
||||
- ``CAN.STOPPED`` -- the controller is completely off and reset;
|
||||
- ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state
|
||||
(both TEC and REC are less than 96);
|
||||
- ``CAN.ERROR_WARNING`` -- the controller is on and in the Error Warning state
|
||||
(at least one of TEC or REC is 96 or greater);
|
||||
- ``CAN.ERROR_PASSIVE`` -- the controller is on and in the Error Passive state
|
||||
(at least one of TEC or REC is 128 or greater);
|
||||
- ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity
|
||||
(TEC overflowed beyond 255).
|
||||
|
||||
.. method:: CAN.info([list])
|
||||
|
||||
Get information about the controller's error states and TX and RX buffers.
|
||||
If *list* is provided then it should be a list object with at least 8 entries,
|
||||
which will be filled in with the information. Otherwise a new list will be
|
||||
created and filled in. In both cases the return value of the method is the
|
||||
populated list.
|
||||
|
||||
The values in the list are:
|
||||
|
||||
- TEC value
|
||||
- REC value
|
||||
- number of times the controller enterted the Error Warning state (wrapped
|
||||
around to 0 after 65535)
|
||||
- number of times the controller enterted the Error Passive state (wrapped
|
||||
around to 0 after 65535)
|
||||
- number of times the controller enterted the Bus Off state (wrapped
|
||||
around to 0 after 65535)
|
||||
- number of pending TX messages
|
||||
- number of pending RX messages on fifo 0
|
||||
- number of pending RX messages on fifo 1
|
||||
|
||||
.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr)
|
||||
|
||||
.. method:: can.setfilter(bank, mode, fifo, params)
|
||||
|
||||
Configure a filter bank:
|
||||
|
||||
- *bank* is the filter bank that is to be configured.
|
||||
- *mode* is the mode the filter should operate in.
|
||||
- *fifo* is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter.
|
||||
- *params* is an array of values the defines the filter. The contents of the array depends on the *mode* argument.
|
||||
|
||||
|
||||
- ``bank`` is the filter bank that is to be configured.
|
||||
- ``mode`` is the mode the filter should operate in.
|
||||
- ``fifo`` is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter.
|
||||
- ``params`` is an array of values the defines the filter. The contents of the array depends on the ``mode`` argument.
|
||||
|
||||
+-----------+---------------------------------------------------------+
|
||||
|*mode* |contents of *params* array |
|
||||
|``mode`` |contents of parameter array |
|
||||
+===========+=========================================================+
|
||||
|CAN.LIST16 |Four 16 bit ids that will be accepted |
|
||||
+-----------+---------------------------------------------------------+
|
||||
|
@ -159,142 +106,49 @@ Methods
|
|||
+-----------+---------------------------------------------------------+
|
||||
|CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.|
|
||||
+-----------+---------------------------------------------------------+
|
||||
|
||||
- *rtr* is an array of booleans that states if a filter should accept a
|
||||
remote transmission request message. If this argument is not given
|
||||
then it defaults to ``False`` for all entries. The length of the array
|
||||
depends on the *mode* argument.
|
||||
|
||||
+-----------+----------------------+
|
||||
|*mode* |length of *rtr* array |
|
||||
+===========+======================+
|
||||
|CAN.LIST16 |4 |
|
||||
+-----------+----------------------+
|
||||
|CAN.LIST32 |2 |
|
||||
+-----------+----------------------+
|
||||
|CAN.MASK16 |2 |
|
||||
+-----------+----------------------+
|
||||
|CAN.MASK32 |1 |
|
||||
+-----------+----------------------+
|
||||
|
||||
.. method:: CAN.clearfilter(bank)
|
||||
|
||||
.. method:: can.clearfilter(bank)
|
||||
|
||||
Clear and disables a filter bank:
|
||||
|
||||
- ``bank`` is the filter bank that is to be cleared.
|
||||
|
||||
- *bank* is the filter bank that is to be cleared.
|
||||
|
||||
.. method:: CAN.any(fifo)
|
||||
.. method:: can.any(fifo)
|
||||
|
||||
Return ``True`` if any message waiting on the FIFO, else ``False``.
|
||||
|
||||
.. method:: CAN.recv(fifo, list=None, \*, timeout=5000)
|
||||
.. method:: can.recv(fifo, \*, timeout=5000)
|
||||
|
||||
Receive data on the bus:
|
||||
|
||||
- ``fifo`` is an integer, which is the FIFO to receive on
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
Return value: buffer of data bytes.
|
||||
|
||||
- *fifo* is an integer, which is the FIFO to receive on
|
||||
- *list* is an optional list object to be used as the return value
|
||||
- *timeout* is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
Return value: A tuple containing four values.
|
||||
|
||||
- The id of the message.
|
||||
- A boolean that indicates if the message is an RTR message.
|
||||
- The FMI (Filter Match Index) value.
|
||||
- An array containing the data.
|
||||
|
||||
If *list* is ``None`` then a new tuple will be allocated, as well as a new
|
||||
bytes object to contain the data (as the fourth element in the tuple).
|
||||
|
||||
If *list* is not ``None`` then it should be a list object with a least four
|
||||
elements. The fourth element should be a memoryview object which is created
|
||||
from either a bytearray or an array of type 'B' or 'b', and this array must
|
||||
have enough room for at least 8 bytes. The list object will then be
|
||||
populated with the first three return values above, and the memoryview object
|
||||
will be resized inplace to the size of the data and filled in with that data.
|
||||
The same list and memoryview objects can be reused in subsequent calls to
|
||||
this method, providing a way of receiving data without using the heap.
|
||||
For example::
|
||||
|
||||
buf = bytearray(8)
|
||||
lst = [0, 0, 0, memoryview(buf)]
|
||||
# No heap memory is allocated in the following call
|
||||
can.recv(0, lst)
|
||||
|
||||
.. method:: CAN.send(data, id, \*, timeout=0, rtr=False)
|
||||
.. method:: can.send(send, addr, \*, timeout=5000)
|
||||
|
||||
Send a message on the bus:
|
||||
|
||||
- *data* is the data to send (an integer to send, or a buffer object).
|
||||
- *id* is the id of the message to be sent.
|
||||
- *timeout* is the timeout in milliseconds to wait for the send.
|
||||
- *rtr* is a boolean that specifies if the message shall be sent as
|
||||
a remote transmission request. If *rtr* is True then only the length
|
||||
of *data* is used to fill in the DLC slot of the frame; the actual
|
||||
bytes in *data* are unused.
|
||||
|
||||
If timeout is 0 the message is placed in a buffer in one of three hardware
|
||||
buffers and the method returns immediately. If all three buffers are in use
|
||||
an exception is thrown. If timeout is not 0, the method waits until the
|
||||
message is transmitted. If the message can't be transmitted within the
|
||||
specified time an exception is thrown.
|
||||
|
||||
|
||||
- ``send`` is the data to send (an integer to send, or a buffer object).
|
||||
- ``addr`` is the address to send to
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send.
|
||||
|
||||
Return value: ``None``.
|
||||
|
||||
.. method:: CAN.rxcallback(fifo, fun)
|
||||
|
||||
Register a function to be called when a message is accepted into a empty fifo:
|
||||
|
||||
- *fifo* is the receiving fifo.
|
||||
- *fun* is the function to be called when the fifo becomes non empty.
|
||||
|
||||
The callback function takes two arguments the first is the can object it self the second is
|
||||
a integer that indicates the reason for the callback.
|
||||
|
||||
+--------+------------------------------------------------+
|
||||
| Reason | |
|
||||
+========+================================================+
|
||||
| 0 | A message has been accepted into a empty FIFO. |
|
||||
+--------+------------------------------------------------+
|
||||
| 1 | The FIFO is full |
|
||||
+--------+------------------------------------------------+
|
||||
| 2 | A message has been lost due to a full FIFO |
|
||||
+--------+------------------------------------------------+
|
||||
|
||||
Example use of rxcallback::
|
||||
|
||||
def cb0(bus, reason):
|
||||
print('cb0')
|
||||
if reason == 0:
|
||||
print('pending')
|
||||
if reason == 1:
|
||||
print('full')
|
||||
if reason == 2:
|
||||
print('overflow')
|
||||
|
||||
can = CAN(1, CAN.LOOPBACK)
|
||||
can.rxcallback(0, cb0)
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: CAN.NORMAL
|
||||
CAN.LOOPBACK
|
||||
CAN.SILENT
|
||||
CAN.SILENT_LOOPBACK
|
||||
.. data:: CAN.LOOPBACK
|
||||
.. data:: CAN.SILENT
|
||||
.. data:: CAN.SILENT_LOOPBACK
|
||||
|
||||
The mode of the CAN bus used in :meth:`~CAN.init()`.
|
||||
|
||||
.. data:: CAN.STOPPED
|
||||
CAN.ERROR_ACTIVE
|
||||
CAN.ERROR_WARNING
|
||||
CAN.ERROR_PASSIVE
|
||||
CAN.BUS_OFF
|
||||
|
||||
Possible states of the CAN controller returned from :meth:`~CAN.state()`.
|
||||
the mode of the CAN bus
|
||||
|
||||
.. data:: CAN.LIST16
|
||||
CAN.MASK16
|
||||
CAN.LIST32
|
||||
CAN.MASK32
|
||||
.. data:: CAN.MASK16
|
||||
.. data:: CAN.LIST32
|
||||
.. data:: CAN.MASK32
|
||||
|
||||
The operation mode of a filter used in :meth:`~CAN.setfilter()`.
|
||||
the operation mode of a filter
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.DAC:
|
||||
|
||||
class DAC -- digital to analog conversion
|
||||
|
@ -16,9 +15,6 @@ Example usage::
|
|||
dac = DAC(1) # create DAC 1 on pin X5
|
||||
dac.write(128) # write a value to the DAC (makes X5 1.65V)
|
||||
|
||||
dac = DAC(1, bits=12) # use 12 bit resolution
|
||||
dac.write(4095) # output maximum value, 3.3V
|
||||
|
||||
To output a continuous sine-wave::
|
||||
|
||||
import math
|
||||
|
@ -27,98 +23,47 @@ To output a continuous sine-wave::
|
|||
# create a buffer containing a sine-wave
|
||||
buf = bytearray(100)
|
||||
for i in range(len(buf)):
|
||||
buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf)))
|
||||
buf[i] = 128 + int(127 \* math.sin(2 \* math.pi \* i / len(buf)))
|
||||
|
||||
# output the sine-wave at 400Hz
|
||||
dac = DAC(1)
|
||||
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
|
||||
dac.write_timed(buf, 400 \* len(buf), mode=DAC.CIRCULAR)
|
||||
|
||||
To output a continuous sine-wave at 12-bit resolution::
|
||||
|
||||
import math
|
||||
from array import array
|
||||
from pyb import DAC
|
||||
|
||||
# create a buffer containing a sine-wave, using half-word samples
|
||||
buf = array('H', 2048 + int(2047 * math.sin(2 * math.pi * i / 128)) for i in range(128))
|
||||
|
||||
# output the sine-wave at 400Hz
|
||||
dac = DAC(1, bits=12)
|
||||
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.DAC(port, bits=8, \*, buffering=None)
|
||||
.. class:: pyb.DAC(port)
|
||||
|
||||
Construct a new DAC object.
|
||||
|
||||
|
||||
``port`` can be a pin object, or an integer (1 or 2).
|
||||
DAC(1) is on pin X5 and DAC(2) is on pin X6.
|
||||
|
||||
``bits`` is an integer specifying the resolution, and can be 8 or 12.
|
||||
The maximum value for the write and write_timed methods will be
|
||||
2\*\*``bits``-1.
|
||||
|
||||
The *buffering* parameter selects the behaviour of the DAC op-amp output
|
||||
buffer, whose purpose is to reduce the output impedance. It can be
|
||||
``None`` to select the default (buffering enabled for :meth:`DAC.noise`,
|
||||
:meth:`DAC.triangle` and :meth:`DAC.write_timed`, and disabled for
|
||||
:meth:`DAC.write`), ``False`` to disable buffering completely, or ``True``
|
||||
to enable output buffering.
|
||||
|
||||
When buffering is enabled the DAC pin can drive loads down to 5KΩ.
|
||||
Otherwise it has an output impedance of 15KΩ maximum: consequently
|
||||
to achieve a 1% accuracy without buffering requires the applied load
|
||||
to be less than 1.5MΩ. Using the buffer incurs a penalty in accuracy,
|
||||
especially near the extremes of range.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: DAC.init(bits=8, \*, buffering=None)
|
||||
|
||||
Reinitialise the DAC. *bits* can be 8 or 12. *buffering* can be
|
||||
``None``, ``False`` or ``True``; see above constructor for the meaning
|
||||
of this parameter.
|
||||
|
||||
.. method:: DAC.deinit()
|
||||
|
||||
De-initialise the DAC making its pin available for other uses.
|
||||
|
||||
.. method:: DAC.noise(freq)
|
||||
.. method:: dac.noise(freq)
|
||||
|
||||
Generate a pseudo-random noise signal. A new random sample is written
|
||||
to the DAC output at the given frequency.
|
||||
|
||||
.. method:: DAC.triangle(freq)
|
||||
.. method:: dac.triangle(freq)
|
||||
|
||||
Generate a triangle wave. The value on the DAC output changes at the given
|
||||
frequency and ramps through the full 12-bit range (up and down). Therefore
|
||||
the frequency of the repeating triangle wave itself is 8192 times smaller.
|
||||
Generate a triangle wave. The value on the DAC output changes at
|
||||
the given frequency, and the frequence of the repeating triangle wave
|
||||
itself is 256 (or 1024, need to check) times smaller.
|
||||
|
||||
.. method:: DAC.write(value)
|
||||
.. method:: dac.write(value)
|
||||
|
||||
Direct access to the DAC output. The minimum value is 0. The maximum
|
||||
value is 2\*\*``bits``-1, where ``bits`` is set when creating the DAC
|
||||
object or by using the ``init`` method.
|
||||
Direct access to the DAC output (8 bit only at the moment).
|
||||
|
||||
.. method:: DAC.write_timed(data, freq, \*, mode=DAC.NORMAL)
|
||||
.. method:: dac.write_timed(data, freq, \*, mode=DAC.NORMAL)
|
||||
|
||||
Initiates a burst of RAM to DAC using a DMA transfer.
|
||||
The input data is treated as an array of bytes in 8-bit mode, and
|
||||
an array of unsigned half-words (array typecode 'H') in 12-bit mode.
|
||||
|
||||
``freq`` can be an integer specifying the frequency to write the DAC
|
||||
samples at, using Timer(6). Or it can be an already-initialised
|
||||
Timer object which is used to trigger the DAC sample. Valid timers
|
||||
are 2, 4, 5, 6, 7 and 8.
|
||||
|
||||
The input data is treated as an array of bytes (8 bit data).
|
||||
|
||||
``mode`` can be ``DAC.NORMAL`` or ``DAC.CIRCULAR``.
|
||||
|
||||
Example using both DACs at the same time::
|
||||
|
||||
dac1 = DAC(1)
|
||||
dac2 = DAC(2)
|
||||
dac1.write_timed(buf1, pyb.Timer(6, freq=100), mode=DAC.CIRCULAR)
|
||||
dac2.write_timed(buf2, pyb.Timer(7, freq=200), mode=DAC.CIRCULAR)
|
||||
|
||||
TIM6 is used to control the frequency of the transfer.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.ExtInt:
|
||||
|
||||
class ExtInt -- configure I/O pins to interrupt on external events
|
||||
|
@ -7,7 +6,7 @@ class ExtInt -- configure I/O pins to interrupt on external events
|
|||
There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
|
||||
and the remaining 6 are from internal sources.
|
||||
|
||||
For lines 0 through 15, a given line can map to the corresponding line from an
|
||||
For lines 0 thru 15, a given line can map to the corresponding line from an
|
||||
arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
|
||||
line 1 can map to Px1 where x is A, B, C, ... ::
|
||||
|
||||
|
@ -27,7 +26,7 @@ explanation, along with various techniques for debouncing.
|
|||
Trying to register 2 callbacks onto the same pin will throw an exception.
|
||||
|
||||
If pin is passed as an integer, then it is assumed to map to one of the
|
||||
internal interrupt sources, and must be in the range 16 through 22.
|
||||
internal interrupt sources, and must be in the range 16 thru 22.
|
||||
|
||||
All other pin objects go through the pin mapper to come up with one of the
|
||||
gpio pins. ::
|
||||
|
@ -54,7 +53,7 @@ Constructors
|
|||
.. class:: pyb.ExtInt(pin, mode, pull, callback)
|
||||
|
||||
Create an ExtInt object:
|
||||
|
||||
|
||||
- ``pin`` is the pin on which to enable the interrupt (can be a pin object or any valid pin name).
|
||||
- ``mode`` can be one of:
|
||||
- ``ExtInt.IRQ_RISING`` - trigger on a rising edge;
|
||||
|
@ -72,7 +71,7 @@ Constructors
|
|||
Class methods
|
||||
-------------
|
||||
|
||||
.. classmethod:: ExtInt.regs()
|
||||
.. method:: ExtInt.regs()
|
||||
|
||||
Dump the values of the EXTI registers.
|
||||
|
||||
|
@ -80,20 +79,20 @@ Class methods
|
|||
Methods
|
||||
-------
|
||||
|
||||
.. method:: ExtInt.disable()
|
||||
.. method:: extint.disable()
|
||||
|
||||
Disable the interrupt associated with the ExtInt object.
|
||||
This could be useful for debouncing.
|
||||
|
||||
.. method:: ExtInt.enable()
|
||||
.. method:: extint.enable()
|
||||
|
||||
Enable a disabled interrupt.
|
||||
|
||||
.. method:: ExtInt.line()
|
||||
.. method:: extint.line()
|
||||
|
||||
Return the line number that the pin is mapped to.
|
||||
|
||||
.. method:: ExtInt.swint()
|
||||
.. method:: extint.swint()
|
||||
|
||||
Trigger the callback from software.
|
||||
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Flash:
|
||||
|
||||
class Flash -- access to built-in flash storage
|
||||
===============================================
|
||||
|
||||
The Flash class allows direct access to the primary flash device on the pyboard.
|
||||
|
||||
In most cases, to store persistent data on the device, you'll want to use a
|
||||
higher-level abstraction, for example the filesystem via Python's standard file
|
||||
API, but this interface is useful to :ref:`customise the filesystem
|
||||
configuration <filesystem>` or implement a low-level storage system for your
|
||||
application.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.Flash()
|
||||
|
||||
Create and return a block device that represents the flash device presented
|
||||
to the USB mass storage interface.
|
||||
|
||||
It includes a virtual partition table at the start, and the actual flash
|
||||
starts at block ``0x100``.
|
||||
|
||||
This constructor is deprecated and will be removed in a future version of MicroPython.
|
||||
|
||||
.. class:: pyb.Flash(\*, start=-1, len=-1)
|
||||
|
||||
Create and return a block device that accesses the flash at the specified offset. The length defaults to the remaining size of the device.
|
||||
|
||||
The *start* and *len* offsets are in bytes, and must be a multiple of the block size (typically 512 for internal flash).
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Flash.readblocks(block_num, buf)
|
||||
.. method:: Flash.readblocks(block_num, buf, offset)
|
||||
.. method:: Flash.writeblocks(block_num, buf)
|
||||
.. method:: Flash.writeblocks(block_num, buf, offset)
|
||||
.. method:: Flash.ioctl(cmd, arg)
|
||||
|
||||
These methods implement the simple and :ref:`extended
|
||||
<block-device-interface>` block protocol defined by
|
||||
:class:`uos.AbstractBlockDev`.
|
||||
|
||||
Hardware Note
|
||||
-------------
|
||||
|
||||
On boards with external spiflash (e.g. Pyboard D), the MicroPython firmware will
|
||||
be configured to use that as the primary flash storage. On all other boards, the
|
||||
internal flash inside the :term:`MCU` will be used.
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.I2C:
|
||||
|
||||
class I2C -- a two-wire serial protocol
|
||||
|
@ -8,9 +7,7 @@ I2C is a two-wire protocol for communicating between devices. At the physical
|
|||
level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
|
||||
|
||||
I2C objects are created attached to a specific bus. They can be initialised
|
||||
when created, or initialised later on.
|
||||
|
||||
Example::
|
||||
when created, or initialised later on::
|
||||
|
||||
from pyb import I2C
|
||||
|
||||
|
@ -22,7 +19,7 @@ Example::
|
|||
|
||||
Printing the i2c object gives you information about its configuration.
|
||||
|
||||
The basic methods are send and recv::
|
||||
Basic methods for slave are send and recv::
|
||||
|
||||
i2c.send('abc') # send 3 bytes
|
||||
i2c.send(0x42) # send a single byte, given by the number
|
||||
|
@ -35,7 +32,7 @@ To receive inplace, first create a bytearray::
|
|||
|
||||
You can specify a timeout (in ms)::
|
||||
|
||||
i2c.send(b'123', timeout=2000) # timeout after 2 seconds
|
||||
i2c.send(b'123', timeout=2000) # timout after 2 seconds
|
||||
|
||||
A master must specify the recipient's address::
|
||||
|
||||
|
@ -50,109 +47,100 @@ Master also has other methods::
|
|||
# a list of valid addresses
|
||||
i2c.mem_read(3, 0x42, 2) # read 3 bytes from memory of slave 0x42,
|
||||
# starting at address 2 in the slave
|
||||
i2c.mem_write('abc', 0x42, 2, timeout=1000) # write 'abc' (3 bytes) to memory of slave 0x42
|
||||
# starting at address 2 in the slave, timeout after 1 second
|
||||
i2c.mem_write('abc', 0x42, 2, timeout=1000)
|
||||
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.I2C(bus, ...)
|
||||
|
||||
Construct an I2C object on the given bus. ``bus`` can be 1 or 2, 'X' or
|
||||
'Y'. With no additional parameters, the I2C object is created but not
|
||||
Construct an I2C object on the given bus. ``bus`` can be 1 or 2.
|
||||
With no additional parameters, the I2C object is created but not
|
||||
initialised (it has the settings from the last initialisation of
|
||||
the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
See ``init`` for parameters of initialisation.
|
||||
|
||||
The physical pins of the I2C busses on Pyboards V1.0 and V1.1 are:
|
||||
|
||||
|
||||
The physical pins of the I2C busses are:
|
||||
|
||||
- ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)``
|
||||
- ``I2C(2)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PB10, PB11)``
|
||||
|
||||
On the Pyboard Lite:
|
||||
|
||||
- ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)``
|
||||
- ``I2C(3)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PA8, PB8)``
|
||||
|
||||
Calling the constructor with 'X' or 'Y' enables portability between Pyboard
|
||||
types.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: I2C.deinit()
|
||||
.. method:: i2c.deinit()
|
||||
|
||||
Turn off the I2C bus.
|
||||
|
||||
.. method:: I2C.init(mode, \*, addr=0x12, baudrate=400000, gencall=False, dma=False)
|
||||
|
||||
Initialise the I2C bus with the given parameters:
|
||||
.. method:: i2c.init(mode, \*, addr=0x12, baudrate=400000, gencall=False)
|
||||
|
||||
Initialise the I2C bus with the given parameters:
|
||||
|
||||
- ``mode`` must be either ``I2C.MASTER`` or ``I2C.SLAVE``
|
||||
- ``addr`` is the 7-bit address (only sensible for a slave)
|
||||
- ``baudrate`` is the SCL clock rate (only sensible for a master)
|
||||
- ``gencall`` is whether to support general call mode
|
||||
- ``dma`` is whether to allow the use of DMA for the I2C transfers (note
|
||||
that DMA transfers have more precise timing but currently do not handle bus
|
||||
errors properly)
|
||||
|
||||
.. method:: I2C.is_ready(addr)
|
||||
.. method:: i2c.is_ready(addr)
|
||||
|
||||
Check if an I2C device responds to the given address. Only valid when in master mode.
|
||||
|
||||
.. method:: I2C.mem_read(data, addr, memaddr, \*, timeout=5000, addr_size=8)
|
||||
.. method:: i2c.mem_read(data, addr, memaddr, timeout=5000, addr_size=8)
|
||||
|
||||
Read from the memory of an I2C device:
|
||||
|
||||
|
||||
- ``data`` can be an integer (number of bytes to read) or a buffer to read into
|
||||
- ``addr`` is the I2C device address
|
||||
- ``memaddr`` is the memory location within the I2C device
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the read
|
||||
- ``addr_size`` selects width of memaddr: 8 or 16 bits
|
||||
|
||||
|
||||
Returns the read data.
|
||||
This is only valid in master mode.
|
||||
|
||||
.. method:: I2C.mem_write(data, addr, memaddr, \*, timeout=5000, addr_size=8)
|
||||
.. method:: i2c.mem_write(data, addr, memaddr, timeout=5000, addr_size=8)
|
||||
|
||||
Write to the memory of an I2C device:
|
||||
|
||||
|
||||
- ``data`` can be an integer or a buffer to write from
|
||||
- ``addr`` is the I2C device address
|
||||
- ``memaddr`` is the memory location within the I2C device
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the write
|
||||
- ``addr_size`` selects width of memaddr: 8 or 16 bits
|
||||
|
||||
|
||||
Returns ``None``.
|
||||
This is only valid in master mode.
|
||||
|
||||
.. method:: I2C.recv(recv, addr=0x00, \*, timeout=5000)
|
||||
.. method:: i2c.recv(recv, addr=0x00, timeout=5000)
|
||||
|
||||
Receive data on the bus:
|
||||
|
||||
|
||||
- ``recv`` can be an integer, which is the number of bytes to receive,
|
||||
or a mutable buffer, which will be filled with received bytes
|
||||
- ``addr`` is the address to receive from (only required in master mode)
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive
|
||||
|
||||
|
||||
Return value: if ``recv`` is an integer then a new buffer of the bytes received,
|
||||
otherwise the same buffer that was passed in to ``recv``.
|
||||
|
||||
.. method:: I2C.send(send, addr=0x00, \*, timeout=5000)
|
||||
|
||||
Send data on the bus:
|
||||
|
||||
- ``send`` is the data to send (an integer to send, or a buffer object)
|
||||
- ``addr`` is the address to send to (only required in master mode)
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send
|
||||
|
||||
Return value: ``None``.
|
||||
|
||||
.. method:: I2C.scan()
|
||||
.. method:: i2c.scan()
|
||||
|
||||
Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
|
||||
Only valid when in master mode.
|
||||
|
||||
.. method:: i2c.send(send, addr=0x00, timeout=5000)
|
||||
|
||||
Send data on the bus:
|
||||
|
||||
- ``send`` is the data to send (an integer to send, or a buffer object)
|
||||
- ``addr`` is the address to send to (only required in master mode)
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send
|
||||
|
||||
Return value: ``None``.
|
||||
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.LCD:
|
||||
|
||||
class LCD -- LCD control for the LCD touch-sensor pyskin
|
||||
========================================================
|
||||
|
||||
|
@ -50,48 +47,48 @@ Constructors
|
|||
Methods
|
||||
-------
|
||||
|
||||
.. method:: LCD.command(instr_data, buf)
|
||||
.. method:: lcd.command(instr_data, buf)
|
||||
|
||||
Send an arbitrary command to the LCD. Pass 0 for ``instr_data`` to send an
|
||||
instruction, otherwise pass 1 to send data. ``buf`` is a buffer with the
|
||||
instructions/data to send.
|
||||
|
||||
.. method:: LCD.contrast(value)
|
||||
.. method:: lcd.contrast(value)
|
||||
|
||||
Set the contrast of the LCD. Valid values are between 0 and 47.
|
||||
|
||||
.. method:: LCD.fill(colour)
|
||||
.. method:: lcd.fill(colour)
|
||||
|
||||
Fill the screen with the given colour (0 or 1 for white or black).
|
||||
|
||||
|
||||
This method writes to the hidden buffer. Use ``show()`` to show the buffer.
|
||||
|
||||
.. method:: LCD.get(x, y)
|
||||
.. method:: lcd.get(x, y)
|
||||
|
||||
Get the pixel at the position ``(x, y)``. Returns 0 or 1.
|
||||
|
||||
|
||||
This method reads from the visible buffer.
|
||||
|
||||
.. method:: LCD.light(value)
|
||||
.. method:: lcd.light(value)
|
||||
|
||||
Turn the backlight on/off. True or 1 turns it on, False or 0 turns it off.
|
||||
|
||||
.. method:: LCD.pixel(x, y, colour)
|
||||
.. method:: lcd.pixel(x, y, colour)
|
||||
|
||||
Set the pixel at ``(x, y)`` to the given colour (0 or 1).
|
||||
|
||||
|
||||
This method writes to the hidden buffer. Use ``show()`` to show the buffer.
|
||||
|
||||
.. method:: LCD.show()
|
||||
.. method:: lcd.show()
|
||||
|
||||
Show the hidden buffer on the screen.
|
||||
|
||||
.. method:: LCD.text(str, x, y, colour)
|
||||
.. method:: lcd.text(str, x, y, colour)
|
||||
|
||||
Draw the given text to the position ``(x, y)`` using the given colour (0 or 1).
|
||||
|
||||
|
||||
This method writes to the hidden buffer. Use ``show()`` to show the buffer.
|
||||
|
||||
.. method:: LCD.write(str)
|
||||
.. method:: lcd.write(str)
|
||||
|
||||
Write the string ``str`` to the screen. It will appear immediately.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.LED:
|
||||
|
||||
class LED -- LED object
|
||||
|
@ -13,34 +12,28 @@ Constructors
|
|||
.. class:: pyb.LED(id)
|
||||
|
||||
Create an LED object associated with the given LED:
|
||||
|
||||
|
||||
- ``id`` is the LED number, 1-4.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: LED.intensity([value])
|
||||
.. method:: led.intensity([value])
|
||||
|
||||
Get or set the LED intensity. Intensity ranges between 0 (off) and 255 (full on).
|
||||
If no argument is given, return the LED intensity.
|
||||
If an argument is given, set the LED intensity and return ``None``.
|
||||
|
||||
*Note:* Only LED(3) and LED(4) can have a smoothly varying intensity, and
|
||||
they use timer PWM to implement it. LED(3) uses Timer(2) and LED(4) uses
|
||||
Timer(3). These timers are only configured for PWM if the intensity of the
|
||||
relevant LED is set to a value between 1 and 254. Otherwise the timers are
|
||||
free for general purpose use.
|
||||
|
||||
.. method:: LED.off()
|
||||
.. method:: led.off()
|
||||
|
||||
Turn the LED off.
|
||||
|
||||
.. method:: LED.on()
|
||||
.. method:: led.on()
|
||||
|
||||
Turn the LED on, to maximum intensity.
|
||||
|
||||
.. method:: LED.toggle()
|
||||
.. method:: led.toggle()
|
||||
|
||||
Toggle the LED between on (maximum intensity) and off. If the LED is at
|
||||
non-zero intensity then it is considered "on" and toggle will turn it off.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Pin:
|
||||
|
||||
class Pin -- control I/O pins
|
||||
|
@ -6,20 +5,20 @@ class Pin -- control I/O pins
|
|||
|
||||
A pin is the basic object to control I/O pins. It has methods to set
|
||||
the mode of the pin (input, output, etc) and methods to get and set the
|
||||
digital logic level. For analog control of a pin, see the ADC class.
|
||||
digital logic level. For analog control of a pin, see the ADC class.
|
||||
|
||||
Usage Model:
|
||||
|
||||
All Board Pins are predefined as pyb.Pin.board.Name::
|
||||
All Board Pins are predefined as pyb.Pin.board.Name ::
|
||||
|
||||
x1_pin = pyb.Pin.board.X1
|
||||
|
||||
g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN)
|
||||
|
||||
CPU pins which correspond to the board pins are available
|
||||
as ``pyb.Pin.cpu.Name``. For the CPU pins, the names are the port letter
|
||||
as ``pyb.cpu.Name``. For the CPU pins, the names are the port letter
|
||||
followed by the pin number. On the PYBv1.0, ``pyb.Pin.board.X1`` and
|
||||
``pyb.Pin.cpu.A0`` are the same pin.
|
||||
``pyb.Pin.cpu.B6`` are the same pin.
|
||||
|
||||
You can also use strings::
|
||||
|
||||
|
@ -31,7 +30,7 @@ Users can add their own names::
|
|||
pyb.Pin.dict(MyMapperDict)
|
||||
g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)
|
||||
|
||||
and can query mappings::
|
||||
and can query mappings ::
|
||||
|
||||
pin = pyb.Pin("LeftMotorDir")
|
||||
|
||||
|
@ -62,15 +61,6 @@ When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled,
|
|||
that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND
|
||||
respectively (except pin Y5 which has 11k Ohm resistors).
|
||||
|
||||
Now every time a falling edge is seen on the gpio pin, the callback will be
|
||||
executed. Caution: mechanical push buttons have "bounce" and pushing or
|
||||
releasing a switch will often generate multiple edges.
|
||||
See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
|
||||
explanation, along with various techniques for debouncing.
|
||||
|
||||
All pin objects go through the pin mapper to come up with one of the
|
||||
gpio pins.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
|
@ -79,18 +69,23 @@ Constructors
|
|||
Create a new Pin object associated with the id. If additional arguments are given,
|
||||
they are used to initialise the pin. See :meth:`pin.init`.
|
||||
|
||||
|
||||
Class methods
|
||||
-------------
|
||||
|
||||
.. classmethod:: Pin.debug([state])
|
||||
.. method:: Pin.af_list()
|
||||
|
||||
Returns an array of alternate functions available for this pin.
|
||||
|
||||
.. method:: Pin.debug([state])
|
||||
|
||||
Get or set the debugging state (``True`` or ``False`` for on or off).
|
||||
|
||||
.. classmethod:: Pin.dict([dict])
|
||||
.. method:: Pin.dict([dict])
|
||||
|
||||
Get or set the pin mapper dictionary.
|
||||
|
||||
.. classmethod:: Pin.mapper([fun])
|
||||
.. method:: Pin.mapper([fun])
|
||||
|
||||
Get or set the pin mapper function.
|
||||
|
||||
|
@ -98,31 +93,35 @@ Class methods
|
|||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Pin.init(mode, pull=Pin.PULL_NONE, af=-1)
|
||||
.. method:: pin.init(mode, pull=Pin.PULL_NONE, af=-1)
|
||||
|
||||
Initialise the pin:
|
||||
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``Pin.IN`` - configure the pin for input;
|
||||
- ``Pin.OUT_PP`` - configure the pin for output, with push-pull control;
|
||||
- ``Pin.OUT_OD`` - configure the pin for output, with open-drain control;
|
||||
- ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull;
|
||||
- ``Pin.AF_OD`` - configure the pin for alternate function, open-drain;
|
||||
- ``Pin.ANALOG`` - configure the pin for analog.
|
||||
|
||||
- ``Pin.IN`` - configure the pin for input;
|
||||
- ``Pin.OUT_PP`` - configure the pin for output, with push-pull control;
|
||||
- ``Pin.OUT_OD`` - configure the pin for output, with open-drain control;
|
||||
- ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull;
|
||||
- ``Pin.AF_OD`` - configure the pin for alternate function, open-drain;
|
||||
- ``Pin.ANALOG`` - configure the pin for analog.
|
||||
- ``pull`` can be one of:
|
||||
|
||||
- ``Pin.PULL_NONE`` - no pull up or down resistors;
|
||||
- ``Pin.PULL_UP`` - enable the pull-up resistor;
|
||||
- ``Pin.PULL_DOWN`` - enable the pull-down resistor.
|
||||
|
||||
- when mode is ``Pin.AF_PP`` or ``Pin.AF_OD``, then af can be the index or name
|
||||
- ``Pin.PULL_NONE`` - no pull up or down resistors;
|
||||
- ``Pin.PULL_UP`` - enable the pull-up resistor;
|
||||
- ``Pin.PULL_DOWN`` - enable the pull-down resistor.
|
||||
- when mode is Pin.AF_PP or Pin.AF_OD, then af can be the index or name
|
||||
of one of the alternate functions associated with a pin.
|
||||
|
||||
|
||||
Returns: ``None``.
|
||||
|
||||
.. method:: Pin.value([value])
|
||||
.. method:: pin.high()
|
||||
|
||||
Set the pin to a high logic level.
|
||||
|
||||
.. method:: pin.low()
|
||||
|
||||
Set the pin to a low logic level.
|
||||
|
||||
.. method:: pin.value([value])
|
||||
|
||||
Get or set the digital logic level of the pin:
|
||||
|
||||
|
@ -131,51 +130,48 @@ Methods
|
|||
anything that converts to a boolean. If it converts to ``True``, the pin
|
||||
is set high, otherwise it is set low.
|
||||
|
||||
.. method:: Pin.__str__()
|
||||
.. method:: pin.__str__()
|
||||
|
||||
Return a string describing the pin object.
|
||||
|
||||
.. method:: Pin.af()
|
||||
.. method:: pin.af()
|
||||
|
||||
Returns the currently configured alternate-function of the pin. The
|
||||
integer returned will match one of the allowed constants for the af
|
||||
argument to the init function.
|
||||
|
||||
.. method:: Pin.af_list()
|
||||
|
||||
Returns an array of alternate functions available for this pin.
|
||||
|
||||
.. method:: Pin.gpio()
|
||||
.. method:: pin.gpio()
|
||||
|
||||
Returns the base address of the GPIO block associated with this pin.
|
||||
|
||||
.. method:: Pin.mode()
|
||||
.. method:: pin.mode()
|
||||
|
||||
Returns the currently configured mode of the pin. The integer returned
|
||||
will match one of the allowed constants for the mode argument to the init
|
||||
function.
|
||||
|
||||
.. method:: Pin.name()
|
||||
.. method:: pin.name()
|
||||
|
||||
Get the pin name.
|
||||
|
||||
.. method:: Pin.names()
|
||||
.. method:: pin.names()
|
||||
|
||||
Returns the cpu and board names for this pin.
|
||||
|
||||
.. method:: Pin.pin()
|
||||
.. method:: pin.pin()
|
||||
|
||||
Get the pin number.
|
||||
|
||||
.. method:: Pin.port()
|
||||
.. method:: pin.port()
|
||||
|
||||
Get the pin port.
|
||||
|
||||
.. method:: Pin.pull()
|
||||
.. method:: pin.pull()
|
||||
|
||||
Returns the currently configured pull of the pin. The integer returned
|
||||
will match one of the allowed constants for the pull argument to the init
|
||||
function.
|
||||
|
||||
Returns the currently configured pull of the pin. The integer returned
|
||||
will match one of the allowed constants for the pull argument to the init
|
||||
function.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
@ -216,10 +212,11 @@ Constants
|
|||
|
||||
enable the pull-up resistor on the pin
|
||||
|
||||
|
||||
class PinAF -- Pin Alternate Functions
|
||||
======================================
|
||||
|
||||
A Pin represents a physical pin on the microprocessor. Each pin
|
||||
A Pin represents a physical pin on the microcprocessor. Each pin
|
||||
can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF
|
||||
object represents a particular function for a pin.
|
||||
|
||||
|
@ -228,7 +225,7 @@ Usage Model::
|
|||
x3 = pyb.Pin.board.X3
|
||||
x3_af = x3.af_list()
|
||||
|
||||
x3_af will now contain an array of PinAF objects which are available on
|
||||
x3_af will now contain an array of PinAF objects which are availble on
|
||||
pin X3.
|
||||
|
||||
For the pyboard, x3_af would contain:
|
||||
|
@ -246,6 +243,7 @@ or::
|
|||
|
||||
pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=1)
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.RTC:
|
||||
|
||||
class RTC -- real time clock
|
||||
============================
|
||||
|
||||
|
@ -25,54 +22,27 @@ Constructors
|
|||
Methods
|
||||
-------
|
||||
|
||||
.. method:: RTC.datetime([datetimetuple])
|
||||
.. method:: rtc.datetime([datetimetuple])
|
||||
|
||||
Get or set the date and time of the RTC.
|
||||
|
||||
|
||||
With no arguments, this method returns an 8-tuple with the current
|
||||
date and time. With 1 argument (being an 8-tuple) it sets the date
|
||||
and time (and ``subseconds`` is reset to 255).
|
||||
|
||||
and time.
|
||||
|
||||
The 8-tuple has the following format:
|
||||
|
||||
|
||||
(year, month, day, weekday, hours, minutes, seconds, subseconds)
|
||||
|
||||
|
||||
``weekday`` is 1-7 for Monday through Sunday.
|
||||
|
||||
|
||||
``subseconds`` counts down from 255 to 0
|
||||
|
||||
.. method:: RTC.wakeup(timeout, callback=None)
|
||||
|
||||
Set the RTC wakeup timer to trigger repeatedly at every ``timeout``
|
||||
milliseconds. This trigger can wake the pyboard from both the sleep
|
||||
states: :meth:`pyb.stop` and :meth:`pyb.standby`.
|
||||
|
||||
If ``timeout`` is ``None`` then the wakeup timer is disabled.
|
||||
|
||||
If ``callback`` is given then it is executed at every trigger of the
|
||||
wakeup timer. ``callback`` must take exactly one argument.
|
||||
|
||||
.. method:: RTC.info()
|
||||
.. method:: rtc.info()
|
||||
|
||||
Get information about the startup time and reset source.
|
||||
|
||||
|
||||
- The lower 0xffff are the number of milliseconds the RTC took to
|
||||
start up.
|
||||
- Bit 0x10000 is set if a power-on reset occurred.
|
||||
- Bit 0x20000 is set if an external reset occurred
|
||||
|
||||
.. method:: RTC.calibration(cal)
|
||||
|
||||
Get or set RTC calibration.
|
||||
|
||||
With no arguments, ``calibration()`` returns the current calibration
|
||||
value, which is an integer in the range [-511 : 512]. With one
|
||||
argument it sets the RTC calibration.
|
||||
|
||||
The RTC Smooth Calibration mechanism adjusts the RTC clock rate by
|
||||
adding or subtracting the given number of ticks from the 32768 Hz
|
||||
clock over a 32 second period (corresponding to 2^20 clock ticks.)
|
||||
Each tick added will speed up the clock by 1 part in 2^20, or 0.954
|
||||
ppm; likewise the RTC clock it slowed by negative values. The
|
||||
usable calibration range is:
|
||||
(-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.SPI:
|
||||
|
||||
class SPI -- a master-driven serial protocol
|
||||
|
@ -18,43 +17,45 @@ Only required parameter is mode, SPI.MASTER or SPI.SLAVE. Polarity can be
|
|||
to sample data on the first or second clock edge respectively. Crc can be
|
||||
None for no CRC, or a polynomial specifier.
|
||||
|
||||
Additional methods for SPI::
|
||||
Additional method for SPI::
|
||||
|
||||
data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes
|
||||
buf = bytearray(4)
|
||||
spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf
|
||||
spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf
|
||||
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.SPI(bus, ...)
|
||||
|
||||
Construct an SPI object on the given bus. ``bus`` can be 1 or 2, or
|
||||
'X' or 'Y'. With no additional parameters, the SPI object is created but
|
||||
not initialised (it has the settings from the last initialisation of
|
||||
Construct an SPI object on the given bus. ``bus`` can be 1 or 2.
|
||||
With no additional parameters, the SPI object is created but not
|
||||
initialised (it has the settings from the last initialisation of
|
||||
the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
See ``init`` for parameters of initialisation.
|
||||
|
||||
|
||||
The physical pins of the SPI busses are:
|
||||
|
||||
|
||||
- ``SPI(1)`` is on the X position: ``(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)``
|
||||
- ``SPI(2)`` is on the Y position: ``(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)``
|
||||
|
||||
|
||||
At the moment, the NSS pin is not used by the SPI driver and is free
|
||||
for other use.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: SPI.deinit()
|
||||
.. method:: spi.deinit()
|
||||
|
||||
Turn off the SPI bus.
|
||||
|
||||
.. method:: SPI.init(mode, baudrate=328125, \*, prescaler, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
|
||||
.. method:: spi.init(mode, baudrate=328125, \*, prescaler, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
|
||||
|
||||
Initialise the SPI bus with the given parameters:
|
||||
|
||||
|
||||
- ``mode`` must be either ``SPI.MASTER`` or ``SPI.SLAVE``.
|
||||
- ``baudrate`` is the SCK clock rate (only sensible for a master).
|
||||
- ``prescaler`` is the prescaler to use to derive SCK from the APB bus frequency;
|
||||
|
@ -62,7 +63,6 @@ Methods
|
|||
- ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
|
||||
- ``phase`` can be 0 or 1 to sample data on the first or second clock edge
|
||||
respectively.
|
||||
- ``bits`` can be 8 or 16, and is the number of bits in each transferred word.
|
||||
- ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
|
||||
- ``crc`` can be None for no CRC, or a polynomial specifier.
|
||||
|
||||
|
@ -76,38 +76,39 @@ Methods
|
|||
Printing the SPI object will show you the computed baudrate and the chosen
|
||||
prescaler.
|
||||
|
||||
.. method:: SPI.recv(recv, \*, timeout=5000)
|
||||
.. method:: spi.recv(recv, \*, timeout=5000)
|
||||
|
||||
Receive data on the bus:
|
||||
|
||||
|
||||
- ``recv`` can be an integer, which is the number of bytes to receive,
|
||||
or a mutable buffer, which will be filled with received bytes.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
|
||||
Return value: if ``recv`` is an integer then a new buffer of the bytes received,
|
||||
otherwise the same buffer that was passed in to ``recv``.
|
||||
|
||||
.. method:: SPI.send(send, \*, timeout=5000)
|
||||
.. method:: spi.send(send, \*, timeout=5000)
|
||||
|
||||
Send data on the bus:
|
||||
|
||||
|
||||
- ``send`` is the data to send (an integer to send, or a buffer object).
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send.
|
||||
|
||||
|
||||
Return value: ``None``.
|
||||
|
||||
.. method:: SPI.send_recv(send, recv=None, \*, timeout=5000)
|
||||
.. method:: spi.send_recv(send, recv=None, \*, timeout=5000)
|
||||
|
||||
Send and receive data on the bus at the same time:
|
||||
|
||||
|
||||
- ``send`` is the data to send (an integer to send, or a buffer object).
|
||||
- ``recv`` is a mutable buffer which will be filled with received bytes.
|
||||
It can be the same as ``send``, or omitted. If omitted, a new buffer will
|
||||
be created.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
|
||||
Return value: the buffer with the received bytes.
|
||||
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
|
|
|
@ -1,80 +1,38 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Servo:
|
||||
|
||||
class Servo -- 3-wire hobby servo driver
|
||||
========================================
|
||||
|
||||
Servo objects control standard hobby servo motors with 3-wires (ground, power,
|
||||
signal). There are 4 positions on the pyboard where these motors can be plugged
|
||||
in: pins X1 through X4 are the signal pins, and next to them are 4 sets of power
|
||||
and ground pins.
|
||||
Servo controls standard hobby servos with 3-wires (ground, power, signal).
|
||||
|
||||
Example usage::
|
||||
|
||||
import pyb
|
||||
|
||||
s1 = pyb.Servo(1) # create a servo object on position X1
|
||||
s2 = pyb.Servo(2) # create a servo object on position X2
|
||||
|
||||
s1.angle(45) # move servo 1 to 45 degrees
|
||||
s2.angle(0) # move servo 2 to 0 degrees
|
||||
|
||||
# move servo1 and servo2 synchronously, taking 1500ms
|
||||
s1.angle(-60, 1500)
|
||||
s2.angle(30, 1500)
|
||||
|
||||
.. note:: The Servo objects use Timer(5) to produce the PWM output. You can
|
||||
use Timer(5) for Servo control, or your own purposes, but not both at the
|
||||
same time.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.Servo(id)
|
||||
|
||||
Create a servo object. ``id`` is 1-4, and corresponds to pins X1 through X4.
|
||||
Create a servo object. ``id`` is 1-4.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Servo.angle([angle, time=0])
|
||||
|
||||
If no arguments are given, this function returns the current angle.
|
||||
|
||||
If arguments are given, this function sets the angle of the servo:
|
||||
.. method:: servo.angle([angle, time=0])
|
||||
|
||||
Get or set the angle of the servo.
|
||||
|
||||
- ``angle`` is the angle to move to in degrees.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified
|
||||
angle. If omitted, then the servo moves as quickly as possible to its
|
||||
new position.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified angle.
|
||||
|
||||
.. method:: Servo.speed([speed, time=0])
|
||||
.. method:: servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]])
|
||||
|
||||
If no arguments are given, this function returns the current speed.
|
||||
Get or set the calibration of the servo timing.
|
||||
|
||||
If arguments are given, this function sets the speed of the servo:
|
||||
.. method:: servo.pulse_width([value])
|
||||
|
||||
- ``speed`` is the speed to change to, between -100 and 100.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified
|
||||
speed. If omitted, then the servo accelerates as quickly as possible.
|
||||
Get or set the pulse width in milliseconds.
|
||||
|
||||
.. method:: Servo.pulse_width([value])
|
||||
.. method:: servo.speed([speed, time=0])
|
||||
|
||||
If no arguments are given, this function returns the current raw pulse-width
|
||||
value.
|
||||
|
||||
If an argument is given, this function sets the raw pulse-width value.
|
||||
|
||||
.. method:: Servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]])
|
||||
|
||||
If no arguments are given, this function returns the current calibration
|
||||
data, as a 5-tuple.
|
||||
|
||||
If arguments are given, this function sets the timing calibration:
|
||||
|
||||
- ``pulse_min`` is the minimum allowed pulse width.
|
||||
- ``pulse_max`` is the maximum allowed pulse width.
|
||||
- ``pulse_centre`` is the pulse width corresponding to the centre/zero position.
|
||||
- ``pulse_angle_90`` is the pulse width corresponding to 90 degrees.
|
||||
- ``pulse_speed_100`` is the pulse width corresponding to a speed of 100.
|
||||
Get or set the speed of a continuous rotation servo.
|
||||
|
||||
- ``speed`` is the speed to move to change to, between -100 and 100.
|
||||
- ``time`` is the number of milliseconds to take to get to the specified speed.
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Switch:
|
||||
|
||||
class Switch -- switch object
|
||||
=============================
|
||||
|
||||
|
@ -9,8 +6,7 @@ A Switch object is used to control a push-button switch.
|
|||
Usage::
|
||||
|
||||
sw = pyb.Switch() # create a switch object
|
||||
sw.value() # get state (True if pressed, False otherwise)
|
||||
sw() # shorthand notation to get the switch state
|
||||
sw() # get state (True if pressed, False otherwise)
|
||||
sw.callback(f) # register a callback to be called when the
|
||||
# switch is pressed down
|
||||
sw.callback(None) # remove the callback
|
||||
|
@ -31,16 +27,11 @@ Constructors
|
|||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Switch.__call__()
|
||||
.. method:: switch()
|
||||
|
||||
Call switch object directly to get its state: ``True`` if pressed down,
|
||||
``False`` otherwise.
|
||||
Return the switch state: ``True`` if pressed down, ``False`` otherwise.
|
||||
|
||||
.. method:: Switch.value()
|
||||
|
||||
Get the switch state. Returns ``True`` if pressed down, otherwise ``False``.
|
||||
|
||||
.. method:: Switch.callback(fun)
|
||||
.. method:: switch.callback(fun)
|
||||
|
||||
Register the given function to be called when the switch is pressed down.
|
||||
If ``fun`` is ``None``, then it disables the callback.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.Timer:
|
||||
|
||||
class Timer -- control internal timers
|
||||
|
@ -19,13 +18,6 @@ Example usage to toggle an LED at a fixed frequency::
|
|||
tim.init(freq=2) # trigger at 2Hz
|
||||
tim.callback(lambda t:pyb.LED(1).toggle())
|
||||
|
||||
Example using named function for the callback::
|
||||
|
||||
def tick(timer): # we will receive the timer object when being called
|
||||
print(timer.counter()) # show current timer's counter value
|
||||
tim = pyb.Timer(4, freq=1) # create a timer object using timer 4 - trigger at 1Hz
|
||||
tim.callback(tick) # set the callback to our tick function
|
||||
|
||||
Further examples::
|
||||
|
||||
tim = pyb.Timer(4, freq=100) # freq in Hz
|
||||
|
@ -36,18 +28,9 @@ Further examples::
|
|||
tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance)
|
||||
tim.callback(None) # clear callback
|
||||
|
||||
*Note:* Timer(2) and Timer(3) are used for PWM to set the intensity of LED(3)
|
||||
and LED(4) respectively. But these timers are only configured for PWM if
|
||||
the intensity of the relevant LED is set to a value between 1 and 254. If
|
||||
the intensity feature of the LEDs is not used then these timers are free for
|
||||
general purpose use. Similarly, Timer(5) controls the servo driver, and
|
||||
Timer(6) is used for timed ADC/DAC reading/writing. It is recommended to
|
||||
use the other timers in your programs.
|
||||
|
||||
*Note:* Memory can't be allocated during a callback (an interrupt) and so
|
||||
exceptions raised within a callback don't give much information. See
|
||||
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
|
||||
limitation.
|
||||
*Note:* Timer 3 is reserved for internal use. Timer 5 controls
|
||||
the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing.
|
||||
It is recommended to use the other timers in your programs.
|
||||
|
||||
|
||||
Constructors
|
||||
|
@ -57,86 +40,31 @@ Constructors
|
|||
|
||||
Construct a new timer object of the given id. If additional
|
||||
arguments are given, then the timer is initialised by ``init(...)``.
|
||||
``id`` can be 1 to 14.
|
||||
``id`` can be 1 to 14, excluding 3.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: Timer.init(\*, freq, prescaler, period)
|
||||
|
||||
Initialise the timer. Initialisation must be either by frequency (in Hz)
|
||||
or by prescaler and period::
|
||||
|
||||
tim.init(freq=100) # set the timer to trigger at 100Hz
|
||||
tim.init(prescaler=83, period=999) # set the prescaler and period directly
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
- ``freq`` --- specifies the periodic frequency of the timer. You might also
|
||||
view this as the frequency with which the timer goes through one complete cycle.
|
||||
|
||||
- ``prescaler`` [0-0xffff] - specifies the value to be loaded into the
|
||||
timer's Prescaler Register (PSC). The timer clock source is divided by
|
||||
(``prescaler + 1``) to arrive at the timer clock. Timers 2-7 and 12-14
|
||||
have a clock source of 84 MHz (pyb.freq()[2] \* 2), and Timers 1, and 8-11
|
||||
have a clock source of 168 MHz (pyb.freq()[3] \* 2).
|
||||
|
||||
- ``period`` [0-0xffff] for timers 1, 3, 4, and 6-15. [0-0x3fffffff] for timers 2 & 5.
|
||||
Specifies the value to be loaded into the timer's AutoReload
|
||||
Register (ARR). This determines the period of the timer (i.e. when the
|
||||
counter cycles). The timer counter will roll-over after ``period + 1``
|
||||
timer clock cycles.
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``Timer.UP`` - configures the timer to count from 0 to ARR (default)
|
||||
- ``Timer.DOWN`` - configures the timer to count from ARR down to 0.
|
||||
- ``Timer.CENTER`` - configures the timer to count from 0 to ARR and
|
||||
then back down to 0.
|
||||
|
||||
- ``div`` can be one of 1, 2, or 4. Divides the timer clock to determine
|
||||
the sampling clock used by the digital filters.
|
||||
|
||||
- ``callback`` - as per Timer.callback()
|
||||
|
||||
- ``deadtime`` - specifies the amount of "dead" or inactive time between
|
||||
transitions on complimentary channels (both channels will be inactive)
|
||||
for this time). ``deadtime`` may be an integer between 0 and 1008, with
|
||||
the following restrictions: 0-128 in steps of 1. 128-256 in steps of
|
||||
2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadtime``
|
||||
measures ticks of ``source_freq`` divided by ``div`` clock ticks.
|
||||
``deadtime`` is only available on timers 1 and 8.
|
||||
|
||||
You must either specify freq or both of period and prescaler.
|
||||
|
||||
.. method:: Timer.deinit()
|
||||
|
||||
Deinitialises the timer.
|
||||
|
||||
Disables the callback (and the associated irq).
|
||||
|
||||
Disables any channel callbacks (and the associated irq).
|
||||
Stops the timer, and disables the timer peripheral.
|
||||
|
||||
.. method:: Timer.callback(fun)
|
||||
.. method:: timer.callback(fun)
|
||||
|
||||
Set the function to be called when the timer triggers.
|
||||
``fun`` is passed 1 argument, the timer object.
|
||||
If ``fun`` is ``None`` then the callback will be disabled.
|
||||
|
||||
.. method:: Timer.channel(channel, mode, ...)
|
||||
.. method:: timer.channel(channel, mode, ...)
|
||||
|
||||
If only a channel number is passed, then a previously initialized channel
|
||||
object is returned (or ``None`` if there is no previous channel).
|
||||
|
||||
Otherwise, a TimerChannel object is initialized and returned.
|
||||
|
||||
|
||||
Othwerwise, a TimerChannel object is initialized and returned.
|
||||
|
||||
Each channel can be configured to perform pwm, output compare, or
|
||||
input capture. All channels share the same underlying timer, which means
|
||||
that they share the same timer clock.
|
||||
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``Timer.PWM`` --- configure the timer in PWM mode (active high).
|
||||
|
@ -148,73 +76,115 @@ Methods
|
|||
- ``Timer.OC_FORCED_ACTIVE`` --- the pin is forced active (compare match is ignored).
|
||||
- ``Timer.OC_FORCED_INACTIVE`` --- the pin is forced inactive (compare match is ignored).
|
||||
- ``Timer.IC`` --- configure the timer in Input Capture mode.
|
||||
- ``Timer.ENC_A`` --- configure the timer in Encoder mode. The counter only changes when CH1 changes.
|
||||
- ``Timer.ENC_B`` --- configure the timer in Encoder mode. The counter only changes when CH2 changes.
|
||||
- ``Timer.ENC_AB`` --- configure the timer in Encoder mode. The counter changes when CH1 or CH2 changes.
|
||||
|
||||
|
||||
- ``callback`` - as per TimerChannel.callback()
|
||||
|
||||
|
||||
- ``pin`` None (the default) or a Pin object. If specified (and not None)
|
||||
this will cause the alternate function of the the indicated pin
|
||||
to be configured for this timer channel. An error will be raised if
|
||||
the pin doesn't support any alternate functions for this timer channel.
|
||||
|
||||
|
||||
Keyword arguments for Timer.PWM modes:
|
||||
|
||||
|
||||
- ``pulse_width`` - determines the initial pulse width value to use.
|
||||
- ``pulse_width_percent`` - determines the initial pulse width percentage to use.
|
||||
|
||||
|
||||
Keyword arguments for Timer.OC modes:
|
||||
|
||||
|
||||
- ``compare`` - determines the initial value of the compare register.
|
||||
|
||||
|
||||
- ``polarity`` can be one of:
|
||||
|
||||
- ``Timer.HIGH`` - output is active high
|
||||
- ``Timer.LOW`` - output is active low
|
||||
|
||||
- ``Timer.LOW`` - output is acive low
|
||||
|
||||
Optional keyword arguments for Timer.IC modes:
|
||||
|
||||
|
||||
- ``polarity`` can be one of:
|
||||
|
||||
- ``Timer.RISING`` - captures on rising edge.
|
||||
- ``Timer.FALLING`` - captures on falling edge.
|
||||
- ``Timer.BOTH`` - captures on both edges.
|
||||
|
||||
|
||||
Note that capture only works on the primary channel, and not on the
|
||||
complimentary channels.
|
||||
|
||||
Notes for Timer.ENC modes:
|
||||
|
||||
- Requires 2 pins, so one or both pins will need to be configured to use
|
||||
the appropriate timer AF using the Pin API.
|
||||
- Read the encoder value using the timer.counter() method.
|
||||
- Only works on CH1 and CH2 (and not on CH1N or CH2N)
|
||||
- The channel number is ignored when setting the encoder mode.
|
||||
|
||||
|
||||
PWM Example::
|
||||
|
||||
|
||||
timer = pyb.Timer(2, freq=1000)
|
||||
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=8000)
|
||||
ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=16000)
|
||||
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=210000)
|
||||
ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=420000)
|
||||
|
||||
.. method:: Timer.counter([value])
|
||||
.. method:: timer.counter([value])
|
||||
|
||||
Get or set the timer counter.
|
||||
|
||||
.. method:: Timer.freq([value])
|
||||
.. method:: timer.deinit()
|
||||
|
||||
Deinitialises the timer.
|
||||
|
||||
Disables the callback (and the associated irq).
|
||||
Disables any channel callbacks (and the associated irq).
|
||||
Stops the timer, and disables the timer peripheral.
|
||||
|
||||
.. method:: timer.freq([value])
|
||||
|
||||
Get or set the frequency for the timer (changes prescaler and period if set).
|
||||
|
||||
.. method:: Timer.period([value])
|
||||
.. method:: timer.init(\*, freq, prescaler, period)
|
||||
|
||||
Initialise the timer. Initialisation must be either by frequency (in Hz)
|
||||
or by prescaler and period::
|
||||
|
||||
tim.init(freq=100) # set the timer to trigger at 100Hz
|
||||
tim.init(prescaler=83, period=999) # set the prescaler and period directly
|
||||
|
||||
Keyword arguments:
|
||||
|
||||
- ``freq`` --- specifies the periodic frequency of the timer. You migh also
|
||||
view this as the frequency with which the timer goes through one complete cycle.
|
||||
|
||||
- ``prescaler`` [0-0xffff] - specifies the value to be loaded into the
|
||||
timer's Prescaler Register (PSC). The timer clock source is divided by
|
||||
(``prescaler + 1``) to arrive at the timer clock. Timers 2-7 and 12-14
|
||||
have a clock source of 84 MHz (pyb.freq()[2] \* 2), and Timers 1, and 8-11
|
||||
have a clock source of 168 MHz (pyb.freq()[3] \* 2).
|
||||
|
||||
- ``period`` [0-0xffff] for timers 1, 3, 4, and 6-15. [0-0x3fffffff] for timers 2 & 5.
|
||||
Specifies the value to be loaded into the timer's AutoReload
|
||||
Register (ARR). This determines the period of the timer (i.e. when the
|
||||
counter cycles). The timer counter will roll-over after ``period + 1``
|
||||
timer clock cycles.
|
||||
|
||||
- ``mode`` can be one of:
|
||||
|
||||
- ``Timer.UP`` - configures the timer to count from 0 to ARR (default)
|
||||
- ``Timer.DOWN`` - configures the timer to count from ARR down to 0.
|
||||
- ``Timer.CENTER`` - confgures the timer to count from 0 to ARR and
|
||||
then back down to 0.
|
||||
|
||||
- ``div`` can be one of 1, 2, or 4. Divides the timer clock to determine
|
||||
the sampling clock used by the digital filters.
|
||||
|
||||
- ``callback`` - as per Timer.callback()
|
||||
|
||||
- ``deadtime`` - specifies the amount of "dead" or inactive time between
|
||||
transitions on complimentary channels (both channels will be inactive)
|
||||
for this time). ``deadtime`` may be an integer between 0 and 1008, with
|
||||
the following restrictions: 0-128 in steps of 1. 128-256 in steps of
|
||||
2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadime``
|
||||
measures ticks of ``source_freq`` divided by ``div`` clock ticks.
|
||||
``deadtime`` is only available on timers 1 and 8.
|
||||
|
||||
You must either specify freq or both of period and prescaler.
|
||||
|
||||
.. method:: timer.period([value])
|
||||
|
||||
Get or set the period of the timer.
|
||||
|
||||
.. method:: Timer.prescaler([value])
|
||||
.. method:: timer.prescaler([value])
|
||||
|
||||
Get or set the prescaler for the timer.
|
||||
|
||||
.. method:: Timer.source_freq()
|
||||
.. method:: timer.source_freq()
|
||||
|
||||
Get the frequency of the source of the timer.
|
||||
|
||||
|
@ -251,7 +221,7 @@ Methods
|
|||
Get or set the pulse width value associated with a channel.
|
||||
capture, compare, and pulse_width are all aliases for the same function.
|
||||
pulse_width is the logical name to use when the channel is in PWM mode.
|
||||
|
||||
|
||||
In edge aligned mode, a pulse_width of ``period + 1`` corresponds to a duty cycle of 100%
|
||||
In center aligned mode, a pulse width of ``period`` corresponds to a duty cycle of 100%
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.UART:
|
||||
|
||||
class UART -- duplex serial communication bus
|
||||
|
@ -21,11 +20,11 @@ Bits can be 7, 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1
|
|||
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
|
||||
only 7 and 8 bits are supported.
|
||||
|
||||
A UART object acts like a `stream` object and reading and writing is done
|
||||
A UART object acts like a stream object and reading and writing is done
|
||||
using the standard stream methods::
|
||||
|
||||
uart.read(10) # read 10 characters, returns a bytes object
|
||||
uart.read() # read all available characters
|
||||
uart.readall() # read all available characters
|
||||
uart.readline() # read a line
|
||||
uart.readinto(buf) # read and store into the given buffer
|
||||
uart.write('abc') # write the 3 characters
|
||||
|
@ -37,10 +36,9 @@ Individual characters can be read/written using::
|
|||
|
||||
To check if there is anything to be read, use::
|
||||
|
||||
uart.any() # returns the number of characters waiting
|
||||
uart.any() # returns True if any characters waiting
|
||||
|
||||
|
||||
*Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
|
||||
*Note:* The stream functions ``read``, ``write`` etc Are new in Micro Python since v1.3.4.
|
||||
Earlier versions use ``uart.send`` and ``uart.recv``.
|
||||
|
||||
Constructors
|
||||
|
@ -62,14 +60,10 @@ Constructors
|
|||
- ``UART(3)`` is on ``YB``: ``(TX, RX) = (Y9, Y10) = (PB10, PB11)``
|
||||
- ``UART(2)`` is on: ``(TX, RX) = (X3, X4) = (PA2, PA3)``
|
||||
|
||||
The Pyboard Lite supports UART(1), UART(2) and UART(6) only. Pins are as above except:
|
||||
|
||||
- ``UART(2)`` is on: ``(TX, RX) = (X1, X2) = (PA2, PA3)``
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: UART.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=0, flow=0, timeout_char=0, read_buf_len=64)
|
||||
.. method:: uart.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=1000, timeout_char=0, read_buf_len=64)
|
||||
|
||||
Initialise the UART bus with the given parameters:
|
||||
|
||||
|
@ -77,149 +71,66 @@ Methods
|
|||
- ``bits`` is the number of bits per character, 7, 8 or 9.
|
||||
- ``parity`` is the parity, ``None``, 0 (even) or 1 (odd).
|
||||
- ``stop`` is the number of stop bits, 1 or 2.
|
||||
- ``flow`` sets the flow control type. Can be 0, ``UART.RTS``, ``UART.CTS``
|
||||
or ``UART.RTS | UART.CTS``.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for writing/reading the first character.
|
||||
- ``timeout_char`` is the timeout in milliseconds to wait between characters while writing or reading.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the first character.
|
||||
- ``timeout_char`` is the timeout in milliseconds to wait between characters.
|
||||
- ``read_buf_len`` is the character length of the read buffer (0 to disable).
|
||||
|
||||
This method will raise an exception if the baudrate could not be set within
|
||||
5% of the desired value. The minimum baudrate is dictated by the frequency
|
||||
of the bus that the UART is on; UART(1) and UART(6) are APB2, the rest are on
|
||||
APB1. The default bus frequencies give a minimum baudrate of 1300 for
|
||||
UART(1) and UART(6) and 650 for the others. Use :func:`pyb.freq <pyb.freq>`
|
||||
to reduce the bus frequencies to get lower baudrates.
|
||||
|
||||
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
|
||||
only 7 and 8 bits are supported.
|
||||
|
||||
.. method:: UART.deinit()
|
||||
.. method:: uart.deinit()
|
||||
|
||||
Turn off the UART bus.
|
||||
|
||||
.. method:: UART.any()
|
||||
.. method:: uart.any()
|
||||
|
||||
Returns the number of bytes waiting (may be 0).
|
||||
Return ``True`` if any characters waiting, else ``False``.
|
||||
|
||||
.. method:: UART.read([nbytes])
|
||||
.. method:: uart.read([nbytes])
|
||||
|
||||
Read characters. If ``nbytes`` is specified then read at most that many bytes.
|
||||
If ``nbytes`` are available in the buffer, returns immediately, otherwise returns
|
||||
when sufficient characters arrive or the timeout elapses.
|
||||
|
||||
If ``nbytes`` is not given then the method reads as much data as possible. It
|
||||
returns after the timeout has elapsed.
|
||||
|
||||
*Note:* for 9 bit characters each character takes two bytes, ``nbytes`` must
|
||||
be even, and the number of characters is ``nbytes/2``.
|
||||
|
||||
Return value: a bytes object containing the bytes read in. Returns ``None``
|
||||
Return value: a bytes object containing the bytes read in. Returns ``b''``
|
||||
on timeout.
|
||||
|
||||
.. method:: UART.readchar()
|
||||
.. method:: uart.readall()
|
||||
|
||||
Read as much data as possible.
|
||||
|
||||
Return value: a bytes object.
|
||||
|
||||
.. method:: uart.readchar()
|
||||
|
||||
Receive a single character on the bus.
|
||||
|
||||
Return value: The character read, as an integer. Returns -1 on timeout.
|
||||
|
||||
.. method:: UART.readinto(buf[, nbytes])
|
||||
.. method:: uart.readinto(buf[, nbytes])
|
||||
|
||||
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
|
||||
that many bytes. Otherwise, read at most ``len(buf)`` bytes.
|
||||
|
||||
Return value: number of bytes read and stored into ``buf`` or ``None`` on
|
||||
timeout.
|
||||
Return value: number of bytes read and stored into ``buf``.
|
||||
|
||||
.. method:: UART.readline()
|
||||
.. method:: uart.readline()
|
||||
|
||||
Read a line, ending in a newline character. If such a line exists, return is
|
||||
immediate. If the timeout elapses, all available data is returned regardless
|
||||
of whether a newline exists.
|
||||
Read a line, ending in a newline character.
|
||||
|
||||
Return value: the line read or ``None`` on timeout if no data is available.
|
||||
Return value: the line read.
|
||||
|
||||
.. method:: UART.write(buf)
|
||||
.. method:: uart.write(buf)
|
||||
|
||||
Write the buffer of bytes to the bus. If characters are 7 or 8 bits wide
|
||||
then each byte is one character. If characters are 9 bits wide then two
|
||||
bytes are used for each character (little endian), and ``buf`` must contain
|
||||
an even number of bytes.
|
||||
|
||||
Return value: number of bytes written. If a timeout occurs and no bytes
|
||||
were written returns ``None``.
|
||||
Return value: number of bytes written.
|
||||
|
||||
.. method:: UART.writechar(char)
|
||||
.. method:: uart.writechar(char)
|
||||
|
||||
Write a single character on the bus. ``char`` is an integer to write.
|
||||
Return value: ``None``. See note below if CTS flow control is used.
|
||||
|
||||
.. method:: UART.sendbreak()
|
||||
|
||||
Send a break condition on the bus. This drives the bus low for a duration
|
||||
of 13 bits.
|
||||
Return value: ``None``.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: UART.RTS
|
||||
UART.CTS
|
||||
|
||||
to select the flow control type.
|
||||
|
||||
Flow Control
|
||||
------------
|
||||
|
||||
On Pyboards V1 and V1.1 ``UART(2)`` and ``UART(3)`` support RTS/CTS hardware flow control
|
||||
using the following pins:
|
||||
|
||||
- ``UART(2)`` is on: ``(TX, RX, nRTS, nCTS) = (X3, X4, X2, X1) = (PA2, PA3, PA1, PA0)``
|
||||
- ``UART(3)`` is on :``(TX, RX, nRTS, nCTS) = (Y9, Y10, Y7, Y6) = (PB10, PB11, PB14, PB13)``
|
||||
|
||||
On the Pyboard Lite only ``UART(2)`` supports flow control on these pins:
|
||||
|
||||
``(TX, RX, nRTS, nCTS) = (X1, X2, X4, X3) = (PA2, PA3, PA1, PA0)``
|
||||
|
||||
In the following paragraphs the term "target" refers to the device connected to
|
||||
the UART.
|
||||
|
||||
When the UART's ``init()`` method is called with ``flow`` set to one or both of
|
||||
``UART.RTS`` and ``UART.CTS`` the relevant flow control pins are configured.
|
||||
``nRTS`` is an active low output, ``nCTS`` is an active low input with pullup
|
||||
enabled. To achieve flow control the Pyboard's ``nCTS`` signal should be connected
|
||||
to the target's ``nRTS`` and the Pyboard's ``nRTS`` to the target's ``nCTS``.
|
||||
|
||||
CTS: target controls Pyboard transmitter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If CTS flow control is enabled the write behaviour is as follows:
|
||||
|
||||
If the Pyboard's ``UART.write(buf)`` method is called, transmission will stall for
|
||||
any periods when ``nCTS`` is ``False``. This will result in a timeout if the entire
|
||||
buffer was not transmitted in the timeout period. The method returns the number of
|
||||
bytes written, enabling the user to write the remainder of the data if required. In
|
||||
the event of a timeout, a character will remain in the UART pending ``nCTS``. The
|
||||
number of bytes composing this character will be included in the return value.
|
||||
|
||||
If ``UART.writechar()`` is called when ``nCTS`` is ``False`` the method will time
|
||||
out unless the target asserts ``nCTS`` in time. If it times out ``OSError 116``
|
||||
will be raised. The character will be transmitted as soon as the target asserts ``nCTS``.
|
||||
|
||||
RTS: Pyboard controls target's transmitter
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If RTS flow control is enabled, behaviour is as follows:
|
||||
|
||||
If buffered input is used (``read_buf_len`` > 0), incoming characters are buffered.
|
||||
If the buffer becomes full, the next character to arrive will cause ``nRTS`` to go
|
||||
``False``: the target should cease transmission. ``nRTS`` will go ``True`` when
|
||||
characters are read from the buffer.
|
||||
|
||||
Note that the ``any()`` method returns the number of bytes in the buffer. Assume a
|
||||
buffer length of ``N`` bytes. If the buffer becomes full, and another character arrives,
|
||||
``nRTS`` will be set False, and ``any()`` will return the count ``N``. When
|
||||
characters are read the additional character will be placed in the buffer and will
|
||||
be included in the result of a subsequent ``any()`` call.
|
||||
|
||||
If buffered input is not used (``read_buf_len`` == 0) the arrival of a character will
|
||||
cause ``nRTS`` to go ``False`` until the character is read.
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.USB_HID:
|
||||
|
||||
class USB_HID -- USB Human Interface Device (HID)
|
||||
=================================================
|
||||
|
||||
The USB_HID class allows creation of an object representing the USB
|
||||
Human Interface Device (HID) interface. It can be used to emulate
|
||||
a peripheral such as a mouse or keyboard.
|
||||
|
||||
Before you can use this class, you need to use :meth:`pyb.usb_mode()` to set the USB mode to include the HID interface.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.USB_HID()
|
||||
|
||||
Create a new USB_HID object.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: USB_HID.recv(data, \*, timeout=5000)
|
||||
|
||||
Receive data on the bus:
|
||||
|
||||
- ``data`` can be an integer, which is the number of bytes to receive,
|
||||
or a mutable buffer, which will be filled with received bytes.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
Return value: if ``data`` is an integer then a new buffer of the bytes received,
|
||||
otherwise the number of bytes read into ``data`` is returned.
|
||||
|
||||
.. method:: USB_HID.send(data)
|
||||
|
||||
Send data over the USB HID interface:
|
||||
|
||||
- ``data`` is the data to send (a tuple/list of integers, or a
|
||||
bytearray).
|
|
@ -1,10 +1,7 @@
|
|||
.. currentmodule:: pyb
|
||||
.. _pyb.USB_VCP:
|
||||
|
||||
class USB_VCP -- USB virtual comm port
|
||||
======================================
|
||||
|
||||
The USB_VCP class allows creation of a `stream`-like object representing the USB
|
||||
The USB_VCP class allows creation of an object representing the USB
|
||||
virtual comm port. It can be used to read and write data over USB to
|
||||
the connected host.
|
||||
|
||||
|
@ -12,22 +9,15 @@ the connected host.
|
|||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: pyb.USB_VCP(id=0)
|
||||
.. class:: pyb.USB_VCP()
|
||||
|
||||
Create a new USB_VCP object. The *id* argument specifies which USB VCP port to
|
||||
use.
|
||||
Create a new USB_VCP object.
|
||||
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: USB_VCP.init(\*, flow=-1)
|
||||
|
||||
Configure the USB VCP port. If the *flow* argument is not -1 then the value sets
|
||||
the flow control, which can be a bitwise-or of ``USB_VCP.RTS`` and ``USB_VCP.CTS``.
|
||||
RTS is used to control read behaviour and CTS, to control write behaviour.
|
||||
|
||||
.. method:: USB_VCP.setinterrupt(chr)
|
||||
.. method:: usb_vcp.setinterrupt(chr)
|
||||
|
||||
Set the character which interrupts running Python code. This is set
|
||||
to 3 (CTRL-C) by default, and when a CTRL-C character is received over
|
||||
|
@ -36,84 +26,41 @@ Methods
|
|||
Set to -1 to disable this interrupt feature. This is useful when you
|
||||
want to send raw bytes over the USB VCP port.
|
||||
|
||||
.. method:: USB_VCP.isconnected()
|
||||
|
||||
Return ``True`` if USB is connected as a serial device, else ``False``.
|
||||
|
||||
.. method:: USB_VCP.any()
|
||||
.. method:: usb_vcp.any()
|
||||
|
||||
Return ``True`` if any characters waiting, else ``False``.
|
||||
|
||||
.. method:: USB_VCP.close()
|
||||
.. method:: usb_vcp.close()
|
||||
|
||||
This method does nothing. It exists so the USB_VCP object can act as
|
||||
a file.
|
||||
|
||||
.. method:: USB_VCP.read([nbytes])
|
||||
.. method:: usb_vcp.read([nbytes])
|
||||
|
||||
Read at most ``nbytes`` from the serial device and return them as a
|
||||
bytes object. If ``nbytes`` is not specified then the method reads
|
||||
all available bytes from the serial device.
|
||||
USB_VCP `stream` implicitly works in non-blocking mode,
|
||||
so if no pending data available, this method will return immediately
|
||||
with ``None`` value.
|
||||
|
||||
.. method:: USB_VCP.readinto(buf, [maxlen])
|
||||
.. method:: usb_vcp.readall()
|
||||
|
||||
Read bytes from the serial device and store them into ``buf``, which
|
||||
should be a buffer-like object. At most ``len(buf)`` bytes are read.
|
||||
If ``maxlen`` is given and then at most ``min(maxlen, len(buf))`` bytes
|
||||
are read.
|
||||
|
||||
Returns the number of bytes read and stored into ``buf`` or ``None``
|
||||
if no pending data available.
|
||||
.. method:: usb_vcp.readline()
|
||||
|
||||
.. method:: USB_VCP.readline()
|
||||
|
||||
Read a whole line from the serial device.
|
||||
|
||||
Returns a bytes object containing the data, including the trailing
|
||||
newline character or ``None`` if no pending data available.
|
||||
|
||||
.. method:: USB_VCP.readlines()
|
||||
|
||||
Read as much data as possible from the serial device, breaking it into
|
||||
lines.
|
||||
|
||||
Returns a list of bytes objects, each object being one of the lines.
|
||||
Each line will include the newline character.
|
||||
|
||||
.. method:: USB_VCP.write(buf)
|
||||
|
||||
Write the bytes from ``buf`` to the serial device.
|
||||
|
||||
Returns the number of bytes written.
|
||||
|
||||
.. method:: USB_VCP.recv(data, \*, timeout=5000)
|
||||
.. method:: usb_vcp.recv(data, \*, timeout=5000)
|
||||
|
||||
Receive data on the bus:
|
||||
|
||||
|
||||
- ``data`` can be an integer, which is the number of bytes to receive,
|
||||
or a mutable buffer, which will be filled with received bytes.
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the receive.
|
||||
|
||||
|
||||
Return value: if ``data`` is an integer then a new buffer of the bytes received,
|
||||
otherwise the number of bytes read into ``data`` is returned.
|
||||
|
||||
.. method:: USB_VCP.send(data, \*, timeout=5000)
|
||||
.. method:: usb_vcp.send(data, \*, timeout=5000)
|
||||
|
||||
Send data over the USB VCP:
|
||||
|
||||
|
||||
- ``data`` is the data to send (an integer to send, or a buffer object).
|
||||
- ``timeout`` is the timeout in milliseconds to wait for the send.
|
||||
|
||||
|
||||
Return value: number of bytes sent.
|
||||
|
||||
.. method:: usb_vcp.write(buf)
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: USB_VCP.RTS
|
||||
USB_VCP.CTS
|
||||
|
||||
to select the flow control type.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue