Browse Source

Initial commit

v1.0.2-dev
Ken 4 years ago
commit
22abc7086e
  1. 26
      .gitattributes
  2. 57
      .gitignore
  3. 32
      .gitmodules
  4. 19
      .reuse/dep5
  5. 265
      .travis.yml
  6. 1764
      ACKNOWLEDGEMENTS
  7. 210
      CODECONVENTIONS.md
  8. 53
      CODEOFCONDUCT.md
  9. 8
      CONTRIBUTING.md
  10. 163
      DEVELOPMENT.md
  11. 208
      LICENSES/Apache-2.0.txt
  12. 47
      LICENSES/BSD-2-Clause-Patent.txt
  13. 22
      LICENSES/BSD-2-Clause.txt
  14. 26
      LICENSES/BSD-3-Clause.txt
  15. 625
      LICENSES/GPL-3.0-only.txt
  16. 625
      LICENSES/GPL-3.0-or-later.txt
  17. 15
      LICENSES/ISC.txt
  18. 21
      LICENSES/MIT.txt
  19. 22
      LICENSES/Unlicense.txt
  20. 188
      README-MP.md
  21. 13
      README.md
  22. 191
      docs/Makefile
  23. 38
      docs/README.md
  24. 301
      docs/conf.py
  25. 180
      docs/develop/cmodules.rst
  26. 14
      docs/develop/index.rst
  27. 202
      docs/develop/natmod.rst
  28. 112
      docs/develop/qstr.rst
  29. 11
      docs/differences/index_template.txt
  30. 64
      docs/esp32/general.rst
  31. BIN
      docs/esp32/img/esp32.jpg
  32. 519
      docs/esp32/quickref.rst
  33. 139
      docs/esp32/tutorial/intro.rst
  34. 197
      docs/esp8266/general.rst
  35. BIN
      docs/esp8266/img/adafruit_products_pinoutstop.jpg
  36. 394
      docs/esp8266/quickref.rst
  37. 19
      docs/esp8266/tutorial/adc.rst
  38. 91
      docs/esp8266/tutorial/apa102.rst
  39. 65
      docs/esp8266/tutorial/dht.rst
  40. 69
      docs/esp8266/tutorial/filesystem.rst
  41. 34
      docs/esp8266/tutorial/index.rst
  42. 202
      docs/esp8266/tutorial/intro.rst
  43. 84
      docs/esp8266/tutorial/neopixel.rst
  44. 81
      docs/esp8266/tutorial/network_basics.rst
  45. 122
      docs/esp8266/tutorial/network_tcp.rst
  46. 12
      docs/esp8266/tutorial/nextsteps.rst
  47. 37
      docs/esp8266/tutorial/onewire.rst
  48. 76
      docs/esp8266/tutorial/pins.rst
  49. 61
      docs/esp8266/tutorial/powerctrl.rst
  50. 87
      docs/esp8266/tutorial/pwm.rst
  51. 212
      docs/esp8266/tutorial/repl.rst
  52. 14
      docs/index.rst
  53. 12
      docs/library/_thread.rst
  54. 159
      docs/library/btree.rst
  55. 199
      docs/library/builtins.rst
  56. 63
      docs/library/cmath.rst
  57. 101
      docs/library/esp.rst
  58. 202
      docs/library/esp32.rst
  59. 161
      docs/library/framebuf.rst
  60. 66
      docs/library/gc.rst
  61. 166
      docs/library/index.rst
  62. 394
      docs/library/lcd160cr.rst
  63. 35
      docs/library/machine.ADC.rst
  64. 81
      docs/library/machine.ADCWiPy.rst
  65. 180
      docs/library/machine.I2C.rst
  66. 254
      docs/library/machine.Pin.rst
  67. 69
      docs/library/machine.RTC.rst
  68. 47
      docs/library/machine.SD.rst
  69. 122
      docs/library/machine.SDCard.rst
  70. 101
      docs/library/machine.SPI.rst
  71. 123
      docs/library/machine.Signal.rst
  72. 64
      docs/library/machine.Timer.rst
  73. 159
      docs/library/machine.TimerWiPy.rst
  74. 152
      docs/library/machine.UART.rst
  75. 36
      docs/library/machine.WDT.rst
  76. 171
      docs/library/machine.rst
  77. 185
      docs/library/math.rst
  78. 140
      docs/library/micropython.rst
  79. 89
      docs/library/network.CC3K.rst
  80. 71
      docs/library/network.WIZNET5K.rst
  81. 132
      docs/library/network.WLAN.rst
  82. 161
      docs/library/network.WLANWiPy.rst
  83. 173
      docs/library/network.rst
  84. 167
      docs/library/pyb.ADC.rst
  85. 57
      docs/library/pyb.Accel.rst
  86. 300
      docs/library/pyb.CAN.rst
  87. 124
      docs/library/pyb.DAC.rst
  88. 114
      docs/library/pyb.ExtInt.rst
  89. 52
      docs/library/pyb.Flash.rst
  90. 165
      docs/library/pyb.I2C.rst
  91. 97
      docs/library/pyb.LCD.rst
  92. 46
      docs/library/pyb.LED.rst
  93. 268
      docs/library/pyb.Pin.rst
  94. 78
      docs/library/pyb.RTC.rst
  95. 122
      docs/library/pyb.SPI.rst
  96. 80
      docs/library/pyb.Servo.rst
  97. 46
      docs/library/pyb.Switch.rst
  98. 264
      docs/library/pyb.Timer.rst
  99. 225
      docs/library/pyb.UART.rst
  100. 40
      docs/library/pyb.USB_HID.rst

26
.gitattributes

@ -0,0 +1,26 @@
# 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

57
.gitignore

@ -0,0 +1,57 @@
# Compiled Sources
###################
*.o
*.a
*.elf
*.bin
*.map
*.hex
*.dis
*.exe
# Packages
############
# Logs and Databases
######################
*.log
# VIM Swap Files
######################
*.swp
# Build directories
######################
build/
build-*/
# Test failure outputs
######################
tests/*.exp
tests/*.out
# Python cache files
######################
__pycache__/
*.pyc
# Customized Makefile/project overrides
######################
GNUmakefile
user.props
# Generated rst files
######################
genrst/
ports/stm32/boards/Passport/finalbootloader/bootloader.bin.tmp
ports/stm32/boards/Passport/finalbootloader/bootloader.lss
ports/stm32/boards/Passport/finalbootloader/bootloader.sym
*.d
ports/stm32/boards/Passport/tools/signit/x86/release/
ports/stm32/boards/Passport/tools/cosign/x86/release/

32
.gitmodules

@ -0,0 +1,32 @@
[submodule "lib/axtls"]
path = lib/axtls
url = https://github.com/pfalcon/axtls
branch = micropython
[submodule "lib/libffi"]
path = lib/libffi
url = https://github.com/atgreen/libffi
[submodule "lib/lwip"]
path = lib/lwip
url = https://git.savannah.gnu.org/r/lwip.git
[submodule "lib/berkeley-db-1.xx"]
path = lib/berkeley-db-1.xx
url = https://github.com/pfalcon/berkeley-db-1.xx
[submodule "lib/stm32lib"]
path = lib/stm32lib
url = https://github.com/micropython/stm32lib
branch = work-F4-1.13.1+F7-1.5.0+L4-1.3.0
[submodule "lib/nrfx"]
path = lib/nrfx
url = https://github.com/NordicSemiconductor/nrfx.git
[submodule "lib/mbedtls"]
path = lib/mbedtls
url = https://github.com/ARMmbed/mbedtls.git
[submodule "lib/asf4"]
path = lib/asf4
url = https://github.com/adafruit/asf4
[submodule "lib/tinyusb"]
path = lib/tinyusb
url = https://github.com/hathach/tinyusb
[submodule "lib/mynewt-nimble"]
path = lib/mynewt-nimble
url = https://github.com/apache/mynewt-nimble.git

19
.reuse/dep5

@ -0,0 +1,19 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Passport
Upstream-Contact: hello@foundationdevices.com
Source: https://git.example.com/FoundationDevices/passport
Files: ACKNOWLEDGEMENTS *.md docs/* drivers/* examples/* extmod/* lib/* py/* tests/* tools/* .gitattributes .gitignore .gitmodules .travis.yml logo/* mpy-cross/*
Copyright: Copyright (c) 2016-2020 Damien P. George (http://micropython.org/)
License: MIT
Files: ports/bare-arm/* ports/cc3200/* ports/esp32/* ports/esp8266/* ports/javascript/* ports/minimal/* ports/nrf/* ports/pic16bit/* ports/powerpc/* ports/qemu/* ports/qemu-arm/* ports/samd/* ports/teensy/* ports/unix/* ports/windows/* ports/zephyr/*
Copyright: Copyright (c) 2016-2020 Damien P. George (http://micropython.org/)
License: MIT
Files: ports/stm32/*
Copyright: Copyright (c) 2016-2020 Damien P. George (http://micropython.org/)
License: MIT
Copyright: 020 Foundation Devices, Inc. <hello@foundationdevices.com>
License: GPL-3.0-or-later

265
.travis.yml

@ -0,0 +1,265 @@
# global options
dist: xenial
language:
- c
compiler:
- gcc
cache:
directories:
- "${HOME}/persist"
env:
global:
- MAKEOPTS="-j4"
git:
submodules: false
# define the successive stages
stages:
- name: test
# 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
# 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
# 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-

1764
ACKNOWLEDGEMENTS

File diff suppressed because it is too large

210
CODECONVENTIONS.md

@ -0,0 +1,210 @@
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
=======================
Python code follows [PEP 8](http://legacy.python.org/dev/peps/pep-0008/).
Naming conventions:
- Module names are short and all lowercase; eg pyb, stm.
- Class names are CamelCase, with abreviations all uppercase; eg I2C, not
I2c.
- Function and method names are all lowercase with words separated by
a single underscore as necessary to improve readability; eg mem_read.
- Constants are all uppercase with words separated by a single underscore;
eg GPIO_IDR.
C code conventions
==================
When writing new C code, please adhere to the following conventions.
White space:
- Expand tabs to 4 spaces.
- Don't leave trailing whitespace at the end of a line.
- For control blocks (if, for, while), put 1 space between the
keyword and the opening parenthesis.
- Put 1 space after a comma, and 1 space around operators.
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
a new line.
- For else-statements, put the else on the same line as the previous
closing brace.
Header files:
- Header files should be protected from multiple inclusion with #if
directives. See an existing header for naming convention.
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.
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:
- 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
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:
#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);
} else {
foo(x + TO_ADD, some_value - 1);
}
for (int my_counter = 0; my_counter < x; my_counter++) {
}
}
Type declarations:
typedef struct _my_struct_t {
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

53
CODEOFCONDUCT.md

@ -0,0 +1,53 @@
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/

8
CONTRIBUTING.md

@ -0,0 +1,8 @@
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

163
DEVELOPMENT.md

@ -0,0 +1,163 @@
# Development
This document describes how to develop for Passport.
## Installation
### Get the Source Code
The instructions below assume you are installing into your home folder at `~/`. You can choose
to install to a different folder, and just update the `cd` commands appropriately.
cd ~/
git clone git@github.com:Foundation-Devices/passport-ng.git
### Install Dependencies
Several tools are required for building and debugging Passport.
#### Cross-Compiler Toolchain
sudo apt install gcc-arm-none-eabi
cd ~/passport-ng
make -C mpy-cross
#### Autotools and USB
sudo apt install autotools-dev
sudo apt install automake
sudo apt install libusb-1.0-0-dev
sudo apt install libtool
#### OpenOCD - On-Chip Debugger
cd ~/
git clone https://github.com/ntfreak/openocd.git
cd ~/openocd/
./bootstrap
./configure --enable-stlink
make
sudo make install
#### RShell - Micropython Shell and REPL
cd ~/
git clone https://github.com/dhylands/rshell
sudo apt install python3-pip
sudo pip3 install rshell (this should install rshell in /usr/local/ area)
## Building
### Open Shell Windows/Tabs
You will need several shell windows or tabs open to interact with the various tools.
### Build Window
#### Building the Main Firmare
In one shell, make sure that you `cd` to the root `stm32` source folder, e.g., `cd ~/passport-ng/ports/stm32`:
make BOARD=Passport
To include debug symbols for use in `ddd`, run the following:
make BOARD=Passport DEBUG=1
You should see it building various `.c` files and freezing `.py` files. Once complete, the final output should look similar to the following:
LINK build-Passport/firmware.elf
text data bss dec hex filename
475304 792 57600 533696 824c0 build-Passport/firmware.elf
GEN build-Passport/firmware.dfu
GEN build-Passport/firmware.hex
#### Code Signing
In order to load the files onto the device, they need to first be signed by two separate keys.
The `cosign` program performs this task, and it needs to be called twice with two separate
private keys.
First, you need to build the `cosign` tool and copy it somewhere in your `PATH`:
cd ports/stm32/boards/Passport/tools/cosign
make
cp x86/release/cosign ~/.local/bin # You can run `echo $PATH` to see the list of possible places you can put this file
Next you want to sign the firmware twice. The `cosign` tool appends `-signed` to the end of the main filename each time it signs.
Assuming you are still in the `ports/stm32` folder run the following:
# TODO: Update once actual signing is implemented
cosign -f build-Passport/firmware.bin -k 1 -v 0.9
cosign -f build-Passport/firmware-signed.bin -k 2
You can also dump the contents of the firmware header with the following command:
cosign -f build-Passport/firmware-signed-signed.bin -x
#### Building the Bootloader
To build the bootloader do the following:
cd ports/stm32/boards/Passport/finalbootloader folder
make
### OpenOCD Server Window
OpenOCD server provides a socket on `localhost:4444` that you can connect to and issue commands. This server acts as an intermediary between that socket and the board connected over JTAG.
Once the OpenOCD server is running, you can pretty much ignore this window. You will interact with the OpenOCD client window (see below). Open a second shell and run the following:
/usr/local/bin/openocd -f stlink.cfg -c "adapter speed 1000; transport select hla_swd" -f stm32h7x.cfg
You should see output similar to the following:
Open On-Chip Debugger 0.10.0+dev-01383-gd46f28c2e-dirty (2020-08-24-08:31)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
hla_swd
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1800 kHz
Info : STLINK V2J29S7 (API v2) VID:PID 0483:3748
Info : Target voltage: 2.975559
Info : stm32h7x.cpu0: hardware has 8 breakpoints, 4 watchpoints
Info : starting gdb server for stm32h7x.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
### OpenOCD Client Window (aka `telnet` Window)
We use `telnet` to connect to the OpenOCD Server. Open a third shell and run the following:
telnet localhost 4444
From here can connect over JTAG and run a range of commands (see the help for OpenOCD for details):
Whenever you change any code in the `finalbootlaoder` folder or in the `common` folder, you will need to rebuild the bootloader (see above), and then flash it to the device with the following sequence in OpenOCD:
reset halt
flash write_image erase boards/Passport/finalbootloader/bootloader.bin 0x8000000
reset
The following command sequence is one you will run repeatedly (i.e., after each build):
reset halt
flash write_image erase build-Passport/firmware-signed-signed.bin 0x8020000
reset
These commands do the following:
- Stop execution of code on the MCU
- Write part 0 of the firmware to flash at address 0x8000000
- Write part 1 of the firmware to flash at address 0x8040000
- Reset the MCU and start executing code at address 0x8000000
### RShell Window
We use `rshell` to connect to the MicroPython device over USB serial. Open another shell and run:
sudo rshell -p /dev/ttyUSB0
This gives us an interactive shell where we can do things like inspect the flash file system, or run a REPL:
- `ls -la /flash` - Get a listing of the files in `/flash` on the device
- `cp local_folder/my_math.py /flash` - Copy a local file into `/flash`
- `repl` - Open a MicroPython REPL. If there are any files in `/flash`, you can import them. For example:
```
import my_math
my_math.add(1, 2)
```

208
LICENSES/Apache-2.0.txt

@ -0,0 +1,208 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution
as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct
or indirect, to cause the direction or management of such entity, whether
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation
or translation of a Source form, including but not limited to compiled object
code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form,
made available under the License, as indicated by a copyright notice that
is included in or attached to the work (an example is provided in the Appendix
below).
"Derivative Works" shall mean any work, whether in Source or Object form,
that is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative
Works shall not include works that remain separable from, or merely link (or
bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative
Works thereof, that is intentionally submitted to Licensor for inclusion in
the Work by the copyright owner or by an individual or Legal Entity authorized
to submit on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication
sent to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor
for the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently incorporated
within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License,
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section) patent
license to make, have made, use, offer to sell, sell, import, and otherwise
transfer the Work, where such license applies only to those patent claims
licensable by such Contributor that are necessarily infringed by their Contribution(s)
alone or by combination of their Contribution(s) with the Work to which such
Contribution(s) was submitted. If You institute patent litigation against
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
that the Work or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses granted to You
under this License for that Work shall terminate as of the date such litigation
is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or
Derivative Works thereof in any medium, with or without modifications, and
in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy
of this License; and
(b) You must cause any modified files to carry prominent notices stating that
You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source
form of the Work, excluding those notices that do not pertain to any part
of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable copy
of the attribution notices contained within such NOTICE file, excluding those
notices that do not pertain to any part of the Derivative Works, in at least
one of the following places: within a NOTICE text file distributed as part
of the Derivative Works; within the Source form or documentation, if provided
along with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works
that You distribute, alongside or as an addendum to the NOTICE text from the
Work, provided that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction,
or distribution of Your modifications, or for any such Derivative Works as
a whole, provided Your use, reproduction, and distribution of the Work otherwise
complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any
Contribution intentionally submitted for inclusion in the Work by You to the
Licensor shall be under the terms and conditions of this License, without
any additional terms or conditions. Notwithstanding the above, nothing herein
shall supersede or modify the terms of any separate license agreement you
may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names,
trademarks, service marks, or product names of the Licensor, except as required
for reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
in writing, Licensor provides the Work (and each Contributor provides its
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied, including, without limitation, any warranties
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
of using or redistributing the Work and assume any risks associated with Your
exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether
in tort (including negligence), contract, or otherwise, unless required by
applicable law (such as deliberate and grossly negligent acts) or agreed to
in writing, shall any Contributor be liable to You for damages, including
any direct, indirect, special, incidental, or consequential damages of any
character arising as a result of this License or out of the use or inability
to use the Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all other commercial
damages or losses), even if such Contributor has been advised of the possibility
of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work
or Derivative Works thereof, You may choose to offer, and charge a fee for,
acceptance of support, warranty, indemnity, or other liability obligations
and/or rights consistent with this License. However, in accepting such obligations,
You may act only on Your own behalf and on Your sole responsibility, not on
behalf of any other Contributor, and only if You agree to indemnify, defend,
and hold each Contributor harmless for any liability incurred by, or claims
asserted against, such Contributor by reason of your accepting any such warranty
or additional liability. END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
information. (Don't include the brackets!) The text should be enclosed in
the appropriate comment syntax for the file format. We also recommend that
a file or class name and description of purpose be included on the same "printed
page" as the copyright notice for easier identification within third-party
archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

47
LICENSES/BSD-2-Clause-Patent.txt

@ -0,0 +1,47 @@
Copyright (c) 2020 Foundation Devices, Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
Subject to the terms and conditions of this license, each copyright holder
and contributor hereby grants to those receiving rights under this license
a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except for failure to satisfy the conditions of this license) patent license
to make, have made, use, offer to sell, sell, import, and otherwise transfer
this software, where such license applies only to those patent claims, already
acquired or hereafter acquired, licensable by such copyright holder or contributor
that are necessarily infringed by:
(a) their Contribution(s) (the licensed copyrights of copyright holders and
non-copyrightable additions of contributors, in source or binary form) alone;
or
(b) combination of their Contribution(s) with the work of authorship to which
such Contribution(s) was added by such copyright holder or contributor, if,
at the time the Contribution is added, such addition causes such combination
to be necessarily infringed. The patent license shall not apply to any other
combinations which include the Contribution.
Except as expressly stated above, no rights or licenses from any copyright
holder or contributor is granted under this license, whether expressly, by
implication, estoppel or otherwise.
DISCLAIMER
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
LICENSES/BSD-2-Clause.txt

@ -0,0 +1,22 @@
Copyright (c) <year> <owner> All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

26
LICENSES/BSD-3-Clause.txt

@ -0,0 +1,26 @@
Copyright (c) <year> <owner>. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

625
LICENSES/GPL-3.0-only.txt

@ -0,0 +1,625 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for software and
other kinds of works.
The licenses for most software and other practical works are designed to take
away your freedom to share and change the works. By contrast, the GNU General
Public License is intended to guarantee your freedom to share and change all
versions of a program--to make sure it remains free software for all its users.
We, the Free Software Foundation, use the GNU General Public License for most
of our software; it applies also to any other work released this way by its
authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for them if you wish), that
you receive source code or can get it if you want it, that you can change
the software or use pieces of it in new free programs, and that you know you
can do these things.
To protect your rights, we need to prevent others from denying you these rights
or asking you to surrender the rights. Therefore, you have certain responsibilities
if you distribute copies of the software, or if you modify it: responsibilities
to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must pass on to the recipients the same freedoms that you received.
You must make sure that they, too, receive or can get the source code. And
you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert
copyright on the software, and (2) offer you this License giving you legal
permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that
there is no warranty for this free software. For both users' and authors'
sake, the GPL requires that modified versions be marked as changed, so that
their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified
versions of the software inside them, although the manufacturer can do so.
This is fundamentally incompatible with the aim of protecting users' freedom
to change the software. The systematic pattern of such abuse occurs in the
area of products for individuals to use, which is precisely where it is most
unacceptable. Therefore, we have designed this version of the GPL to prohibit
the practice for those products. If such problems arise substantially in other
domains, we stand ready to extend this provision to those domains in future
versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States
should not allow patents to restrict development and use of software on general-purpose
computers, but in those that do, we wish to avoid the special danger that
patents applied to a free program could make it effectively proprietary. To
prevent this, the GPL assures that patents cannot be used to render the program
non-free.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of works,
such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this License.
Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
or organizations.
To "modify" a work means to copy from or adapt all or part of the work in
a fashion requiring copyright permission, other than the making of an exact
copy. The resulting work is called a "modified version" of the earlier work
or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based on the
Program.
To "propagate" a work means to do anything with it that, without permission,
would make you directly or secondarily liable for infringement under applicable
copyright law, except executing it on a computer or modifying a private copy.
Propagation includes copying, distribution (with or without modification),
making available to the public, and in some countries other activities as
well.
To "convey" a work means any kind of propagation that enables other parties
to make or receive copies. Mere interaction with a user through a computer
network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices" to the
extent that it includes a convenient and prominently visible feature that
(1) displays an appropriate copyright notice, and (2) tells the user that
there is no warranty for the work (except to the extent that warranties are
provided), that licensees may convey the work under this License, and how
to view a copy of this License. If the interface presents a list of user commands
or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work for making
modifications to it. "Object code" means any non-source form of a work.
A "Standard Interface" means an interface that either is an official standard
defined by a recognized standards body, or, in the case of interfaces specified
for a particular programming language, one that is widely used among developers
working in that language.
The "System Libraries" of an executable work include anything, other than
the work as a whole, that (a) is included in the normal form of packaging
a Major Component, but which is not part of that Major Component, and (b)
serves only to enable use of the work with that Major Component, or to implement
a Standard Interface for which an implementation is available to the public
in source code form. A "Major Component", in this context, means a major essential
component (kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to produce
the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all the source
code needed to generate, install, and (for an executable work) run the object
code and to modify the work, including scripts to control those activities.
However, it does not include the work's System Libraries, or general-purpose
tools or generally available free programs which are used unmodified in performing
those activities but which are not part of the work. For example, Corresponding
Source includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically linked
subprograms that the work is specifically designed to require, such as by
intimate data communication or control flow between those subprograms and
other parts of the work.
The Corresponding Source need not include anything that users can regenerate
automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright
on the Program, and are irrevocable provided the stated conditions are met.
This License explicitly affirms your unlimited permission to run the unmodified
Program. The output from running a covered work is covered by this License
only if the output, given its content, constitutes a covered work. This License
acknowledges your rights of fair use or other equivalent, as provided by copyright
law.
You may make, run and propagate covered works that you do not convey, without
conditions so long as your license otherwise remains in force. You may convey
covered works to others for the sole purpose of having them make modifications
exclusively for you, or provide you with facilities for running those works,
provided that you comply with the terms of this License in conveying all material
for which you do not control copyright. Those thus making or running the covered
works for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of your copyrighted
material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure
under any applicable law fulfilling obligations under article 11 of the WIPO
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention
of technological measures to the extent such circumvention is effected by
exercising rights under this License with respect to the covered work, and
you disclaim any intention to limit operation or modification of the work
as a means of enforcing, against the work's users, your or third parties'
legal rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive
it, in any medium, provided that you conspicuously and appropriately publish
on each copy an appropriate copyright notice; keep intact all notices stating
that this License and any non-permissive terms added in accord with section
7 apply to the code; keep intact all notices of the absence of any warranty;
and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you
may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce
it from the Program, in the form of source code under the terms of section
4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and
giving a relevant date.
b) The work must carry prominent notices stating that it is released under
this License and any conditions added under section 7. This requirement modifies
the requirement in section 4 to "keep intact all notices".
c) You must license the entire work, as a whole, under this License to anyone
who comes into possession of a copy. This License will therefore apply, along
with any applicable section 7 additional terms, to the whole of the work,
and all its parts, regardless of how they are packaged. This License gives
no permission to license the work in any other way, but it does not invalidate
such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate
Legal Notices; however, if the Program has interactive interfaces that do
not display Appropriate Legal Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent works,
which are not by their nature extensions of the covered work, and which are
not combined with it such as to form a larger program, in or on a volume of
a storage or distribution medium, is called an "aggregate" if the compilation
and its resulting copyright are not used to limit the access or legal rights
of the compilation's users beyond what the individual works permit. Inclusion
of a covered work in an aggregate does not cause this License to apply to
the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections
4 and 5, provided that you also convey the machine-readable Corresponding
Source under the terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by the Corresponding Source fixed
on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by a written offer, valid for
at least three years and valid for as long as you offer spare parts or customer
support for that product model, to give anyone who possesses the object code
either (1) a copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical medium customarily
used for software interchange, for a price no more than your reasonable cost
of physically performing this conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written
offer to provide the Corresponding Source. This alternative is allowed only
occasionally and noncommercially, and only if you received the object code
with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis
or for a charge), and offer equivalent access to the Corresponding Source
in the same way through the same place at no further charge. You need not
require recipients to copy the Corresponding Source along with the object
code. If the place to copy the object code is a network server, the Corresponding
Source may be on a different server (operated by you or a third party) that
supports equivalent copying facilities, provided you maintain clear directions
next to the object code saying where to find the Corresponding Source. Regardless
of what server hosts the Corresponding Source, you remain obligated to ensure
that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform
other peers where the object code and Corresponding Source of the work are
being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from
the Corresponding Source as a System Library, need not be included in conveying
the object code work.
A "User Product" is either (1) a "consumer product", which means any tangible
personal property which is normally used for personal, family, or household
purposes, or (2) anything designed or sold for incorporation into a dwelling.
In determining whether a product is a consumer product, doubtful cases shall
be resolved in favor of coverage. For a particular product received by a particular
user, "normally used" refers to a typical or common use of that class of product,
regardless of the status of the particular user or of the way in which the
particular user actually uses, or expects or is expected to use, the product.
A product is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent the
only significant mode of use of the product.
"Installation Information" for a User Product means any methods, procedures,
authorization keys, or other information required to install and execute modified
versions of a covered work in that User Product from a modified version of
its Corresponding Source. The information must suffice to ensure that the
continued functioning of the modified object code is in no case prevented
or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically
for use in, a User Product, and the conveying occurs as part of a transaction
in which the right of possession and use of the User Product is transferred
to the recipient in perpetuity or for a fixed term (regardless of how the
transaction is characterized), the Corresponding Source conveyed under this
section must be accompanied by the Installation Information. But this requirement
does not apply if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has been installed
in ROM).
The requirement to provide Installation Information does not include a requirement
to continue to provide support service, warranty, or updates for a work that
has been modified or installed by the recipient, or for the User Product in
which it has been modified or installed. Access to a network may be denied
when the modification itself materially and adversely affects the operation
of the network or violates the rules and protocols for communication across
the network.
Corresponding Source conveyed, and Installation Information provided, in accord
with this section must be in a format that is publicly documented (and with
an implementation available to the public in source code form), and must require
no special password or key for unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this License
by making exceptions from one or more of its conditions. Additional permissions
that are applicable to the entire Program shall be treated as though they
were included in this License, to the extent that they are valid under applicable
law. If additional permissions apply only to part of the Program, that part
may be used separately under those permissions, but the entire Program remains
governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional
permissions may be written to require their own removal in certain cases when
you modify the work.) You may place additional permissions on material, added
by you to a covered work, for which you have or can give appropriate copyright
permission.
Notwithstanding any other provision of this License, for material you add
to a covered work, you may (if authorized by the copyright holders of that
material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of
sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author
attributions in that material or in the Appropriate Legal Notices displayed
by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring
that modified versions of such material be marked in reasonable ways as different
from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors
of the material; or
e) Declining to grant rights under trademark law for use of some trade names,
trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by
anyone who conveys the material (or modified versions of it) with contractual
assumptions of liability to the recipient, for any liability that these contractual
assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered "further restrictions"
within the meaning of section 10. If the Program as you received it, or any
part of it, contains a notice stating that it is governed by this License
along with a term that is a further restriction, you may remove that term.
If a license document contains a further restriction but permits relicensing
or conveying under this License, you may add to a covered work material governed
by the terms of that license document, provided that the further restriction
does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place,
in the relevant source files, a statement of the additional terms that apply
to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form
of a separately written license, or stated as exceptions; the above requirements
apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided
under this License. Any attempt otherwise to propagate or modify it is void,
and will automatically terminate your rights under this License (including
any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from
a particular copyright holder is reinstated (a) provisionally, unless and
until the copyright holder explicitly and finally terminates your license,
and (b) permanently, if the copyright holder fails to notify you of the violation
by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently
if the copyright holder notifies you of the violation by some reasonable means,
this is the first time you have received notice of violation of this License
(for any work) from that copyright holder, and you cure the violation prior
to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses
of parties who have received copies or rights from you under this License.
If your rights have been terminated and not permanently reinstated, you do
not qualify to receive new licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy
of the Program. Ancillary propagation of a covered work occurring solely as
a consequence of using peer-to-peer transmission to receive a copy likewise
does not require acceptance. However, nothing other than this License grants
you permission to propagate or modify any covered work. These actions infringe
copyright if you do not accept this License. Therefore, by modifying or propagating
a covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives
a license from the original licensors, to run, modify and propagate that work,
subject to this License. You are not responsible for enforcing compliance
by third parties with this License.
An "entity transaction" is a transaction transferring control of an organization,
or substantially all assets of one, or subdividing an organization, or merging
organizations. If propagation of a covered work results from an entity transaction,
each party to that transaction who receives a copy of the work also receives
whatever licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the Corresponding
Source of the work from the predecessor in interest, if the predecessor has
it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights
granted or affirmed under this License. For example, you may not impose a
license fee, royalty, or other charge for exercise of rights granted under
this License, and you may not initiate litigation (including a cross-claim
or counterclaim in a lawsuit) alleging that any patent claim is infringed
by making, using, selling, offering for sale, or importing the Program or
any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this License
of the Program or a work on which the Program is based. The work thus licensed
is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims owned or controlled
by the contributor, whether already acquired or hereafter acquired, that would
be infringed by some manner, permitted by this License, of making, using,
or selling its contributor version, but do not include claims that would be
infringed only as a consequence of further modification of the contributor
version. For purposes of this definition, "control" includes the right to
grant patent sublicenses in a manner consistent with the requirements of this
License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
license under the contributor's essential patent claims, to make, use, sell,
offer for sale, import and otherwise run, modify and propagate the contents
of its contributor version.
In the following three paragraphs, a "patent license" is any express agreement
or commitment, however denominated, not to enforce a patent (such as an express
permission to practice a patent or covenant not to sue for patent infringement).
To "grant" such a patent license to a party means to make such an agreement
or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the
Corresponding Source of the work is not available for anyone to copy, free
of charge and under the terms of this License, through a publicly available
network server or other readily accessible means, then you must either (1)
cause the Corresponding Source to be so available, or (2) arrange to deprive
yourself of the benefit of the patent license for this particular work, or
(3) arrange, in a manner consistent with the requirements of this License,
to extend the patent license to downstream recipients. "Knowingly relying"
means you have actual knowledge that, but for the patent license, your conveying
the covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that country
that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement,
you convey, or propagate by procuring conveyance of, a covered work, and grant
a patent license to some of the parties receiving the covered work authorizing
them to use, propagate, modify or convey a specific copy of the covered work,
then the patent license you grant is automatically extended to all recipients
of the covered work and works based on it.
A patent license is "discriminatory" if it does not include within the scope
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
of one or more of the rights that are specifically granted under this License.
You may not convey a covered work if you are a party to an arrangement with
a third party that is in the business of distributing software, under which
you make payment to the third party based on the extent of your activity of
conveying the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory patent
license (a) in connection with copies of the covered work conveyed by you
(or copies made from those copies), or (b) primarily for and in connection
with specific products or compilations that contain the covered work, unless
you entered into that arrangement, or that patent license was granted, prior
to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied
license or other defenses to infringement that may otherwise be available
to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise)
that contradict the conditions of this License, they do not excuse you from
the conditions of this License. If you cannot convey a covered work so as
to satisfy simultaneously your obligations under this License and any other
pertinent obligations, then as a consequence you may not convey it at all.
For example, if you agree to terms that obligate you to collect a royalty
for further conveying from those to whom you convey the Program, the only
way you could satisfy both those terms and this License would be to refrain
entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to
link or combine any covered work with a work licensed under version 3 of the
GNU Affero General Public License into a single combined work, and to convey
the resulting work. The terms of this License will continue to apply to the
part which is the covered work, but the special requirements of the GNU Affero
General Public License, section 13, concerning interaction through a network
will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the
GNU General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
that a certain numbered version of the GNU General Public License "or any
later version" applies to it, you have the option of following the terms and
conditions either of that numbered version or of any later version published
by the Free Software Foundation. If the Program does not specify a version
number of the GNU General Public License, you may choose any version ever
published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of
the GNU General Public License can be used, that proxy's public statement
of acceptance of a version permanently authorizes you to choose that version
for the Program.
Later license versions may give you additional or different permissions. However,
no additional obligations are imposed on any author or copyright holder as
a result of your choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot
be given local legal effect according to their terms, reviewing courts shall
apply local law that most closely approximates an absolute waiver of all civil
liability in connection with the Program, unless a warranty or assumption
of liability accompanies a copy of the Program in return for a fee. END OF
TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively state the exclusion
of warranty; and each file should have at least the "copyright" line and a
pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like
this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under certain
conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands might
be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General Public
License instead of this License. But first, please read <https://www.gnu.org/
licenses /why-not-lgpl.html>.

625
LICENSES/GPL-3.0-or-later.txt

@ -0,0 +1,625 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for software and
other kinds of works.
The licenses for most software and other practical works are designed to take
away your freedom to share and change the works. By contrast, the GNU General
Public License is intended to guarantee your freedom to share and change all
versions of a program--to make sure it remains free software for all its users.
We, the Free Software Foundation, use the GNU General Public License for most
of our software; it applies also to any other work released this way by its
authors. You can apply it to your programs, too.
When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for them if you wish), that
you receive source code or can get it if you want it, that you can change
the software or use pieces of it in new free programs, and that you know you
can do these things.
To protect your rights, we need to prevent others from denying you these rights
or asking you to surrender the rights. Therefore, you have certain responsibilities
if you distribute copies of the software, or if you modify it: responsibilities
to respect the freedom of others.
For example, if you distribute copies of such a program, whether gratis or
for a fee, you must pass on to the recipients the same freedoms that you received.
You must make sure that they, too, receive or can get the source code. And
you must show them these terms so they know their rights.
Developers that use the GNU GPL protect your rights with two steps: (1) assert
copyright on the software, and (2) offer you this License giving you legal
permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains that
there is no warranty for this free software. For both users' and authors'
sake, the GPL requires that modified versions be marked as changed, so that
their problems will not be attributed erroneously to authors of previous versions.
Some devices are designed to deny users access to install or run modified
versions of the software inside them, although the manufacturer can do so.
This is fundamentally incompatible with the aim of protecting users' freedom
to change the software. The systematic pattern of such abuse occurs in the
area of products for individuals to use, which is precisely where it is most
unacceptable. Therefore, we have designed this version of the GPL to prohibit
the practice for those products. If such problems arise substantially in other
domains, we stand ready to extend this provision to those domains in future
versions of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents. States
should not allow patents to restrict development and use of software on general-purpose
computers, but in those that do, we wish to avoid the special danger that
patents applied to a free program could make it effectively proprietary. To
prevent this, the GPL assures that patents cannot be used to render the program
non-free.
The precise terms and conditions for copying, distribution and modification
follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of works,
such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this License.
Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals
or organizations.
To "modify" a work means to copy from or adapt all or part of the work in
a fashion requiring copyright permission, other than the making of an exact
copy. The resulting work is called a "modified version" of the earlier work
or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based on the
Program.
To "propagate" a work means to do anything with it that, without permission,
would make you directly or secondarily liable for infringement under applicable
copyright law, except executing it on a computer or modifying a private copy.
Propagation includes copying, distribution (with or without modification),
making available to the public, and in some countries other activities as
well.
To "convey" a work means any kind of propagation that enables other parties
to make or receive copies. Mere interaction with a user through a computer
network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices" to the
extent that it includes a convenient and prominently visible feature that
(1) displays an appropriate copyright notice, and (2) tells the user that
there is no warranty for the work (except to the extent that warranties are
provided), that licensees may convey the work under this License, and how
to view a copy of this License. If the interface presents a list of user commands
or options, such as a menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work for making
modifications to it. "Object code" means any non-source form of a work.
A "Standard Interface" means an interface that either is an official standard
defined by a recognized standards body, or, in the case of interfaces specified
for a particular programming language, one that is widely used among developers
working in that language.
The "System Libraries" of an executable work include anything, other than
the work as a whole, that (a) is included in the normal form of packaging
a Major Component, but which is not part of that Major Component, and (b)
serves only to enable use of the work with that Major Component, or to implement
a Standard Interface for which an implementation is available to the public
in source code form. A "Major Component", in this context, means a major essential
component (kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to produce
the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all the source
code needed to generate, install, and (for an executable work) run the object
code and to modify the work, including scripts to control those activities.
However, it does not include the work's System Libraries, or general-purpose
tools or generally available free programs which are used unmodified in performing
those activities but which are not part of the work. For example, Corresponding
Source includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically linked
subprograms that the work is specifically designed to require, such as by
intimate data communication or control flow between those subprograms and
other parts of the work.
The Corresponding Source need not include anything that users can regenerate
automatically from other parts of the Corresponding Source.
The Corresponding Source for a work in source code form is that same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of copyright
on the Program, and are irrevocable provided the stated conditions are met.
This License explicitly affirms your unlimited permission to run the unmodified
Program. The output from running a covered work is covered by this License
only if the output, given its content, constitutes a covered work. This License
acknowledges your rights of fair use or other equivalent, as provided by copyright
law.
You may make, run and propagate covered works that you do not convey, without
conditions so long as your license otherwise remains in force. You may convey
covered works to others for the sole purpose of having them make modifications
exclusively for you, or provide you with facilities for running those works,
provided that you comply with the terms of this License in conveying all material
for which you do not control copyright. Those thus making or running the covered
works for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of your copyrighted
material outside their relationship with you.
Conveying under any other circumstances is permitted solely under the conditions
stated below. Sublicensing is not allowed; section 10 makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological measure
under any applicable law fulfilling obligations under article 11 of the WIPO
copyright treaty adopted on 20 December 1996, or similar laws prohibiting
or restricting circumvention of such measures.
When you convey a covered work, you waive any legal power to forbid circumvention
of technological measures to the extent such circumvention is effected by
exercising rights under this License with respect to the covered work, and
you disclaim any intention to limit operation or modification of the work
as a means of enforcing, against the work's users, your or third parties'
legal rights to forbid circumvention of technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you receive
it, in any medium, provided that you conspicuously and appropriately publish
on each copy an appropriate copyright notice; keep intact all notices stating
that this License and any non-permissive terms added in accord with section
7 apply to the code; keep intact all notices of the absence of any warranty;
and give all recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey, and you
may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to produce
it from the Program, in the form of source code under the terms of section
4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified it, and
giving a relevant date.
b) The work must carry prominent notices stating that it is released under
this License and any conditions added under section 7. This requirement modifies
the requirement in section 4 to "keep intact all notices".
c) You must license the entire work, as a whole, under this License to anyone
who comes into possession of a copy. This License will therefore apply, along
with any applicable section 7 additional terms, to the whole of the work,
and all its parts, regardless of how they are packaged. This License gives
no permission to license the work in any other way, but it does not invalidate
such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display Appropriate
Legal Notices; however, if the Program has interactive interfaces that do
not display Appropriate Legal Notices, your work need not make them do so.
A compilation of a covered work with other separate and independent works,
which are not by their nature extensions of the covered work, and which are
not combined with it such as to form a larger program, in or on a volume of
a storage or distribution medium, is called an "aggregate" if the compilation
and its resulting copyright are not used to limit the access or legal rights
of the compilation's users beyond what the individual works permit. Inclusion
of a covered work in an aggregate does not cause this License to apply to
the other parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms of sections
4 and 5, provided that you also convey the machine-readable Corresponding
Source under the terms of this License, in one of these ways:
a) Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by the Corresponding Source fixed
on a durable physical medium customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product (including
a physical distribution medium), accompanied by a written offer, valid for
at least three years and valid for as long as you offer spare parts or customer
support for that product model, to give anyone who possesses the object code
either (1) a copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical medium customarily
used for software interchange, for a price no more than your reasonable cost
of physically performing this conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the written
offer to provide the Corresponding Source. This alternative is allowed only
occasionally and noncommercially, and only if you received the object code
with such an offer, in accord with subsection 6b.
d) Convey the object code by offering access from a designated place (gratis
or for a charge), and offer equivalent access to the Corresponding Source
in the same way through the same place at no further charge. You need not
require recipients to copy the Corresponding Source along with the object
code. If the place to copy the object code is a network server, the Corresponding
Source may be on a different server (operated by you or a third party) that
supports equivalent copying facilities, provided you maintain clear directions
next to the object code saying where to find the Corresponding Source. Regardless
of what server hosts the Corresponding Source, you remain obligated to ensure
that it is available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided you inform
other peers where the object code and Corresponding Source of the work are
being offered to the general public at no charge under subsection 6d.
A separable portion of the object code, whose source code is excluded from
the Corresponding Source as a System Library, need not be included in conveying
the object code work.
A "User Product" is either (1) a "consumer product", which means any tangible
personal property which is normally used for personal, family, or household
purposes, or (2) anything designed or sold for incorporation into a dwelling.
In determining whether a product is a consumer product, doubtful cases shall
be resolved in favor of coverage. For a particular product received by a particular
user, "normally used" refers to a typical or common use of that class of product,
regardless of the status of the particular user or of the way in which the
particular user actually uses, or expects or is expected to use, the product.
A product is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent the
only significant mode of use of the product.
"Installation Information" for a User Product means any methods, procedures,
authorization keys, or other information required to install and execute modified
versions of a covered work in that User Product from a modified version of
its Corresponding Source. The information must suffice to ensure that the
continued functioning of the modified object code is in no case prevented
or interfered with solely because modification has been made.
If you convey an object code work under this section in, or with, or specifically
for use in, a User Product, and the conveying occurs as part of a transaction
in which the right of possession and use of the User Product is transferred
to the recipient in perpetuity or for a fixed term (regardless of how the
transaction is characterized), the Corresponding Source conveyed under this
section must be accompanied by the Installation Information. But this requirement
does not apply if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has been installed
in ROM).
The requirement to provide Installation Information does not include a requirement
to continue to provide support service, warranty, or updates for a work that
has been modified or installed by the recipient, or for the User Product in
which it has been modified or installed. Access to a network may be denied
when the modification itself materially and adversely affects the operation
of the network or violates the rules and protocols for communication across
the network.
Corresponding Source conveyed, and Installation Information provided, in accord
with this section must be in a format that is publicly documented (and with
an implementation available to the public in source code form), and must require
no special password or key for unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this License
by making exceptions from one or more of its conditions. Additional permissions
that are applicable to the entire Program shall be treated as though they
were included in this License, to the extent that they are valid under applicable
law. If additional permissions apply only to part of the Program, that part
may be used separately under those permissions, but the entire Program remains
governed by this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option remove any
additional permissions from that copy, or from any part of it. (Additional
permissions may be written to require their own removal in certain cases when
you modify the work.) You may place additional permissions on material, added
by you to a covered work, for which you have or can give appropriate copyright
permission.
Notwithstanding any other provision of this License, for material you add
to a covered work, you may (if authorized by the copyright holders of that
material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the terms of
sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or author
attributions in that material or in the Appropriate Legal Notices displayed
by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or requiring
that modified versions of such material be marked in reasonable ways as different
from the original version; or
d) Limiting the use for publicity purposes of names of licensors or authors
of the material; or
e) Declining to grant rights under trademark law for use of some trade names,
trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that material by
anyone who conveys the material (or modified versions of it) with contractual
assumptions of liability to the recipient, for any liability that these contractual
assumptions directly impose on those licensors and authors.
All other non-permissive additional terms are considered "further restrictions"
within the meaning of section 10. If the Program as you received it, or any
part of it, contains a notice stating that it is governed by this License
along with a term that is a further restriction, you may remove that term.
If a license document contains a further restriction but permits relicensing
or conveying under this License, you may add to a covered work material governed
by the terms of that license document, provided that the further restriction
does not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you must place,
in the relevant source files, a statement of the additional terms that apply
to those files, or a notice indicating where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the form
of a separately written license, or stated as exceptions; the above requirements
apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly provided
under this License. Any attempt otherwise to propagate or modify it is void,
and will automatically terminate your rights under this License (including
any patent licenses granted under the third paragraph of section 11).
However, if you cease all violation of this License, then your license from
a particular copyright holder is reinstated (a) provisionally, unless and
until the copyright holder explicitly and finally terminates your license,
and (b) permanently, if the copyright holder fails to notify you of the violation
by some reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is reinstated permanently
if the copyright holder notifies you of the violation by some reasonable means,
this is the first time you have received notice of violation of this License
(for any work) from that copyright holder, and you cure the violation prior
to 30 days after your receipt of the notice.
Termination of your rights under this section does not terminate the licenses
of parties who have received copies or rights from you under this License.
If your rights have been terminated and not permanently reinstated, you do
not qualify to receive new licenses for the same material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or run a copy
of the Program. Ancillary propagation of a covered work occurring solely as
a consequence of using peer-to-peer transmission to receive a copy likewise
does not require acceptance. However, nothing other than this License grants
you permission to propagate or modify any covered work. These actions infringe
copyright if you do not accept this License. Therefore, by modifying or propagating
a covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically receives
a license from the original licensors, to run, modify and propagate that work,
subject to this License. You are not responsible for enforcing compliance
by third parties with this License.
An "entity transaction" is a transaction transferring control of an organization,
or substantially all assets of one, or subdividing an organization, or merging
organizations. If propagation of a covered work results from an entity transaction,
each party to that transaction who receives a copy of the work also receives
whatever licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the Corresponding
Source of the work from the predecessor in interest, if the predecessor has
it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the rights
granted or affirmed under this License. For example, you may not impose a
license fee, royalty, or other charge for exercise of rights granted under
this License, and you may not initiate litigation (including a cross-claim
or counterclaim in a lawsuit) alleging that any patent claim is infringed
by making, using, selling, offering for sale, or importing the Program or
any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this License
of the Program or a work on which the Program is based. The work thus licensed
is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims owned or controlled
by the contributor, whether already acquired or hereafter acquired, that would
be infringed by some manner, permitted by this License, of making, using,
or selling its contributor version, but do not include claims that would be
infringed only as a consequence of further modification of the contributor
version. For purposes of this definition, "control" includes the right to
grant patent sublicenses in a manner consistent with the requirements of this
License.
Each contributor grants you a non-exclusive, worldwide, royalty-free patent
license under the contributor's essential patent claims, to make, use, sell,
offer for sale, import and otherwise run, modify and propagate the contents
of its contributor version.
In the following three paragraphs, a "patent license" is any express agreement
or commitment, however denominated, not to enforce a patent (such as an express
permission to practice a patent or covenant not to sue for patent infringement).
To "grant" such a patent license to a party means to make such an agreement
or commitment not to enforce a patent against the party.
If you convey a covered work, knowingly relying on a patent license, and the
Corresponding Source of the work is not available for anyone to copy, free
of charge and under the terms of this License, through a publicly available
network server or other readily accessible means, then you must either (1)
cause the Corresponding Source to be so available, or (2) arrange to deprive
yourself of the benefit of the patent license for this particular work, or
(3) arrange, in a manner consistent with the requirements of this License,
to extend the patent license to downstream recipients. "Knowingly relying"
means you have actual knowledge that, but for the patent license, your conveying
the covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that country
that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or arrangement,
you convey, or propagate by procuring conveyance of, a covered work, and grant
a patent license to some of the parties receiving the covered work authorizing
them to use, propagate, modify or convey a specific copy of the covered work,
then the patent license you grant is automatically extended to all recipients
of the covered work and works based on it.
A patent license is "discriminatory" if it does not include within the scope
of its coverage, prohibits the exercise of, or is conditioned on the non-exercise
of one or more of the rights that are specifically granted under this License.
You may not convey a covered work if you are a party to an arrangement with
a third party that is in the business of distributing software, under which
you make payment to the third party based on the extent of your activity of
conveying the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory patent
license (a) in connection with copies of the covered work conveyed by you
(or copies made from those copies), or (b) primarily for and in connection
with specific products or compilations that contain the covered work, unless
you entered into that arrangement, or that patent license was granted, prior
to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting any implied
license or other defenses to infringement that may otherwise be available
to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or otherwise)
that contradict the conditions of this License, they do not excuse you from
the conditions of this License. If you cannot convey a covered work so as
to satisfy simultaneously your obligations under this License and any other
pertinent obligations, then as a consequence you may not convey it at all.
For example, if you agree to terms that obligate you to collect a royalty
for further conveying from those to whom you convey the Program, the only
way you could satisfy both those terms and this License would be to refrain
entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have permission to
link or combine any covered work with a work licensed under version 3 of the
GNU Affero General Public License into a single combined work, and to convey
the resulting work. The terms of this License will continue to apply to the
part which is the covered work, but the special requirements of the GNU Affero
General Public License, section 13, concerning interaction through a network
will apply to the combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of the
GNU General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.
Each version is given a distinguishing version number. If the Program specifies
that a certain numbered version of the GNU General Public License "or any
later version" applies to it, you have the option of following the terms and
conditions either of that numbered version or of any later version published
by the Free Software Foundation. If the Program does not specify a version
number of the GNU General Public License, you may choose any version ever
published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future versions of
the GNU General Public License can be used, that proxy's public statement
of acceptance of a version permanently authorizes you to choose that version
for the Program.
Later license versions may give you additional or different permissions. However,
no additional obligations are imposed on any author or copyright holder as
a result of your choosing to follow a later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM
PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM
AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO
USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided above cannot
be given local legal effect according to their terms, reviewing courts shall
apply local law that most closely approximates an absolute waiver of all civil
liability in connection with the Program, unless a warranty or assumption
of liability accompanies a copy of the Program in return for a fee. END OF
TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively state the exclusion
of warranty; and each file should have at least the "copyright" line and a
pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like
this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it under certain
conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands might
be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. For
more information on this, and how to apply and follow the GNU GPL, see <https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General Public
License instead of this License. But first, please read <https://www.gnu.org/
licenses /why-not-lgpl.html>.

15
LICENSES/ISC.txt

@ -0,0 +1,15 @@
ISC License:
Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC")
Copyright (c) 1995-2003 by Internet Software Consortium
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

21
LICENSES/MIT.txt

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013-2019 Damien P. George
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

22
LICENSES/Unlicense.txt

@ -0,0 +1,22 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or distribute
this software, either in source code form or as a compiled binary, for any
purpose, commercial or non-commercial, and by any means.
In jurisdictions that recognize copyright laws, the author or authors of this
software dedicate any and all copyright interest in the software to the public
domain. We make this dedication for the benefit of the public at large and
to the detriment of our heirs and
successors. We intend this dedication to be an overt act of relinquishment
in perpetuity of all present and future rights to this software under copyright
law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

188
README-MP.md

@ -0,0 +1,188 @@
[![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.

13
README.md

@ -0,0 +1,13 @@
# Passport Wallet
Passport is an Ultra-secure, Open Source Hardware Wallet for Bitcoin that offers
excellent usability and a great design.
Get yours at [FoundationDevices.com](https://foundationdevices.com)
[Follow @FOUNDATIONdvcs on Twitter](https://twitter.com/FOUNDATIONdvcs) to keep up
with the latest updates and security alerts.
![foundation logo](https://user-images.githubusercontent.com/62639971/100529265-99345380-319a-11eb-8ecc-195dd435edab.png)
![passport picture](https://user-images.githubusercontent.com/62639971/100529305-07791600-319b-11eb-8a02-6b14f6060bd3.png)

191
docs/Makefile

@ -0,0 +1,191 @@
# Makefile for Sphinx documentation
#
# 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
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@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
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MicroPython.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MicroPython.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/MicroPython"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MicroPython"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex: cpydiff
$(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
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja: cpydiff
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

38
docs/README.md

@ -0,0 +1,38 @@
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

301
docs/conf.py

@ -0,0 +1,301 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# MicroPython 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
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys
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'),
],
}
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = 'MicroPython'
copyright = '2014-2019, Damien P. George, Paul Sokolovsky, and contributors'
# 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 language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['build', '.venv']
# The reST default role (used for this markup: `text`) to use for all
# documents.
default_role = 'any'
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
# 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 ----------------------------------------------
# on_rtd is whether we are on readthedocs.org
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if we're building docs locally
try:
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
except:
html_theme = 'default'
html_theme_path = ['.']
else:
html_theme_path = ['.']
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = ['.']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#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'
# 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,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['static']
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = '%d %b %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
html_additional_pages = {"index": "topindex.html"}
# If false, no module index is generated.
#html_domain_indices = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, links to the reST sources are added to the pages.
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = 'MicroPythondoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# 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'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# If true, show page references after internal links.
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_domain_indices = True
# -- Options for manual page output ---------------------------------------
# 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),
]
# If true, show URL addresses after external links.
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (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.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
#texinfo_appendices = []
# If false, no module index is generated.
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
#texinfo_no_detailmenu = False
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None)}

180
docs/develop/cmodules.rst

@ -0,0 +1,180 @@
.. _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

14
docs/develop/index.rst

@ -0,0 +1,14 @@
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

202
docs/develop/natmod.rst

@ -0,0 +1,202 @@
.. _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

112
docs/develop/qstr.rst

@ -0,0 +1,112 @@
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.

11
docs/differences/index_template.txt

@ -0,0 +1,11 @@
.. _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

64
docs/esp32/general.rst

@ -0,0 +1,64 @@
.. _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.

BIN
docs/esp32/img/esp32.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

519
docs/esp32/quickref.rst

@ -0,0 +1,519 @@
.. _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.

139
docs/esp32/tutorial/intro.rst

@ -0,0 +1,139 @@
.. _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.

197
docs/esp8266/general.rst

@ -0,0 +1,197 @@
.. _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).

BIN
docs/esp8266/img/adafruit_products_pinoutstop.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

394
docs/esp8266/quickref.rst

@ -0,0 +1,394 @@
.. _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.

19
docs/esp8266/tutorial/adc.rst

@ -0,0 +1,19 @@
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.

91
docs/esp8266/tutorial/apa102.rst

@ -0,0 +1,91 @@
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()

65
docs/esp8266/tutorial/dht.rst

@ -0,0 +1,65 @@
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.

69
docs/esp8266/tutorial/filesystem.rst

@ -0,0 +1,69 @@
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.

34
docs/esp8266/tutorial/index.rst

@ -0,0 +1,34 @@
.. _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

202
docs/esp8266/tutorial/intro.rst

@ -0,0 +1,202 @@
.. _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.

84
docs/esp8266/tutorial/neopixel.rst

@ -0,0 +1,84 @@
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)

81
docs/esp8266/tutorial/network_basics.rst

@ -0,0 +1,81 @@
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.

122
docs/esp8266/tutorial/network_tcp.rst

@ -0,0 +1,122 @@
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()

12
docs/esp8266/tutorial/nextsteps.rst

@ -0,0 +1,12 @@
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!

37
docs/esp8266/tutorial/onewire.rst

@ -0,0 +1,37 @@
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.

76
docs/esp8266/tutorial/pins.rst

@ -0,0 +1,76 @@
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.

61
docs/esp8266/tutorial/powerctrl.rst

@ -0,0 +1,61 @@
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')

87
docs/esp8266/tutorial/pwm.rst

@ -0,0 +1,87 @@
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)

212
docs/esp8266/tutorial/repl.rst

@ -0,0 +1,212 @@
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.

14
docs/index.rst

@ -0,0 +1,14 @@
MicroPython 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

12
docs/library/_thread.rst

@ -0,0 +1,12 @@
: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.

159
docs/library/btree.rst

@ -0,0 +1,159 @@
: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.

199
docs/library/builtins.rst

@ -0,0 +1,199 @@
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

63
docs/library/cmath.rst

@ -0,0 +1,63 @@
:mod:`cmath` -- mathematical functions for complex numbers
==========================================================
.. module:: cmath
:synopsis: mathematical functions for complex numbers
|see_cpython_module| :mod:`python:cmath`.
The ``cmath`` module provides some basic mathematical functions for
working with complex numbers.
Availability: not available on WiPy and ESP8266. Floating point support
required for this module.
Functions
---------
.. function:: cos(z)
Return the cosine of ``z``.
.. function:: exp(z)
Return the exponential of ``z``.
.. function:: log(z)
Return the natural logarithm of ``z``. The branch cut is along the negative real axis.
.. function:: log10(z)
Return the base-10 logarithm of ``z``. The branch cut is along the negative real axis.
.. function:: phase(z)
Returns the phase of the number ``z``, in the range (-pi, +pi].
.. function:: polar(z)
Returns, as a tuple, the polar form of ``z``.
.. function:: rect(r, phi)
Returns the complex number with modulus ``r`` and phase ``phi``.
.. function:: sin(z)
Return the sine of ``z``.
.. function:: sqrt(z)
Return the square-root of ``z``.
Constants
---------
.. data:: e
base of the natural logarithm
.. data:: pi
the ratio of a circle's circumference to its diameter

101
docs/library/esp.rst

@ -0,0 +1,101 @@
: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.

202
docs/library/esp32.rst

@ -0,0 +1,202 @@
.. 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.

161
docs/library/framebuf.rst

@ -0,0 +1,161 @@
: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

66
docs/library/gc.rst

@ -0,0 +1,66 @@
:mod:`gc` -- control the garbage collector
==========================================
.. module:: gc
:synopsis: control the garbage collector
|see_cpython_module| :mod:`python:gc`.
Functions
---------
.. function:: enable()
Enable automatic garbage collection.
.. function:: disable()
Disable automatic garbage collection. Heap memory can still be allocated,
and garbage collection can still be initiated manually using :meth:`gc.collect`.
.. function:: collect()
Run a garbage collection.
.. function:: mem_alloc()
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.

166
docs/library/index.rst

@ -0,0 +1,166 @@
.. _micropython_lib:
MicroPython libraries
=====================
.. warning::
Important summary of this section
* 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).
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
---------------------------------------------
The following standard Python libraries have been "micro-ified" to fit in with
the philosophy of MicroPython. 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).
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,
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
---------------------------------
The following libraries are specific to the pyboard.
.. toctree::
: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

394
docs/library/lcd160cr.rst

@ -0,0 +1,394 @@
: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`.

35
docs/library/machine.ADC.rst

@ -0,0 +1,35 @@
.. 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.

81
docs/library/machine.ADCWiPy.rst

@ -0,0 +1,81 @@
.. 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.

180
docs/library/machine.I2C.rst

@ -0,0 +1,180 @@
.. 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``.

254
docs/library/machine.Pin.rst

@ -0,0 +1,254 @@
.. 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.

69
docs/library/machine.RTC.rst

@ -0,0 +1,69 @@
.. 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

47
docs/library/machine.SD.rst

@ -0,0 +1,47 @@
.. 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.

122
docs/library/machine.SDCard.rst

@ -0,0 +1,122 @@
.. 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` .

101
docs/library/machine.SPI.rst

@ -0,0 +1,101 @@
.. 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

123
docs/library/machine.Signal.rst

@ -0,0 +1,123 @@
.. 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.

64
docs/library/machine.Timer.rst

@ -0,0 +1,64 @@
.. 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.

159
docs/library/machine.TimerWiPy.rst

@ -0,0 +1,159 @@
.. 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.

152
docs/library/machine.UART.rst

@ -0,0 +1,152 @@
.. 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.

36
docs/library/machine.WDT.rst

@ -0,0 +1,36 @@
.. 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.

171
docs/library/machine.rst

@ -0,0 +1,171 @@
: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

185
docs/library/math.rst

@ -0,0 +1,185 @@
:mod:`math` -- mathematical functions
=====================================
.. module:: math
:synopsis: mathematical functions
|see_cpython_module| :mod:`python:math`.
The ``math`` module provides some basic mathematical functions 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
---------
.. function:: acos(x)
Return the inverse cosine of ``x``.
.. function:: acosh(x)
Return the inverse hyperbolic cosine of ``x``.
.. function:: asin(x)
Return the inverse sine of ``x``.
.. function:: asinh(x)
Return the inverse hyperbolic sine of ``x``.
.. function:: atan(x)
Return the inverse tangent of ``x``.
.. function:: atan2(y, x)
Return the principal value of the inverse tangent of ``y/x``.
.. function:: atanh(x)
Return the inverse hyperbolic tangent of ``x``.
.. function:: ceil(x)
Return an integer, being ``x`` rounded towards positive infinity.
.. function:: copysign(x, y)
Return ``x`` with the sign of ``y``.
.. function:: cos(x)
Return the cosine of ``x``.
.. function:: cosh(x)
Return the hyperbolic cosine of ``x``.
.. function:: degrees(x)
Return radians ``x`` converted to degrees.
.. function:: erf(x)
Return the error function of ``x``.
.. function:: erfc(x)
Return the complementary error function of ``x``.
.. function:: exp(x)
Return the exponential of ``x``.
.. function:: expm1(x)
Return ``exp(x) - 1``.
.. function:: fabs(x)
Return the absolute value of ``x``.
.. function:: floor(x)
Return an integer, being ``x`` rounded towards negative infinity.
.. function:: fmod(x, y)
Return the remainder of ``x/y``.
.. 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.
.. function:: gamma(x)
Return the gamma function of ``x``.
.. function:: isfinite(x)
Return ``True`` if ``x`` is finite.
.. function:: isinf(x)
Return ``True`` if ``x`` is infinite.
.. function:: isnan(x)
Return ``True`` if ``x`` is not-a-number
.. function:: ldexp(x, exp)
Return ``x * (2**exp)``.
.. function:: lgamma(x)
Return the natural logarithm of the gamma function of ``x``.
.. function:: log(x)
Return the natural logarithm of ``x``.
.. function:: log10(x)
Return the base-10 logarithm of ``x``.
.. function:: log2(x)
Return the base-2 logarithm of ``x``.
.. function:: modf(x)
Return a tuple of two floats, being the fractional and integral parts of
``x``. Both return values have the same sign as ``x``.
.. function:: pow(x, y)
Returns ``x`` to the power of ``y``.
.. function:: radians(x)
Return degrees ``x`` converted to radians.
.. function:: sin(x)
Return the sine of ``x``.
.. function:: sinh(x)
Return the hyperbolic sine of ``x``.
.. function:: sqrt(x)
Return the square root of ``x``.
.. function:: tan(x)
Return the tangent of ``x``.
.. function:: tanh(x)
Return the hyperbolic tangent of ``x``.
.. function:: trunc(x)
Return an integer, being ``x`` rounded towards 0.
Constants
---------
.. data:: e
base of the natural logarithm
.. data:: pi
the ratio of a circle's circumference to its diameter

140
docs/library/micropython.rst

@ -0,0 +1,140 @@
: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.

89
docs/library/network.CC3K.rst

@ -0,0 +1,89 @@
.. 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

71
docs/library/network.WIZNET5K.rst

@ -0,0 +1,71 @@
.. 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.

132
docs/library/network.WLAN.rst

@ -0,0 +1,132 @@
.. 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
============= ===========

161
docs/library/network.WLANWiPy.rst

@ -0,0 +1,161 @@
.. 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

173
docs/library/network.rst

@ -0,0 +1,173 @@
****************************************
:mod:`network` --- network configuration
****************************************
.. 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.
For example::
# connect/ show IP config 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
addr = socket.getaddrinfo('micropython.org', 80)[0][-1]
s = socket.socket()
s.connect(addr)
s.send(b'GET / HTTP/1.1\r\nHost: micropython.org\r\n\r\n')
data = s.recv(1000)
s.close()
Common network adapter interface
================================
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.
.. class:: AbstractNIC(id=None, ...)
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`.
.. method:: AbstractNIC.active([is_active])
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).
.. method:: AbstractNIC.connect([service_id, key=None, \*, ...])
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:
* WiFi: *bssid* keyword to connect to a specific BSSID (MAC address)
.. method:: AbstractNIC.disconnect()
Disconnect from network.
.. method:: AbstractNIC.isconnected()
Returns ``True`` if connected to network, otherwise returns ``False``.
.. method:: AbstractNIC.scan(\*, ...)
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:
* WiFi: (ssid, bssid, channel, RSSI, authmode, hidden). There
may be further fields, specific to a particular device.
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().
.. method:: AbstractNIC.status([param])
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.
The return types and values are dependent on the network
medium/technology. Some of the parameters that may be supported are:
* 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).
.. method:: AbstractNIC.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:: AbstractNIC.config('param')
AbstractNIC.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
`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::
# 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'))
Specific network class implementations
======================================
The following concrete classes implement the AbstractNIC interface and
provide a way to control networking interfaces of various kinds.
.. toctree::
:maxdepth: 1
network.WLAN.rst
network.WLANWiPy.rst
network.CC3K.rst
network.WIZNET5K.rst
Network functions
=================
The following are functions available in the network module.
.. function:: phy_mode([mode])
Get or set the PHY mode.
If the *mode* parameter is provided, sets the mode to its value. If
the function is called without parameters, returns the current mode.
The possible modes are defined as constants:
* ``MODE_11B`` -- IEEE 802.11b,
* ``MODE_11G`` -- IEEE 802.11g,
* ``MODE_11N`` -- IEEE 802.11n.
Availability: ESP8266.

167
docs/library/pyb.ADC.rst

@ -0,0 +1,167 @@
.. currentmodule:: pyb
.. _pyb.ADC:
class ADC -- analog to digital conversion
=========================================
Usage::
import pyb
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
Constructors
------------
.. class:: pyb.ADC(pin)
Create an ADC object associated with the given pin.
This allows you to then read analog values on that pin.
Methods
-------
.. 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::
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()

57
docs/library/pyb.Accel.rst

@ -0,0 +1,57 @@
.. currentmodule:: pyb
.. _pyb.Accel:
class Accel -- accelerometer control
====================================
Accel is an object that controls the accelerometer. Example usage::
accel = pyb.Accel()
for i in range(10):
print(accel.x(), accel.y(), accel.z())
Raw values are between -32 and 31.
Constructors
------------
.. class:: pyb.Accel()
Create and return an accelerometer object.
Methods
-------
.. 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()
Get the tilt register.
.. method:: Accel.x()
Get the x-axis value.
.. method:: Accel.y()
Get the y-axis value.
.. 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.

300
docs/library/pyb.CAN.rst

@ -0,0 +1,300 @@
.. currentmodule:: pyb
.. _pyb.CAN:
class CAN -- controller area network communication bus
======================================================
CAN implements the standard CAN communications protocol. At
the physical level it consists of 2 lines: RX and TX. Note that
to connect the pyboard to a CAN bus you must use a CAN transceiver
to convert the CAN logic signals from the pyboard to the correct
voltage levels on the bus.
Example usage (works without anything connected)::
from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126)) # set a filter to receive messages with id=123, 124, 125 and 126
can.send('message!', 123) # send a message with id 123
can.recv(0) # receive message on FIFO 0
Constructors
------------
.. class:: pyb.CAN(bus, ...)
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.
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)
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).
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)
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
(29 bits); otherwise it uses standard 11 bit identifiers
- *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;
it can be 1, 2, 3, 4
- *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;
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);
see :meth:`pyb.freq()` to determine PCLK1.
A single bit is made up of the synchronisation segment, which is always 1 tq.
Then follows bit segment 1, then bit segment 2. The sample point is after bit
segment 1 finishes. The transmit point is after bit segment 2 finishes.
The baud rate will be 1/bittime, where the bittime is 1 + BS1 + BS2 multiplied
by the time quanta tq.
For example, with PCLK1=42MHz, prescaler=100, sjw=1, bs1=6, bs2=8, the value of
tq is 2.38 microseconds. The bittime is 35.7 microseconds, and the baudrate
is 28kHz.
See page 680 of the STM32F405 datasheet for more details.
.. 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)
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.
+-----------+---------------------------------------------------------+
|*mode* |contents of *params* array |
+===========+=========================================================+
|CAN.LIST16 |Four 16 bit ids that will be accepted |
+-----------+---------------------------------------------------------+
|CAN.LIST32 |Two 32 bit ids that will be accepted |
+-----------+---------------------------------------------------------+
|CAN.MASK16 |Two 16 bit id/mask pairs. E.g. (1, 3, 4, 4) |
| | | The first pair, 1 and 3 will accept all ids |
| | | that have bit 0 = 1 and bit 1 = 0. |
| | | The second pair, 4 and 4, will accept all ids |
| | | that have bit 2 = 1. |
+-----------+---------------------------------------------------------+
|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)
Clear and disables a filter bank:
- *bank* is the filter bank that is to be cleared.
.. method:: CAN.any(fifo)
Return ``True`` if any message waiting on the FIFO, else ``False``.
.. method:: CAN.recv(fifo, list=None, \*, timeout=5000)
Receive data on the bus:
- *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)
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.
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
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()`.
.. data:: CAN.LIST16
CAN.MASK16
CAN.LIST32
CAN.MASK32
The operation mode of a filter used in :meth:`~CAN.setfilter()`.

124
docs/library/pyb.DAC.rst

@ -0,0 +1,124 @@
.. currentmodule:: pyb
.. _pyb.DAC:
class DAC -- digital to analog conversion
=========================================
The DAC is used to output analog values (a specific voltage) on pin X5 or pin X6.
The voltage will be between 0 and 3.3V.
*This module will undergo changes to the API.*
Example usage::
from pyb import DAC
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
from pyb import DAC
# 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)))
# output the sine-wave at 400Hz
dac = DAC(1)
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)
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)
Generate a pseudo-random noise signal. A new random sample is written
to the DAC output at the given frequency.
.. 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.
.. 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.
.. 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.
``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)

114
docs/library/pyb.ExtInt.rst

@ -0,0 +1,114 @@
.. currentmodule:: pyb
.. _pyb.ExtInt:
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
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, ... ::
def callback(line):
print("line =", line)
Note: ExtInt will automatically configure the gpio line as an input. ::
extint = pyb.ExtInt(pin, pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, callback)
Now every time a falling edge is seen on the X1 pin, the callback will be
called. Caution: mechanical pushbuttons 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.
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.
All other pin objects go through the pin mapper to come up with one of the
gpio pins. ::
extint = pyb.ExtInt(pin, mode, pull, callback)
Valid modes are pyb.ExtInt.IRQ_RISING, pyb.ExtInt.IRQ_FALLING,
pyb.ExtInt.IRQ_RISING_FALLING, pyb.ExtInt.EVT_RISING,
pyb.ExtInt.EVT_FALLING, and pyb.ExtInt.EVT_RISING_FALLING.
Only the IRQ_xxx modes have been tested. The EVT_xxx modes have
something to do with sleep mode and the WFE instruction.
Valid pull values are pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN, pyb.Pin.PULL_NONE.
There is also a C API, so that drivers which require EXTI interrupt lines
can also use this code. See extint.h for the available functions and
usrsw.h for an example of using this.
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;
- ``ExtInt.IRQ_FALLING`` - trigger on a falling edge;
- ``ExtInt.IRQ_RISING_FALLING`` - trigger on a rising or falling edge.
- ``pull`` can be one of:
- ``pyb.Pin.PULL_NONE`` - no pull up or down resistors;
- ``pyb.Pin.PULL_UP`` - enable the pull-up resistor;
- ``pyb.Pin.PULL_DOWN`` - enable the pull-down resistor.
- ``callback`` is the function to call when the interrupt triggers. The
callback function must accept exactly 1 argument, which is the line that
triggered the interrupt.
Class methods
-------------
.. classmethod:: ExtInt.regs()
Dump the values of the EXTI registers.
Methods
-------
.. method:: ExtInt.disable()
Disable the interrupt associated with the ExtInt object.
This could be useful for debouncing.
.. method:: ExtInt.enable()
Enable a disabled interrupt.
.. method:: ExtInt.line()
Return the line number that the pin is mapped to.
.. method:: ExtInt.swint()
Trigger the callback from software.
Constants
---------
.. data:: ExtInt.IRQ_FALLING
interrupt on a falling edge
.. data:: ExtInt.IRQ_RISING
interrupt on a rising edge
.. data:: ExtInt.IRQ_RISING_FALLING
interrupt on a rising or falling edge

52
docs/library/pyb.Flash.rst

@ -0,0 +1,52 @@
.. 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.

165
docs/library/pyb.I2C.rst

@ -0,0 +1,165 @@
.. currentmodule:: pyb
.. _pyb.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.
Example::
from pyb import I2C
i2c = I2C(1) # create on bus 1
i2c = I2C(1, I2C.MASTER) # create and init as a master
i2c.init(I2C.MASTER, baudrate=20000) # init as a master
i2c.init(I2C.SLAVE, addr=0x42) # init as a slave with given address
i2c.deinit() # turn off the peripheral
Printing the i2c object gives you information about its configuration.
The basic methods are send and recv::
i2c.send('abc') # send 3 bytes
i2c.send(0x42) # send a single byte, given by the number
data = i2c.recv(3) # receive 3 bytes
To receive inplace, first create a bytearray::
data = bytearray(3) # create a buffer
i2c.recv(data) # receive 3 bytes, writing them into data
You can specify a timeout (in ms)::
i2c.send(b'123', timeout=2000) # timeout after 2 seconds
A master must specify the recipient's address::
i2c.init(I2C.MASTER)
i2c.send('123', 0x42) # send 3 bytes to slave with address 0x42
i2c.send(b'456', addr=0x42) # keyword for address
Master also has other methods::
i2c.is_ready(0x42) # check if slave 0x42 is ready
i2c.scan() # scan for slaves on the bus, returning
# 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
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
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:
- ``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()
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:
- ``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)
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)
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)
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)
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()
Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
Only valid when in master mode.
Constants
---------
.. data:: I2C.MASTER
for initialising the bus to master mode
.. data:: I2C.SLAVE
for initialising the bus to slave mode

97
docs/library/pyb.LCD.rst

@ -0,0 +1,97 @@
.. currentmodule:: pyb
.. _pyb.LCD:
class LCD -- LCD control for the LCD touch-sensor pyskin
========================================================
The LCD class is used to control the LCD on the LCD touch-sensor pyskin,
LCD32MKv1.0. The LCD is a 128x32 pixel monochrome screen, part NHD-C12832A1Z.
The pyskin must be connected in either the X or Y positions, and then
an LCD object is made using::
lcd = pyb.LCD('X') # if pyskin is in the X position
lcd = pyb.LCD('Y') # if pyskin is in the Y position
Then you can use::
lcd.light(True) # turn the backlight on
lcd.write('Hello world!\n') # print text to the screen
This driver implements a double buffer for setting/getting pixels.
For example, to make a bouncing dot, try::
x = y = 0
dx = dy = 1
while True:
# update the dot's position
x += dx
y += dy
# make the dot bounce of the edges of the screen
if x <= 0 or x >= 127: dx = -dx
if y <= 0 or y >= 31: dy = -dy
lcd.fill(0) # clear the buffer
lcd.pixel(x, y, 1) # draw the dot
lcd.show() # show the buffer
pyb.delay(50) # pause for 50ms
Constructors
------------
.. class:: pyb.LCD(skin_position)
Construct an LCD object in the given skin position. ``skin_position`` can be 'X' or 'Y', and
should match the position where the LCD pyskin is plugged in.
Methods
-------
.. 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)
Set the contrast of the LCD. Valid values are between 0 and 47.
.. 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)
Get the pixel at the position ``(x, y)``. Returns 0 or 1.
This method reads from the visible buffer.
.. 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)
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()
Show the hidden buffer on the screen.
.. 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)
Write the string ``str`` to the screen. It will appear immediately.

46
docs/library/pyb.LED.rst

@ -0,0 +1,46 @@
.. currentmodule:: pyb
.. _pyb.LED:
class LED -- LED object
=======================
The LED object controls an individual LED (Light Emitting Diode).
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])
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()
Turn the LED off.
.. method:: LED.on()
Turn the LED on, to maximum intensity.
.. 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.

268
docs/library/pyb.Pin.rst

@ -0,0 +1,268 @@
.. currentmodule:: pyb
.. _pyb.Pin:
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.
Usage Model:
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
followed by the pin number. On the PYBv1.0, ``pyb.Pin.board.X1`` and
``pyb.Pin.cpu.A0`` are the same pin.
You can also use strings::
g = pyb.Pin('X1', pyb.Pin.OUT_PP)
Users can add their own names::
MyMapperDict = { 'LeftMotorDir' : pyb.Pin.cpu.C12 }
pyb.Pin.dict(MyMapperDict)
g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)
and can query mappings::
pin = pyb.Pin("LeftMotorDir")
Users can also add their own mapping function::
def MyMapper(pin_name):
if pin_name == "LeftMotorDir":
return pyb.Pin.cpu.A0
pyb.Pin.mapper(MyMapper)
So, if you were to call: ``pyb.Pin("LeftMotorDir", pyb.Pin.OUT_PP)``
then ``"LeftMotorDir"`` is passed directly to the mapper function.
To summarise, the following order determines how things get mapped into
an ordinal pin number:
1. Directly specify a pin object
2. User supplied mapping function
3. User supplied mapping (object must be usable as a dictionary key)
4. Supply a string which matches a board pin
5. Supply a string which matches a CPU port/pin
You can set ``pyb.Pin.debug(True)`` to get some debug information about
how a particular object gets mapped to a pin.
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
------------
.. class:: pyb.Pin(id, ...)
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])
Get or set the debugging state (``True`` or ``False`` for on or off).
.. classmethod:: Pin.dict([dict])
Get or set the pin mapper dictionary.
.. classmethod:: Pin.mapper([fun])
Get or set the pin mapper function.
Methods
-------
.. 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.
- ``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
of one of the alternate functions associated with a pin.
Returns: ``None``.
.. method:: Pin.value([value])
Get or set the digital logic level of the pin:
- With no argument, return 0 or 1 depending on the logic level of the pin.
- With ``value`` given, set the logic level of the pin. ``value`` can be
anything that converts to a boolean. If it converts to ``True``, the pin
is set high, otherwise it is set low.
.. method:: Pin.__str__()
Return a string describing the pin object.
.. 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()
Returns the base address of the GPIO block associated with this pin.
.. 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()
Get the pin name.
.. method:: Pin.names()
Returns the cpu and board names for this pin.
.. method:: Pin.pin()
Get the pin number.
.. method:: Pin.port()
Get the pin port.
.. 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.
Constants
---------
.. data:: Pin.AF_OD
initialise the pin to alternate-function mode with an open-drain drive
.. data:: Pin.AF_PP
initialise the pin to alternate-function mode with a push-pull drive
.. data:: Pin.ANALOG
initialise the pin to analog mode
.. data:: Pin.IN
initialise the pin to input mode
.. data:: Pin.OUT_OD
initialise the pin to output mode with an open-drain drive
.. data:: Pin.OUT_PP
initialise the pin to output mode with a push-pull drive
.. data:: Pin.PULL_DOWN
enable the pull-down resistor on the pin
.. data:: Pin.PULL_NONE
don't enable any pull up or down resistors on the pin
.. data:: Pin.PULL_UP
enable the pull-up resistor on the pin
class PinAF -- Pin Alternate Functions
======================================
A Pin represents a physical pin on the microprocessor. Each pin
can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF
object represents a particular function for a pin.
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
pin X3.
For the pyboard, x3_af would contain:
[Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM9, Pin.AF7_USART2]
Normally, each peripheral would configure the af automatically, but sometimes
the same function is available on multiple pins, and having more control
is desired.
To configure X3 to expose TIM2_CH3, you could use::
pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=pyb.Pin.AF1_TIM2)
or::
pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=1)
Methods
-------
.. method:: pinaf.__str__()
Return a string describing the alternate function.
.. method:: pinaf.index()
Return the alternate function index.
.. method:: pinaf.name()
Return the name of the alternate function.
.. method:: pinaf.reg()
Return the base register associated with the peripheral assigned to this
alternate function. For example, if the alternate function were TIM2_CH3
this would return stm.TIM2

78
docs/library/pyb.RTC.rst

@ -0,0 +1,78 @@
.. currentmodule:: pyb
.. _pyb.RTC:
class RTC -- real time clock
============================
The RTC is and independent clock that keeps track of the date
and time.
Example usage::
rtc = pyb.RTC()
rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
print(rtc.datetime())
Constructors
------------
.. class:: pyb.RTC()
Create an RTC object.
Methods
-------
.. 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).
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()
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

122
docs/library/pyb.SPI.rst

@ -0,0 +1,122 @@
.. currentmodule:: pyb
.. _pyb.SPI:
class SPI -- a master-driven serial protocol
============================================
SPI is a serial protocol that is driven by a master. At the physical level
there are 3 lines: SCK, MOSI, MISO.
See usage model of I2C; SPI is very similar. Main difference is
parameters to init the SPI bus::
from pyb import SPI
spi = SPI(1, SPI.MASTER, baudrate=600000, polarity=1, phase=0, crc=0x7)
Only required parameter is mode, SPI.MASTER or SPI.SLAVE. 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. Crc can be
None for no CRC, or a polynomial specifier.
Additional methods 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
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()
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)
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;
use of ``prescaler`` overrides ``baudrate``.
- ``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.
Note that the SPI clock frequency will not always be the requested baudrate.
The hardware only supports baudrates that are the APB bus frequency
(see :meth:`pyb.freq`) divided by a prescaler, which can be 2, 4, 8, 16, 32,
64, 128 or 256. SPI(1) is on AHB2, and SPI(2) is on AHB1. For precise
control over the SPI clock frequency, specify ``prescaler`` instead of
``baudrate``.
Printing the SPI object will show you the computed baudrate and the chosen
prescaler.
.. 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)
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)
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
---------
.. data:: SPI.MASTER
.. data:: SPI.SLAVE
for initialising the SPI bus to master or slave mode
.. data:: SPI.LSB
.. data:: SPI.MSB
set the first bit to be the least or most significant bit

80
docs/library/pyb.Servo.rst

@ -0,0 +1,80 @@
.. 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.
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.
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:
- ``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.
.. method:: Servo.speed([speed, time=0])
If no arguments are given, this function returns the current speed.
If arguments are given, this function sets the speed of the servo:
- ``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.
.. method:: Servo.pulse_width([value])
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.

46
docs/library/pyb.Switch.rst

@ -0,0 +1,46 @@
.. currentmodule:: pyb
.. _pyb.Switch:
class Switch -- switch object
=============================
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.callback(f) # register a callback to be called when the
# switch is pressed down
sw.callback(None) # remove the callback
Example::
pyb.Switch().callback(lambda: pyb.LED(1).toggle())
Constructors
------------
.. class:: pyb.Switch()
Create and return a switch object.
Methods
-------
.. method:: Switch.__call__()
Call switch object directly to get its 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)
Register the given function to be called when the switch is pressed down.
If ``fun`` is ``None``, then it disables the callback.

264
docs/library/pyb.Timer.rst

@ -0,0 +1,264 @@
.. currentmodule:: pyb
.. _pyb.Timer:
class Timer -- control internal timers
======================================
Timers can be used for a great variety of tasks. At the moment, only
the simplest case is implemented: that of calling a function periodically.
Each timer consists of a counter that counts up at a certain rate. The rate
at which it counts is the peripheral clock frequency (in Hz) divided by the
timer prescaler. When the counter reaches the timer period it triggers an
event, and the counter resets back to zero. By using the callback method,
the timer event can call a Python function.
Example usage to toggle an LED at a fixed frequency::
tim = pyb.Timer(4) # create a timer object using timer 4
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
tim = pyb.Timer(4, prescaler=0, period=99)
tim.counter() # get counter (can also set)
tim.prescaler(2) # set prescaler (can also get)
tim.period(199) # set period (can also get)
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.
Constructors
------------
.. class:: pyb.Timer(id, ...)
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.
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)
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, ...)
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.
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).
- ``Timer.PWM_INVERTED`` --- configure the timer in PWM mode (active low).
- ``Timer.OC_TIMING`` --- indicates that no pin is driven.
- ``Timer.OC_ACTIVE`` --- the pin will be made active when a compare match occurs (active is determined by polarity)
- ``Timer.OC_INACTIVE`` --- the pin will be made inactive when a compare match occurs.
- ``Timer.OC_TOGGLE`` --- the pin will be toggled when an compare match occurs.
- ``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
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)
.. method:: Timer.counter([value])
Get or set the timer counter.
.. method:: Timer.freq([value])
Get or set the frequency for the timer (changes prescaler and period if set).
.. method:: Timer.period([value])
Get or set the period of the timer.
.. method:: Timer.prescaler([value])
Get or set the prescaler for the timer.
.. method:: Timer.source_freq()
Get the frequency of the source of the timer.
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.callback(fun)
Set the function to be called when the timer channel triggers.
``fun`` is passed 1 argument, the timer object.
If ``fun`` is ``None`` then the callback will be disabled.
.. method:: timerchannel.capture([value])
Get or set the capture value associated with a channel.
capture, compare, and pulse_width are all aliases for the same function.
capture is the logical name to use when the channel is in input capture mode.
.. method:: timerchannel.compare([value])
Get or set the compare value associated with a channel.
capture, compare, and pulse_width are all aliases for the same function.
compare is the logical name to use when the channel is in output compare mode.
.. method:: timerchannel.pulse_width([value])
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%
.. method:: timerchannel.pulse_width_percent([value])
Get or set the pulse width percentage associated with a channel. The value
is a number between 0 and 100 and sets the percentage of the timer period
for which the pulse is active. The value can be an integer or
floating-point number for more accuracy. For example, a value of 25 gives
a duty cycle of 25%.

225
docs/library/pyb.UART.rst

@ -0,0 +1,225 @@
.. currentmodule:: pyb
.. _pyb.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 pyb import UART
uart = UART(1, 9600) # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
Bits can be 7, 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2.
*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
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
Individual characters can be read/written using::
uart.readchar() # read 1 character and returns it as an integer
uart.writechar(42) # write 1 character
To check if there is anything to be read, use::
uart.any() # returns the number of characters waiting
*Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
Earlier versions use ``uart.send`` and ``uart.recv``.
Constructors
------------
.. class:: pyb.UART(bus, ...)
Construct a UART object on the given bus. ``bus`` can be 1-6, or 'XA', 'XB', 'YA', or 'YB'.
With no additional parameters, the UART 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 UART busses are:
- ``UART(4)`` is on ``XA``: ``(TX, RX) = (X1, X2) = (PA0, PA1)``
- ``UART(1)`` is on ``XB``: ``(TX, RX) = (X9, X10) = (PB6, PB7)``
- ``UART(6)`` is on ``YA``: ``(TX, RX) = (Y1, Y2) = (PC6, PC7)``
- ``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)
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.
- ``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.
- ``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()
Turn off the UART bus.
.. method:: UART.any()
Returns the number of bytes waiting (may be 0).
.. 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``
on timeout.
.. 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])
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. If such a line exists, return is
immediate. If the timeout elapses, all available data is returned regardless
of whether a newline exists.
Return value: the line read or ``None`` on timeout if no data is available.
.. 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``.
.. 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.

40
docs/library/pyb.USB_HID.rst

@ -0,0 +1,40 @@
.. 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).

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save