Compare commits

..

1 Commits

Author SHA1 Message Date
Paul Sokolovsky b7d32672ce emitnative: Incomplete implementation delete_fast operation. 2014-12-27 16:46:09 +02:00
3926 changed files with 336954 additions and 404716 deletions

26
.gitattributes vendored
View File

@ -1,26 +0,0 @@
# Per default everything gets normalized and gets LF line endings on checkout.
* text eol=lf
# These will always have CRLF line endings on checkout.
*.vcxproj text eol=crlf
*.props text eol=crlf
*.bat text eol=crlf
# These are binary so should never be modified by git.
*.a binary
*.png binary
*.jpg binary
*.dxf binary
*.mpy binary
# These should also not be modified by git.
tests/basics/string_cr_conversion.py -text
tests/basics/string_crlf_conversion.py -text
ports/stm32/pybcdc.inf_template -text
ports/stm32/usbhost/** -text
ports/cc3200/hal/aes.c -text
ports/cc3200/hal/aes.h -text
ports/cc3200/hal/des.c -text
ports/cc3200/hal/i2s.c -text
ports/cc3200/hal/i2s.h -text
ports/cc3200/version.h -text

15
.gitignore vendored
View File

@ -9,22 +9,20 @@
*.dis
*.exe
# Packages
# Packages
############
# Logs and Databases
######################
*.log
cscope.out
# VIM Swap Files
######################
*.swp
# Build directories
# Build directory
######################
build/
build-*/
# Test failure outputs
######################
@ -34,13 +32,6 @@ tests/*.out
# Python cache files
######################
__pycache__/
*.pyc
# Customized Makefile/project overrides
######################
# Customized Makefile overrides
GNUmakefile
user.props
# Generated rst files
######################
genrst/

32
.gitmodules vendored
View File

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

View File

@ -1,265 +1,29 @@
# global options
dist: xenial
language:
- c
language: c
compiler:
- gcc
cache:
directories:
- "${HOME}/persist"
env:
global:
- MAKEOPTS="-j4"
git:
submodules: false
# define the successive stages
stages:
- name: test
before_script:
- sudo add-apt-repository -y ppa:fkrull/deadsnakes
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
- sudo apt-get update -qq
- sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-arm-none-eabi qemu-system mingw32
# For teensy build
- sudo apt-get install realpath
# define the jobs for the stages
# order of the jobs has longest running first to optimise total time
jobs:
include:
# stm32 port
- stage: test
env: NAME="stm32 port build"
install:
# need newer gcc version for Cortex-M7 support
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo apt-get update -qq || true
- sudo apt-get install gcc-arm-embedded
- sudo apt-get install libnewlib-arm-none-eabi
- arm-none-eabi-gcc --version
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/stm32 submodules
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1'
- make ${MAKEOPTS} -C ports/stm32 BOARD=B_L072Z_LRWAN1
- make ${MAKEOPTS} -C ports/stm32 BOARD=STM32L476DISC
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55
- make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6
script:
- make -C unix CC=gcc-4.7
- make -C unix-cpy CC=gcc-4.7
- make -C bare-arm
- make -C qemu-arm
- make -C stmhal
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
- make -C stmhal BOARD=STM32F4DISC
- make -C teensy
- make -C windows CROSS_COMPILE=i586-mingw32msvc-
# qemu-arm port
- stage: test
env: NAME="qemu-arm port build and tests"
install:
- sudo apt-get install gcc-arm-none-eabi
- sudo apt-get install libnewlib-arm-none-eabi
- sudo apt-get install qemu-system
- arm-none-eabi-gcc --version
- qemu-system-arm --version
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test
after_failure:
- grep "FAIL" ports/qemu-arm/build/console.out
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests)
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests --emit native)
# unix coverage
- stage: test
env: NAME="unix coverage build and tests"
install:
- sudo apt-get install python3-pip
- sudo pip install cpp-coveralls
- sudo pip3 install setuptools
- sudo pip3 install pyelftools
- gcc --version
- python3 --version
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/unix submodules
- make ${MAKEOPTS} -C ports/unix deplibs
- make ${MAKEOPTS} -C ports/unix coverage
# run the main test suite
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests)
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -d thread)
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --emit native)
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy -d basics float micropython)
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy --emit native -d basics float micropython)
# test when input script comes from stdin
- cat tests/basics/0prelim.py | ports/unix/micropython_coverage | grep -q 'abc'
# test building native mpy modules
- make -C examples/natmod/features1 ARCH=x64
- make -C examples/natmod/features2 ARCH=x64
- make -C examples/natmod/btree ARCH=x64
- make -C examples/natmod/framebuf ARCH=x64
- make -C examples/natmod/uheapq ARCH=x64
- make -C examples/natmod/urandom ARCH=x64
- make -C examples/natmod/ure ARCH=x64
- make -C examples/natmod/uzlib ARCH=x64
# test importing .mpy generated by mpy_ld.py
- MICROPYPATH=examples/natmod/features2 ./ports/unix/micropython_coverage -m features2
- (cd tests && ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py)
# run coveralls coverage analysis (try to, even if some builds/tests failed)
- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod)
after_failure:
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
# standard unix port
- stage: test
env: NAME="unix port build and tests"
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/unix submodules
- make ${MAKEOPTS} -C ports/unix deplibs
- make ${MAKEOPTS} -C ports/unix
- make ${MAKEOPTS} -C ports/unix test
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython ./run-perfbench.py 1000 1000)
# unix nanbox (and using Python 2 to check it can run the build scripts)
- stage: test
env: NAME="unix nanbox port build and tests"
install:
- sudo apt-get install gcc-multilib libffi-dev:i386
script:
- make ${MAKEOPTS} -C mpy-cross PYTHON=python2
- make ${MAKEOPTS} -C ports/unix submodules
- make ${MAKEOPTS} -C ports/unix PYTHON=python2 deplibs
- make ${MAKEOPTS} -C ports/unix PYTHON=python2 nanbox
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_nanbox ./run-tests)
# unix stackless
- stage: test
env: NAME="unix stackless port build and tests with clang"
install:
- sudo apt-get install clang
script:
- make ${MAKEOPTS} -C mpy-cross CC=clang
- make ${MAKEOPTS} -C ports/unix submodules
- make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1"
- make ${MAKEOPTS} -C ports/unix CC=clang test
# unix with sys.settrace
- stage: test
env: NAME="unix port with sys.settrace build and tests"
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_PY_SYS_SETTRACE=1" test
- make ${MAKEOPTS} -C ports/unix clean
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" test
after_failure:
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
# minimal unix port with tests
- stage: test
env: NAME="minimal unix port build and tests"
script:
- make ${MAKEOPTS} -C ports/unix minimal
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_minimal ./run-tests -e exception_chain -e self_type_check -e subclass_native_init -d basics)
# windows port via mingw
- stage: test
env: NAME="windows port build via mingw"
install:
- sudo apt-get install gcc-mingw-w64
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32-
# esp32 port
- stage: test
env: NAME="esp32 port build"
install:
- sudo apt-get install python3-pip
- sudo pip3 install 'pyparsing<2.4'
- wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
- zcat xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz | tar x
- export PATH=$(pwd)/xtensa-esp32-elf/bin:$PATH
- git clone https://github.com/espressif/esp-idf.git
- export IDF_PATH=$(pwd)/esp-idf
script:
- make ${MAKEOPTS} -C mpy-cross
# IDF v3 build
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V3 :=" ports/esp32/Makefile | cut -d " " -f 3)
- git -C esp-idf submodule update --init components/json/cJSON components/esp32/lib components/esptool_py/esptool components/expat/expat components/lwip/lwip components/mbedtls/mbedtls components/micro-ecc/micro-ecc components/nghttp/nghttp2
- make ${MAKEOPTS} -C ports/esp32 submodules
- make ${MAKEOPTS} -C ports/esp32
# clean
- git -C esp-idf clean -f -f -d components/json/cJSON components/esp32/lib components/expat/expat components/micro-ecc/micro-ecc components/nghttp/nghttp2
- make ${MAKEOPTS} -C ports/esp32 clean
# IDF v4 build
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V4 :=" ports/esp32/Makefile | cut -d " " -f 3)
- git -C esp-idf submodule update --init components/bt/controller/lib components/bt/host/nimble/nimble components/esp_wifi/lib_esp32 components/esptool_py/esptool components/lwip/lwip components/mbedtls/mbedtls
- make ${MAKEOPTS} -C ports/esp32 submodules
- make ${MAKEOPTS} -C ports/esp32
# esp8266 port
- stage: test
env: NAME="esp8266 port build"
install:
- wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz
- zcat xtensa-lx106-elf-standalone.tar.gz | tar x
- export PATH=$(pwd)/xtensa-lx106-elf/bin:$PATH
script:
- make ${MAKEOPTS} -C mpy-cross
- make ${MAKEOPTS} -C ports/esp8266 submodules
- make ${MAKEOPTS} -C ports/esp8266
- make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_512K
# nrf port
- stage: test
env: NAME="nrf port build"
install:
- sudo apt-get install gcc-arm-none-eabi
- sudo apt-get install libnewlib-arm-none-eabi
- arm-none-eabi-gcc --version
script:
- make ${MAKEOPTS} -C ports/nrf submodules
- make ${MAKEOPTS} -C ports/nrf
# bare-arm and minimal ports
- stage: test
env: NAME="bare-arm and minimal ports build"
install:
- sudo apt-get install gcc-arm-none-eabi
- sudo apt-get install libnewlib-arm-none-eabi
- arm-none-eabi-gcc --version
script:
- make ${MAKEOPTS} -C ports/bare-arm
- make ${MAKEOPTS} -C ports/minimal CROSS=1 build/firmware.bin
- ls -l ports/minimal/build/firmware.bin
- tools/check_code_size.sh
- mkdir -p ${HOME}/persist
# Save new firmware for reference, but only if building a main branch, not a pull request
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cp ports/minimal/build/firmware.bin ${HOME}/persist/; fi'
# cc3200 port
- stage: test
env: NAME="cc3200 port build"
install:
- sudo apt-get install gcc-arm-none-eabi
- sudo apt-get install libnewlib-arm-none-eabi
script:
- make ${MAKEOPTS} -C ports/cc3200 BTARGET=application BTYPE=release
- make ${MAKEOPTS} -C ports/cc3200 BTARGET=bootloader BTYPE=release
# samd port
- stage: test
env: NAME="samd port build"
install:
- sudo apt-get install gcc-arm-none-eabi
- sudo apt-get install libnewlib-arm-none-eabi
script:
- make ${MAKEOPTS} -C ports/samd submodules
- make ${MAKEOPTS} -C ports/samd
# teensy port
- stage: test
env: NAME="teensy port build"
install:
- sudo apt-get install gcc-arm-none-eabi
- sudo apt-get install libnewlib-arm-none-eabi
script:
- make ${MAKEOPTS} -C ports/teensy
# powerpc port
- stage: test
env: NAME="powerpc port build"
install:
- sudo apt-get install gcc-powerpc64le-linux-gnu
- sudo apt-get install libc6-dev-ppc64el-cross
script:
- make ${MAKEOPTS} -C ports/powerpc CROSS_COMPILE=powerpc64le-linux-gnu-
after_failure:
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +1,3 @@
Git commit conventions
======================
Each commit message should start with a directory or full file path
prefix, so it was clear which part of codebase a commit affects. If
a change affects one file, it's better to use path to a file. If it
affects few files in a subdirectory, using subdirectory as a prefix
is ok. For longish paths, it's acceptable to drop intermediate
components, which still should provide good context of a change.
It's also ok to drop file extensions.
Besides prefix, first line of a commit message should describe a
change clearly and to the point, and be a grammatical sentence with
final full stop. First line should fit within 78 characters. Examples
of good first line of commit messages:
py/objstr: Add splitlines() method.
py: Rename FOO to BAR.
docs/machine: Fix typo in reset() description.
ports: Switch to use lib/foo instead of duplicated code.
After the first line, add an empty line and in following lines describe
a change in a detail, if needed. Any change beyond 5 lines would likely
require such detailed description.
To get good practical examples of good commits and their messages, browse
the `git log` of the project.
MicroPython doesn't require explicit sign-off for patches ("Signed-off-by"
lines and similar). Instead, the commit message, and your name and email
address on it construes your sign-off of the following:
* That you wrote the change yourself, or took it from a project with
a compatible license (in the latter case the commit message, and possibly
source code should provide reference where the implementation was taken
from and give credit to the original author, as required by the license).
* That you are allowed to release these changes to an open-source project
(for example, changes done during paid work for a third party may require
explicit approval from that third party).
* That you (or your employer) agree to release the changes under
MicroPython's license, which is the MIT license. Note that you retain
copyright for your changes (for smaller changes, the commit message
conveys your copyright; if you make significant changes to a particular
source module, you're welcome to add your name to the file header).
* Your signature for all of the above, which is the 'Author' line in
the commit message, and which should include your full real name and
a valid and active email address by which you can be contacted in the
foreseeable future.
Python code conventions
=======================
@ -73,7 +24,7 @@ White space:
keyword and the opening parenthesis.
- Put 1 space after a comma, and 1 space around operators.
Braces:
Braces:
- Use braces for all blocks, even no-line and single-line pieces of
code.
- Put opening braces on the end of the line it belongs to, not on
@ -82,50 +33,37 @@ Braces:
closing brace.
Header files:
- Header files should be protected from multiple inclusion with #if
directives. See an existing header for naming convention.
- Try to stick to the Plan 9 header style, where header files do not
include other header files.
- Don't protect a header file from multiple inclusion with #if directives.
Names:
- Use underscore_case, not camelCase for all names.
- Use CAPS_WITH_UNDERSCORE for enums and macros.
- When defining a type use underscore_case and put '_t' after it.
Type names and declarations:
- When defining a type, put '_t' after it.
Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's
important to use the correctly-sized (and signed) integer types. The
general guidelines are:
Integer types: Micro Python runs on 32 and 64 bit machines (and one day
maybe 16 bit), so it's important to use the correctly-sized (and signed)
integer types. The general guidelines are:
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
integer values. These are guaranteed to be machine-word sized and
therefore big enough to hold the value from a MicroPython small-int
therefore big enough to hold the value from a Micro Python small-int
object.
- Use size_t for things that count bytes / sizes of objects.
- You can use int/uint, but remember that they may be 16-bits wide.
- If in doubt, use mp_int_t/mp_uint_t.
Comments:
- Be concise and only write comments for things that are not obvious.
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
Memory allocation:
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
These macros are defined in py/misc.h.
Examples
--------
Braces, spaces, names and comments:
Braces and spaces:
#define TO_ADD (123)
// This function will always recurse indefinitely and is only used to show
// coding style
int foo_function(int x, int some_value) {
if (x < some_value) {
foo(some_value, x);
int foo(int x, int y) {
if (x < y) {
foo(y, x);
} else {
foo(x + TO_ADD, some_value - 1);
foo(x + 1, y - 1);
}
for (int my_counter = 0; my_counter < x; my_counter++) {
for (int i = 0; i < x; i++) {
}
}
@ -135,76 +73,3 @@ Type declarations:
int member;
void *data;
} my_struct_t;
Documentation conventions
=========================
MicroPython generally follows CPython in documentation process and
conventions. reStructuredText syntax is used for the documention.
Specific conventions/suggestions:
* Use `*` markup to refer to arguments of a function, e.g.:
```
.. method:: poll.unregister(obj)
Unregister *obj* from polling.
```
* Use following syntax for cross-references/cross-links:
```
:func:`foo` - function foo in current module
:func:`module1.foo` - function foo in module "module1"
(similarly for other referent types)
:class:`Foo` - class Foo
:meth:`Class.method1` - method1 in Class
:meth:`~Class.method1` - method1 in Class, but rendered just as "method1()",
not "Class.method1()"
:meth:`title <method1>` - reference method1, but render as "title" (use only
if really needed)
:mod:`module1` - module module1
`symbol` - generic xref syntax which can replace any of the above in case
the xref is unambiguous. If there's ambiguity, there will be a warning
during docs generation, which need to be fixed using one of the syntaxes
above
```
* Cross-referencing arbitrary locations
~~~
.. _xref_target:
Normal non-indented text.
This is :ref:`reference <xref_target>`.
(If xref target is followed by section title, can be just
:ref:`xref_target`).
~~~
* Linking to external URL:
```
`link text <http://foo.com/...>`_
```
* Referencing builtin singleton objects:
```
``None``, ``True``, ``False``
```
* Use following syntax to create common description for more than one element:
~~~
.. function:: foo(x)
bar(y)
Description common to foo() and bar().
~~~
More detailed guides and quickrefs:
* http://www.sphinx-doc.org/en/stable/rest.html
* http://www.sphinx-doc.org/en/stable/markup/inline.html
* http://docutils.sourceforge.net/docs/user/rst/quickref.html

View File

@ -1,53 +0,0 @@
MicroPython Code of Conduct
===========================
The MicroPython community is made up of members from around the globe with a
diverse set of skills, personalities, and experiences. It is through these
differences that our community experiences great successes and continued growth.
When you're working with members of the community, this Code of Conduct will
help steer your interactions and keep MicroPython a positive, successful, and
growing community.
Members of the MicroPython community are open, considerate, and respectful.
Behaviours that reinforce these values contribute to a positive environment, and
include: acknowledging time and effort, being respectful of differing viewpoints
and experiences, gracefully accepting constructive criticism, and using
welcoming and inclusive language.
Every member of our community has the right to have their identity respected.
The MicroPython community is dedicated to providing a positive experience for
everyone, regardless of age, gender identity and expression, sexual orientation,
disability, physical appearance, body size, ethnicity, nationality, race, or
religion (or lack thereof), education, or socio-economic status.
Unacceptable behaviour includes: harassment, trolling, deliberate intimidation,
violent threats or language directed against another person; insults, put downs,
or jokes that are based upon stereotypes, that are exclusionary, or that hold
others up for ridicule; unwelcome sexual attention or advances; sustained
disruption of community discussions; publishing others' private information
without explicit permission; and other conduct that is inappropriate for a
professional audience including people of many different backgrounds.
This code of conduct covers all online and offline presence related to the
MicroPython project, including GitHub and the forum. If a participant engages
in behaviour that violates this code of conduct, the MicroPython team may take
action as they deem appropriate, including warning the offender or expulsion
from the community. Community members asked to stop any inappropriate behaviour
are expected to comply immediately.
Thank you for helping make this a welcoming, friendly community for everyone.
If you believe that someone is violating the code of conduct, or have any other
concerns, please contact a member of the MicroPython team by emailing
contact@micropython.org.
License
-------
This Code of Conduct is licensed under the Creative Commons
Attribution-ShareAlike 3.0 Unported License.
Attributions
------------
Based on the Python code of conduct found at https://www.python.org/psf/conduct/

View File

@ -1,8 +0,0 @@
When reporting an issue and especially submitting a pull request, please
make sure that you are acquainted with Contributor Guidelines:
https://github.com/micropython/micropython/wiki/ContributorGuidelines
and Code Conventions:
https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2013-2019 Damien P. George
Copyright (c) 2013, 2014 Damien P. George
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -1,188 +0,0 @@
[![Build Status](https://travis-ci.org/micropython/micropython.png?branch=master)](https://travis-ci.org/micropython/micropython) [![Coverage Status](https://coveralls.io/repos/micropython/micropython/badge.png?branch=master)](https://coveralls.io/r/micropython/micropython?branch=master)
The MicroPython project
=======================
<p align="center">
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
</p>
This is the MicroPython project, which aims to put an implementation
of Python 3.x on microcontrollers and small embedded systems.
You can find the official website at [micropython.org](http://www.micropython.org).
WARNING: this project is in beta stage and is subject to changes of the
code-base, including project-wide name changes and API changes.
MicroPython implements the entire Python 3.4 syntax (including exceptions,
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
Python 3.5). The following core datatypes are provided: `str` (including
basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`,
`frozenset`, `array.array`, `collections.namedtuple`, classes and instances.
Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have
support for `_thread` module (multithreading). Note that only a subset of
Python 3 functionality is implemented for the data types and modules.
MicroPython can execute scripts in textual source form or from precompiled
bytecode, in both cases either from an on-device filesystem or "frozen" into
the MicroPython executable.
See the repository http://github.com/micropython/pyboard for the MicroPython
board (PyBoard), the officially supported reference electronic circuit board.
Major components in this repository:
- py/ -- the core Python implementation, including compiler, runtime, and
core library.
- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts
into precompiled bytecode.
- ports/unix/ -- a version of MicroPython that runs on Unix.
- ports/stm32/ -- a version of MicroPython that runs on the PyBoard and similar
STM32 boards (using ST's Cube HAL drivers).
- ports/minimal/ -- a minimal MicroPython port. Start with this if you want
to port MicroPython to another microcontroller.
- tests/ -- test framework and test scripts.
- docs/ -- user documentation in Sphinx reStructuredText format. Rendered
HTML documentation is available at http://docs.micropython.org.
Additional components:
- ports/bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used
mostly to control code size.
- ports/teensy/ -- a version of MicroPython that runs on the Teensy 3.1
(preliminary but functional).
- ports/pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
- ports/cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
- ports/esp8266/ -- a version of MicroPython that runs on Espressif's ESP8266 SoC.
- ports/esp32/ -- a version of MicroPython that runs on Espressif's ESP32 SoC.
- ports/nrf/ -- a version of MicroPython that runs on Nordic's nRF51 and nRF52 MCUs.
- extmod/ -- additional (non-core) modules implemented in C.
- tools/ -- various tools, including the pyboard.py module.
- examples/ -- a few example Python scripts.
The subdirectories above may include READMEs with additional info.
"make" is used to build the components, or "gmake" on BSD-based systems.
You will also need bash, gcc, and Python 3.3+ available as the command `python3`
(if your system only has Python 2.7 then invoke make with the additional option
`PYTHON=python2`).
The MicroPython cross-compiler, mpy-cross
-----------------------------------------
Most ports require the MicroPython cross-compiler to be built first. This
program, called mpy-cross, is used to pre-compile Python scripts to .mpy
files which can then be included (frozen) into the firmware/executable for
a port. To build mpy-cross use:
$ cd mpy-cross
$ make
The Unix version
----------------
The "unix" port requires a standard Unix environment with gcc and GNU make.
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
as ARM and MIPS. Making full-featured port to another architecture requires
writing some assembly code for the exception handling and garbage collection.
Alternatively, fallback implementation based on setjmp/longjmp can be used.
To build (see section below for required dependencies):
$ cd ports/unix
$ make submodules
$ make
Then to give it a try:
$ ./micropython
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
Use `CTRL-D` (i.e. EOF) to exit the shell.
Learn about command-line options (in particular, how to increase heap size
which may be needed for larger applications):
$ ./micropython --help
Run complete testsuite:
$ make test
Unix version comes with a builtin package manager called upip, e.g.:
$ ./micropython -m upip install micropython-pystone
$ ./micropython -m pystone
Browse available modules on
[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython).
Standard library modules come from
[micropython-lib](https://github.com/micropython/micropython-lib) project.
External dependencies
---------------------
Building MicroPython ports may require some dependencies installed.
For Unix port, `libffi` library and `pkg-config` tool are required. On
Debian/Ubuntu/Mint derivative Linux distros, install `build-essential`
(includes toolchain and make), `libffi-dev`, and `pkg-config` packages.
Other dependencies can be built together with MicroPython. This may
be required to enable extra features or capabilities, and in recent
versions of MicroPython, these may be enabled by default. To build
these additional dependencies, in the port directory you're
interested in (e.g. `ports/unix/`) first execute:
$ make submodules
This will fetch all the relevant git submodules (sub repositories) that
the port needs. Use the same command to get the latest versions of
submodules as they are updated from time to time. After that execute:
$ make deplibs
This will build all available dependencies (regardless whether they
are used or not). If you intend to build MicroPython with additional
options (like cross-compiling), the same set of options should be passed
to `make deplibs`. To actually enable/disable use of dependencies, edit
`ports/unix/mpconfigport.mk` file, which has inline descriptions of the options.
For example, to build SSL module (required for `upip` tool described above,
and so enabled by dfeault), `MICROPY_PY_USSL` should be set to 1.
For some ports, building required dependences is transparent, and happens
automatically. But they still need to be fetched with the `make submodules`
command.
The STM32 version
-----------------
The "stm32" port requires an ARM compiler, arm-none-eabi-gcc, and associated
bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils,
arm-none-eabi-gcc and arm-none-eabi-newlib packages. Otherwise, try here:
https://launchpad.net/gcc-arm-embedded
To build:
$ cd ports/stm32
$ make submodules
$ make
You then need to get your board into DFU mode. On the pyboard, connect the
3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other
on the bottom left of the board, second row from the bottom).
Then to flash the code via USB DFU to your device:
$ make deploy
This will use the included `tools/pydfu.py` script. If flashing the firmware
does not work it may be because you don't have the correct permissions, and
need to use `sudo make deploy`.
See the README.md file in the ports/stm32/ directory for further details.
Contributing
------------
MicroPython is an open-source project and welcomes contributions. To be
productive, please be sure to follow the
[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines)
and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md).
Note that MicroPython is licenced under the MIT license, and all contributions
should follow this license.

117
README.md
View File

@ -1,4 +1,115 @@
# Micropython for jebbatime
This is a lesser fork of Daniel Thompson's fork of Micropython.
It is for the Pinetime watch.
[![Build Status][travis-img]][travis-repo]
[travis-img]: https://travis-ci.org/micropython/micropython.png?branch=master
[travis-repo]: https://travis-ci.org/micropython/micropython
The Micro Python project
========================
<p align="center">
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
</p>
This is the Micro Python project, which aims to put an implementation
of Python 3.x on a microcontroller.
WARNING: this project is in early beta stage and is subject to large
changes of the code-base, including project-wide name changes and API
changes.
Micro Python implements the entire Python 3.4 syntax (including exceptions,
"with", "yield from", etc.). The following core datatypes are provided:
str (no Unicode support yet), bytes, bytearray, tuple, list, dict, set,
array.array, collections.namedtuple, classes and instances. Builtin
modules include sys, time, and struct. Note that only subset of
Python 3.4 functionality implemented for the data types and modules.
See the repository www.github.com/micropython/pyboard for the Micro
Python board, the officially supported reference electronic circuit board.
Major components in this repository:
- py/ -- the core Python implementation, including compiler and runtime.
- unix/ -- a version of Micro Python that runs on Unix.
- stmhal/ -- a version of Micro Python that runs on the Micro Python board
with an STM32F405RG (using ST's Cube HAL drivers).
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
(preliminary but functional).
Additional components:
- bare-arm/ -- a bare minimum version of Micro Python for ARM MCUs. Start
with this if you want to port Micro Python to another microcontroller.
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
- tests/ -- test framework and test scripts.
- tools/ -- various tools, including the pyboard.py module.
- examples/ -- a few example Python scripts.
"make" is used to build the components, or "gmake" on BSD-based systems.
You will also need bash and Python (at least 2.7 or 3.3).
The Unix version
----------------
The "unix" port requires a standard Unix environment with gcc and GNU make.
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
as ARM and MIPS. Making full-featured port to another architecture requires
writing some assembly code for the exception handling and garbage collection.
Alternatively, fallback implementation based on setjmp/longjmp can be used.
To build:
$ cd unix
$ make
Then to give it a try:
$ ./micropython
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
Run complete testsuite:
$ make test
Debian/Ubuntu/Mint derivative Linux distros will require build-essentials and
libreadline-dev packages installed. To build FFI (Foreign Function Interface)
module, libffi-dev and pkg-config packages are required. If you have problems
with some dependencies, they can be disabled in unix/mpconfigport.mk .
The STM version
---------------
The "stmhal" port requires an ARM compiler, arm-none-eabi-gcc, and associated
bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils and
arm-none-eabi-gcc packages from the AUR. Otherwise, try here:
https://launchpad.net/gcc-arm-embedded
To build:
$ cd stmhal
$ make
You then need to get your board into DFU mode. On the pyboard, connect the
3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other
on the bottom left of the board, second row from the bottom).
Then to flash the code via USB DFU to your device:
$ make deploy
You will need the dfu-util program, on Arch Linux it's dfu-util-git in the
AUR. If the above does not work it may be because you don't have the
correct permissions. Try then:
$ sudo dfu-util -a 0 -d 0483:df11 -D build-PYBV10/firmware.dfu
Building the documentation locally
----------------------------------
Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme,
preferably in a virtualenv:
pip install sphinx
pip install sphinx_rtd_theme
In `micropython/docs`, build the docs:
make html
You'll find the index page at `micropython/docs/build/html/index.html`.

49
bare-arm/Makefile 100644
View File

@ -0,0 +1,49 @@
include ../py/mkenv.mk
# qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h
# include py core make definitions
include ../py/py.mk
CROSS_COMPILE = arm-none-eabi-
INC = -I.
INC += -I..
INC += -I$(PY_SRC)
INC += -I$(BUILD)
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
#Debugging/Optimization
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -ggdb
else
CFLAGS += -Os -DNDEBUG
endif
LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref
LIBS =
SRC_C = \
main.c \
# printf.c \
string0.c \
malloc0.c \
gccollect.c \
SRC_S = \
# startup_stm32f40xx.s \
gchelper.s \
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o))
all: $(BUILD)/firmware.elf
$(BUILD)/firmware.elf: $(OBJ)
$(ECHO) "LINK $@"
$(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
$(Q)$(SIZE) $@
include ../py/mkrules.mk

128
bare-arm/main.c 100644
View File

@ -0,0 +1,128 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
#include "obj.h"
#include "parsehelper.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
#include "repl.h"
#include "pfenv.h"
void do_str(const char *src) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
return;
}
mp_parse_error_kind_t parse_error_kind;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return;
}
// parse okay
qstr source_name = lex->source_name;
mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
if (mp_obj_is_exception_instance(module_fun)) {
// compile error
mp_obj_print_exception(printf_wrapper, NULL, module_fun);
return;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_call_function_0(module_fun);
nlr_pop();
} else {
// uncaught exception
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
}
}
int main(int argc, char **argv) {
mp_init();
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\n')");
mp_deinit();
return 0;
}
void gc_collect(void) {
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
}
mp_import_stat_t mp_import_stat(const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) {
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
void nlr_jump_fail(void *val) {
}
void NORETURN __fatal_error(const char *msg) {
while (1);
}
#ifndef NDEBUG
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
__fatal_error("Assertion failed");
}
#endif
/*
int _lseek() {return 0;}
int _read() {return 0;}
int _write() {return 0;}
int _close() {return 0;}
void _exit(int x) {for(;;){}}
int _sbrk() {return 0;}
int _kill() {return 0;}
int _getpid() {return 0;}
int _fstat() {return 0;}
int _isatty() {return 0;}
*/
void *malloc(size_t n) {return NULL;}
void *calloc(size_t nmemb, size_t size) {return NULL;}
void *realloc(void *ptr, size_t size) {return NULL;}
void free(void *p) {}
int printf(const char *m, ...) {return 0;}
void *memcpy(void *dest, const void *src, size_t n) {return NULL;}
int memcmp(const void *s1, const void *s2, size_t n) {return 0;}
void *memmove(void *dest, const void *src, size_t n) {return NULL;}
void *memset(void *s, int c, size_t n) {return NULL;}
int strcmp(const char *s1, const char* s2) {return 0;}
int strncmp(const char *s1, const char* s2, size_t n) {return 0;}
size_t strlen(const char *s) {return 0;}
char *strcat(char *dest, const char *src) {return NULL;}
char *strchr(const char *dest, int c) {return NULL;}
#include <stdarg.h>
int vprintf(const char *format, va_list ap) {return 0;}
int vsnprintf(char *str, size_t size, const char *format, va_list ap) {return 0;}
#undef putchar
int putchar(int c) {return 0;}
int puts(const char *s) {return 0;}
void _start(void) {main(0, NULL);}

View File

@ -0,0 +1,57 @@
#include <stdint.h>
// options to control how Micro Python is built
#define MICROPY_ALLOC_PATH_MAX (512)
#define MICROPY_EMIT_X64 (0)
#define MICROPY_EMIT_THUMB (0)
#define MICROPY_EMIT_INLINE_THUMB (0)
#define MICROPY_MEM_STATS (0)
#define MICROPY_DEBUG_PRINTERS (0)
#define MICROPY_ENABLE_GC (0)
#define MICROPY_HELPER_REPL (0)
#define MICROPY_HELPER_LEXER_UNIX (0)
#define MICROPY_ENABLE_SOURCE_LINE (0)
#define MICROPY_ENABLE_DOC_STRING (0)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
#define MICROPY_PY_BUILTINS_FROZENSET (0)
#define MICROPY_PY_BUILTINS_SET (0)
#define MICROPY_PY_BUILTINS_SLICE (0)
#define MICROPY_PY_BUILTINS_PROPERTY (0)
#define MICROPY_PY___FILE__ (0)
#define MICROPY_PY_GC (0)
#define MICROPY_PY_ARRAY (0)
#define MICROPY_PY_COLLECTIONS (0)
#define MICROPY_PY_MATH (0)
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_IO (0)
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_SYS (0)
#define MICROPY_CPYTHON_COMPAT (0)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
// type definitions for the specific machine
#define BYTES_PER_WORD (4)
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
#define UINT_FMT "%lu"
#define INT_FMT "%ld"
typedef int32_t mp_int_t; // must be pointer size
typedef uint32_t mp_uint_t; // must be pointer size
typedef void *machine_ptr_t; // must be of pointer size
typedef const void *machine_const_ptr_t; // must be of pointer size
typedef long mp_off_t;
// extra built in names to add to the global namespace
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
#define MICROPY_PORT_BUILTINS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
// We need to provide a declaration/definition of alloca()
#include <alloca.h>

View File

@ -0,0 +1,117 @@
/*
GNU linker script for STM32F405
*/
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x080000 /* sectors 5,6,7,8, 4*128KiB = 512 KiB (could increase it more) */
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
}
/* top end of the stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* RAM extents for the garbage collector */
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = 0x2001c000; /* tunable */
/* define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH_ISR
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
/* *(.glue_7) */ /* glue arm to thumb code */
/* *(.glue_7t) */ /* glue thumb to arm code */
. = ALIGN(4);
_etext = .; /* define a global symbol at end of code */
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
} >FLASH_TEXT
/*
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} >FLASH
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
*/
/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
_ram_start = .; /* create a global symbol at ram start for garbage collector */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM
/* Uninitialized data section */
.bss :
{
. = ALIGN(4);
_sbss = .; /* define a global symbol at bss start; used by startup code */
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end; used by startup code */
} >RAM
/* this is to define the start of the heap, and make sure we have a minimum size */
.heap :
{
. = ALIGN(4);
_heap_start = .; /* define a global symbol at heap start */
} >RAM
/* this just checks there is enough RAM for the stack */
.stack :
{
. = ALIGN(4);
} >RAM
/* Remove information from the standard libraries */
/*
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
*/
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -2,17 +2,10 @@
#
# You can set these variables from the command line.
PYTHON = python3
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build/$(MICROPY_PORT)
CPYDIFFDIR = ../tools
CPYDIFF = gen-cpydiff.py
GENRSTDIR = genrst
# Run "make FORCE= ..." to avoid rebuilding from scratch (and risk
# producing incorrect docs).
FORCE = -E
BUILDDIR = build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
@ -52,19 +45,12 @@ help:
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " cpydiff to generate the MicroPython differences from CPython"
clean:
rm -rf $(BUILDDIR)/*
rm -f $(GENRSTDIR)/*
cpydiff:
@echo "Generating MicroPython Differences."
rm -f $(GENRSTDIR)/*
cd $(CPYDIFFDIR) && $(PYTHON) $(CPYDIFF)
html: cpydiff
$(SPHINXBUILD) $(FORCE) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
@ -117,20 +103,20 @@ epub:
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex: cpydiff
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf: cpydiff
$(SPHINXBUILD) $(FORCE) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja: cpydiff
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja

View File

@ -1,38 +0,0 @@
MicroPython Documentation
=========================
The MicroPython documentation can be found at:
http://docs.micropython.org/en/latest/
The documentation you see there is generated from the files in the docs tree:
https://github.com/micropython/micropython/tree/master/docs
Building the documentation locally
----------------------------------
If you're making changes to the documentation, you may want to build the
documentation locally so that you can preview your changes.
Install Sphinx, and optionally (for the RTD-styling), sphinx_rtd_theme,
preferably in a virtualenv:
pip install sphinx
pip install sphinx_rtd_theme
In `micropython/docs`, build the docs:
make html
You'll find the index page at `micropython/docs/build/html/index.html`.
PDF manual generation
---------------------
This can be achieved with:
make latexpdf
but require rather complete install of LaTeX with various extensions. On
Debian/Ubuntu, try (500MB+ download):
apt-get install texlive-latex-recommended texlive-latex-extra

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# MicroPython documentation build configuration file, created by
# Micro Python documentation build configuration file, created by
# sphinx-quickstart on Sun Sep 21 11:42:03 2014.
#
# This file is execfile()d with the current directory set to its
@ -19,22 +19,7 @@ import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('.'))
# The members of the html_context dict are available inside topindex.html
micropy_version = os.getenv('MICROPY_VERSION') or 'latest'
micropy_all_versions = (os.getenv('MICROPY_ALL_VERSIONS') or 'latest').split(',')
url_pattern = '%s/en/%%s' % (os.getenv('MICROPY_URL_PREFIX') or '/',)
html_context = {
'cur_version':micropy_version,
'all_versions':[
(ver, url_pattern % ver) for ver in micropy_all_versions
],
'downloads':[
('PDF', url_pattern % micropy_version + '/micropython-docs.pdf'),
],
}
#sys.path.insert(0, os.path.abspath('.'))
# -- General configuration ------------------------------------------------
@ -65,16 +50,17 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = 'MicroPython'
copyright = '2014-2019, Damien P. George, Paul Sokolovsky, and contributors'
project = 'Micro Python'
copyright = '2014, Damien P. George'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags"
# breakdown, so use the same version identifier for both to avoid confusion.
version = release = '1.12'
# The short X.Y version.
version = '1.3'
# The full version, including alpha/beta/rc tags.
release = '1.3.7'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -88,11 +74,11 @@ version = release = '1.12'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['build', '.venv']
exclude_patterns = ['build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
default_role = 'any'
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
@ -114,12 +100,6 @@ pygments_style = 'sphinx'
# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False
# Global include files. Sphinx docs suggest using rst_epilog in preference
# of rst_prolog, so we follow. Absolute paths below mean "from the base
# of the doctree".
rst_epilog = """
.. include:: /templates/replace.inc
"""
# -- Options for HTML output ----------------------------------------------
@ -154,12 +134,12 @@ else:
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = '../../logo/trans-logo.png'
#html_logo = '../logo/trans-logo.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = 'static/favicon.ico'
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
@ -227,16 +207,14 @@ latex_elements = {
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Include 3 levels of headers in PDF ToC
'preamble': '\setcounter{tocdepth}{2}',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'MicroPython.tex', 'MicroPython Documentation',
'Damien P. George, Paul Sokolovsky, and contributors', 'manual'),
('index', 'MicroPython.tex', 'Micro Python Documentation',
'Damien P. George', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@ -265,8 +243,8 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'micropython', 'MicroPython Documentation',
['Damien P. George, Paul Sokolovsky, and contributors'], 1),
('index', 'micropython', 'Micro Python Documentation',
['Damien P. George'], 1),
]
# If true, show URL addresses after external links.
@ -279,8 +257,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'MicroPython', 'MicroPython Documentation',
'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.',
('index', 'MicroPython', 'Micro Python Documentation',
'Damien P. George', 'MicroPython', 'One line description of project.',
'Miscellaneous'),
]
@ -298,4 +276,4 @@ texinfo_documents = [
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None)}
intersphinx_mapping = {'http://docs.python.org/': None}

11
docs/contents.rst 100644
View File

@ -0,0 +1,11 @@
Micro Python documentation contents
===================================
.. toctree::
quickref.rst
general.rst
tutorial/index.rst
library/index.rst
hardware/index.rst
license.rst

View File

@ -1,180 +0,0 @@
.. _cmodules:
MicroPython external C modules
==============================
When developing modules for use with MicroPython you may find you run into
limitations with the Python environment, often due to an inability to access
certain hardware resources or Python speed limitations.
If your limitations can't be resolved with suggestions in :ref:`speed_python`,
writing some or all of your module in C is a viable option.
If your module is designed to access or work with commonly available
hardware or libraries please consider implementing it inside the MicroPython
source tree alongside similar modules and submitting it as a pull request.
If however you're targeting obscure or proprietary systems it may make
more sense to keep this external to the main MicroPython repository.
This chapter describes how to compile such external modules into the
MicroPython executable or firmware image.
An alternative approach is to use :ref:`natmod` which allows writing custom C
code that is placed in a .mpy file, which can be imported dynamically in to
a running MicroPython system without the need to recompile the main firmware.
Structure of an external C module
---------------------------------
A MicroPython user C module is a directory with the following files:
* ``*.c`` and/or ``*.h`` source code files for your module.
These will typically include the low level functionality being implemented and
the MicroPython binding functions to expose the functions and module(s).
Currently the best reference for writing these functions/modules is
to find similar modules within the MicroPython tree and use them as examples.
* ``micropython.mk`` contains the Makefile fragment for this module.
``$(USERMOD_DIR)`` is available in ``micropython.mk`` as the path to your
module directory. As it's redefined for each c module, is should be expanded
in your ``micropython.mk`` to a local make variable,
eg ``EXAMPLE_MOD_DIR := $(USERMOD_DIR)``
Your ``micropython.mk`` must add your modules C files relative to your
expanded copy of ``$(USERMOD_DIR)`` to ``SRC_USERMOD``, eg
``SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c``
If you have custom ``CFLAGS`` settings or include folders to define, these
should be added to ``CFLAGS_USERMOD``.
See below for full usage example.
Basic Example
-------------
This simple module named ``example`` provides a single function
``example.add_ints(a, b)`` which adds the two integer args together and returns
the result.
Directory::
example/
├── example.c
└── micropython.mk
``example.c``
.. code-block:: c
// Include required definitions first.
#include "py/obj.h"
#include "py/runtime.h"
#include "py/builtin.h"
// This is the function which will be called from Python as example.add_ints(a, b).
STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
// Extract the ints from the micropython input objects
int a = mp_obj_get_int(a_obj);
int b = mp_obj_get_int(b_obj);
// Calculate the addition and convert to MicroPython object.
return mp_obj_new_int(a + b);
}
// Define a Python reference to the function above
STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
// Define all properties of the example module.
// Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference.
// All identifiers and strings are written as MP_QSTR_xxx and will be
// optimized to word-sized integers by the build system (interned strings).
STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example) },
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
};
STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
// Define module object.
const mp_obj_module_t example_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&example_module_globals,
};
// Register the module to make it available in Python
MP_REGISTER_MODULE(MP_QSTR_example, example_user_cmodule, MODULE_EXAMPLE_ENABLED);
``micropython.mk``
.. code-block:: make
EXAMPLE_MOD_DIR := $(USERMOD_DIR)
# Add all C files to SRC_USERMOD.
SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c
# We can add our module folder to include paths if needed
# This is not actually needed in this example.
CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR)
Finally you will need to define ``MODULE_EXAMPLE_ENABLED`` to 1. This
can be done by adding ``CFLAGS_EXTRA=-DMODULE_EXAMPLE_ENABLED=1`` to
the ``make`` command, or editing ``mpconfigport.h`` or
``mpconfigboard.h`` to add
.. code-block:: c
#define MODULE_EXAMPLE_ENABLED (1)
Note that the exact method depends on the port as they have different
structures. If not done correctly it will compile but importing will
fail to find the module.
Compiling the cmodule into MicroPython
--------------------------------------
To build such a module, compile MicroPython (see `getting started
<https://github.com/micropython/micropython/wiki/Getting-Started>`_) with an
extra ``make`` flag named ``USER_C_MODULES`` set to the directory containing
all modules you want included (not to the module itself). For example:
Directory::
my_project/
├── modules/
│ └──example/
│ ├──example.c
│ └──micropython.mk
└── micropython/
├──ports/
... ├──stm32/
...
Building for stm32 port:
.. code-block:: bash
cd my_project/micropython/ports/stm32
make USER_C_MODULES=../../../modules CFLAGS_EXTRA=-DMODULE_EXAMPLE_ENABLED=1 all
Module usage in MicroPython
---------------------------
Once built into your copy of MicroPython, the module implemented
in ``example.c`` above can now be accessed in Python just
like any other builtin module, eg
.. code-block:: python
import example
print(example.add_ints(1, 3))
# should display 4

View File

@ -1,14 +0,0 @@
Developing and building MicroPython
===================================
This chapter describes some options for extending MicroPython in C. Note
that it doesn't aim to be a complete guide for developing with MicroPython.
See the `getting started guide
<https://github.com/micropython/micropython/wiki/Getting-Started>`_ for further information.
.. toctree::
:maxdepth: 1
cmodules.rst
qstr.rst
natmod.rst

View File

@ -1,202 +0,0 @@
.. _natmod:
Native machine code in .mpy files
=================================
This section describes how to build and work with .mpy files that contain native
machine code from a language other than Python. This allows you to
write code in a language like C, compile and link it into a .mpy file, and then
import this file like a normal Python module. This can be used for implementing
functionality which is performance critical, or for including an existing
library written in another language.
One of the main advantages of using native .mpy files is that native machine code
can be imported by a script dynamically, without the need to rebuild the main
MicroPython firmware. This is in contrast to :ref:`cmodules` which also allows
defining custom modules in C but they must be compiled into the main firmware image.
The focus here is on using C to build native modules, but in principle any
language which can be compiled to stand-alone machine code can be put into a
.mpy file.
A native .mpy module is built using the ``mpy_ld.py`` tool, which is found in the
``tools/`` directory of the project. This tool takes a set of object files
(.o files) and links them together to create a native .mpy files.
Supported features and limitations
----------------------------------
A .mpy file can contain MicroPython bytecode and/or native machine code. If it
contains native machine code then the .mpy file has a specific architecture
associated with it. Current supported architectures are (these are the valid
options for the ``ARCH`` variable, see below):
* ``x86`` (32 bit)
* ``x64`` (64 bit x86)
* ``armv7m`` (ARM Thumb 2, eg Cortex-M3)
* ``armv7emsp`` (ARM Thumb 2, single precision float, eg Cortex-M4F, Cortex-M7)
* ``armv7emdp`` (ARM Thumb 2, double precision float, eg Cortex-M7)
* ``xtensa`` (non-windowed, eg ESP8266)
* ``xtensawin`` (windowed with window size 8, eg ESP32)
When compiling and linking the native .mpy file the architecture must be chosen
and the corresponding file can only be imported on that architecture. For more
details about .mpy files see :ref:`mpy_files`.
Native code must be compiled as position independent code (PIC) and use a global
offset table (GOT), although the details of this varies from architecture to
architecture. When importing .mpy files with native code the import machinery
is able to do some basic relocation of the native code. This includes
relocating text, rodata and BSS sections.
Supported features of the linker and dynamic loader are:
* executable code (text)
* read-only data (rodata), including strings and constant data (arrays, structs, etc)
* zeroed data (BSS)
* pointers in text to text, rodata and BSS
* pointers in rodata to text, rodata and BSS
The known limitations are:
* data sections are not supported; workaround: use BSS data and initialise the
data values explicitly
* static BSS variables are not supported; workaround: use global BSS variables
So, if your C code has writable data, make sure the data is defined globally,
without an initialiser, and only written to within functions.
Defining a native module
------------------------
A native .mpy module is defined by a set of files that are used to build the .mpy.
The filesystem layout consists of two main parts, the source files and the Makefile:
* In the simplest case only a single C source file is required, which contains all
the code that will be compiled into the .mpy module. This C source code must
include the ``py/dynruntime.h`` file to access the MicroPython dynamic API, and
must at least define a function called ``mpy_init``. This function will be the
entry point of the module, called when the module is imported.
The module can be split into multiple C source files if desired. Parts of the
module can also be implemented in Python. All source files should be listed in
the Makefile, by adding them to the ``SRC`` variable (see below). This includes
both C source files as well as any Python files which will be included in the
resulting .mpy file.
* The ``Makefile`` contains the build configuration for the module and list the
source files used to build the .mpy module. It should define ``MPY_DIR`` as the
location of the MicroPython repository (to find header files, the relevant Makefile
fragment, and the ``mpy_ld.py`` tool), ``MOD`` as the name of the module, ``SRC``
as the list of source files, optionally specify the machine architecture via ``ARCH``,
and then include ``py/dynruntime.mk``.
Minimal example
---------------
This section provides a fully working example of a simple module named ``factorial``.
This module provides a single function ``factorial.factorial(x)`` which computes the
factorial of the input and returns the result.
Directory layout::
factorial/
├── factorial.c
└── Makefile
The file ``factorial.c`` contains:
.. code-block:: c
// Include the header file to get access to the MicroPython API
#include "py/dynruntime.h"
// Helper function to compute factorial
STATIC mp_int_t factorial_helper(mp_int_t x) {
if (x == 0) {
return 1;
}
return x * factorial_helper(x - 1);
}
// This is the function which will be called from Python, as factorial(x)
STATIC mp_obj_t factorial(mp_obj_t x_obj) {
// Extract the integer from the MicroPython input object
mp_int_t x = mp_obj_get_int(x_obj);
// Calculate the factorial
mp_int_t result = factorial_helper(x);
// Convert the result to a MicroPython integer object and return it
return mp_obj_new_int(result);
}
// Define a Python reference to the function above
STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial);
// This is the entry point and is called when the module is imported
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
// This must be first, it sets up the globals dict and other things
MP_DYNRUNTIME_INIT_ENTRY
// Make the function available in the module's namespace
mp_store_global(MP_QSTR_factorial, MP_OBJ_FROM_PTR(&factorial_obj));
// This must be last, it restores the globals dict
MP_DYNRUNTIME_INIT_EXIT
}
The file ``Makefile`` contains:
.. code-block:: make
# Location of top-level MicroPython directory
MPY_DIR = ../../..
# Name of module
MOD = features0
# Source files (.c or .py)
SRC = features0.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64
# Include to get the rules for compiling and linking the module
include $(MPY_DIR)/py/dynruntime.mk
Compiling the module
--------------------
Be sure to select the correct ``ARCH`` for the target you are going to run on.
Then build with::
$ make
Without modifying the Makefile you can specify the target architecture via::
$ make ARCH=armv7m
Module usage in MicroPython
---------------------------
Once the module is built there should be a file called ``factorial.mpy``. Copy
this so it is accessible on the filesystem of your MicroPython system and can be
found in the import path. The module con now be accessed in Python just like any
other module, for example::
import factorial
print(factorial.factorial(10))
# should display 3628800
Further examples
----------------
See ``examples/natmod/`` for further examples which show many of the available
features of native .mpy modules. Such features include:
* using multiple C source files
* including Python code alongside C code
* rodata and BSS data
* memory allocation
* use of floating point
* exception handling
* including external C libraries

View File

@ -1,112 +0,0 @@
MicroPython string interning
============================
MicroPython uses `string interning`_ to save both RAM and ROM. This avoids
having to store duplicate copies of the same string. Primarily, this applies to
identifiers in your code, as something like a function or variable name is very
likely to appear in multiple places in the code. In MicroPython an interned
string is called a QSTR (uniQue STRing).
A QSTR value (with type ``qstr``) is a index into a linked list of QSTR pools.
QSTRs store their length and a hash of their contents for fast comparison during
the de-duplication process. All bytecode operations that work with strings use
a QSTR argument.
Compile-time QSTR generation
----------------------------
In the MicroPython C code, any strings that should be interned in the final
firmware are written as ``MP_QSTR_Foo``. At compile time this will evaluate to
a ``qstr`` value that points to the index of ``"Foo"`` in the QSTR pool.
A multi-step process in the ``Makefile`` makes this work. In summary this
process has three parts:
1. Find all ``MP_QSTR_Foo`` tokens in the code.
2. Generate a static QSTR pool containing all the string data (including lengths
and hashes).
3. Replace all ``MP_QSTR_Foo`` (via the preprocessor) with their corresponding
index.
``MP_QSTR_Foo`` tokens are searched for in two sources:
1. All files referenced in ``$(SRC_QSTR)``. This is all C code (i.e. ``py``,
``extmod``, ``ports/stm32``) but not including third-party code such as
``lib``.
2. Additional ``$(QSTR_GLOBAL_DEPENDENCIES)`` (which includes ``mpconfig*.h``).
*Note:* ``frozen_mpy.c`` (generated by mpy-tool.py) has its own QSTR generation
and pool.
Some additional strings that can't be expressed using the ``MP_QSTR_Foo`` syntax
(e.g. they contain non-alphanumeric characters) are explicitly provided in
``qstrdefs.h`` and ``qstrdefsport.h`` via the ``$(QSTR_DEFS)`` variable.
Processing happens in the following stages:
1. ``qstr.i.last`` is the concatenation of putting every single input file
through the C pre-processor. This means that any conditionally disabled code
will be removed, and macros expanded. This means we don't add strings to the
pool that won't be used in the final firmware. Because at this stage (thanks
to the ``NO_QSTR`` macro added by ``QSTR_GEN_EXTRA_CFLAGS``) there is no
definition for ``MP_QSTR_Foo`` it passes through this stage unaffected. This
file also includes comments from the preprocessor that include line number
information. Note that this step only uses files that have changed, which
means that ``qstr.i.last`` will only contain data from files that have
changed since the last compile.
2. ``qstr.split`` is an empty file created after running ``makeqstrdefs.py split``
on qstr.i.last. It's just used as a dependency to indicate that the step ran.
This script outputs one file per input C file, ``genhdr/qstr/...file.c.qstr``,
which contains only the matched QSTRs. Each QSTR is printed as ``Q(Foo)``.
This step is necessary to combine the existing files with the new data
generated from the incremental update in ``qstr.i.last``.
3. ``qstrdefs.collected.h`` is the output of concatenating ``genhdr/qstr/*``
using ``makeqstrdefs.py cat``. This is now the full set of ``MP_QSTR_Foo``'s
found in the code, now formatted as ``Q(Foo)``, one-per-line, with duplicates.
This file is only updated if the set of qstrs has changed. A hash of the QSTR
data is written to another file (``qstrdefs.collected.h.hash``) which allows
it to track changes across builds.
4. ``qstrdefs.preprocessed.h`` adds in the QSTRs from qstrdefs*. It
concatenates ``qstrdefs.collected.h`` with ``qstrdefs*.h``, then it transforms
each line from ``Q(Foo)`` to ``"Q(Foo)"`` so they pass through the preprocessor
unchanged. Then the preprocessor is used to deal with any conditional
compilation in ``qstrdefs*.h``. Then the transformation is undone back to
``Q(Foo)``, and saved as ``qstrdefs.preprocessed.h``.
5. ``qstrdefs.generated.h`` is the output of ``makeqstrdata.py``. For each
``Q(Foo)`` in qstrdefs.preprocessed.h (plus some extra hard-coded ones), it outputs
``QDEF(MP_QSTR_Foo, (const byte*)"hash" "Foo")``.
Then in the main compile, two things happen with ``qstrdefs.generated.h``:
1. In qstr.h, each QDEF becomes an entry in an enum, which makes ``MP_QSTR_Foo``
available to code and equal to the index of that string in the QSTR table.
2. In qstr.c, the actual QSTR data table is generated as elements of the
``mp_qstr_const_pool->qstrs``.
.. _`string interning`: https://en.wikipedia.org/wiki/String_interning
Run-time QSTR generation
------------------------
Additional QSTR pools can be created at runtime so that strings can be added to
them. For example, the code::
foo[x] = 3
Will need to create a QSTR for the value of ``x`` so it can be used by the
"load attr" bytecode.
Also, when compiling Python code, identifiers and literals need to have QSTRs
created. Note: only literals shorter than 10 characters become QSTRs. This is
because a regular string on the heap always takes up a minimum of 16 bytes (one
GC block), whereas QSTRs allow them to be packed more efficiently into the pool.
QSTR pools (and the underlying "chunks" that store the string data) are allocated
on-demand on the heap with a minimum size.

View File

@ -1,11 +0,0 @@
.. _cpython_diffs:
MicroPython differences from CPython
====================================
The operations listed in this section produce conflicting results in MicroPython when compared to standard Python.
MicroPython implements Python 3.4 and some select features of Python 3.5.
.. toctree::
:maxdepth: 2

View File

@ -1,64 +0,0 @@
.. _esp32_general:
General information about the ESP32 port
========================================
The ESP32 is a popular WiFi and Bluetooth enabled System-on-Chip (SoC) by
Espressif Systems.
Multitude of boards
-------------------
There is a multitude of modules and boards from different sources which carry
the ESP32 chip. MicroPython tries to provide a generic port which would run on
as many boards/modules as possible, but there may be limitations. Espressif
development boards are taken as reference for the port (for example, testing is
performed on them). For any board you are using please make sure you have a
datasheet, schematics and other reference materials so you can look up any
board-specific functions.
To make a generic ESP32 port and support as many boards as possible the
following design and implementation decision were made:
* GPIO pin numbering is based on ESP32 chip numbering. Please have the manual/pin
diagram of your board at hand to find correspondence between your board pins and
actual ESP32 pins.
* All pins are supported by MicroPython but not all are usable on any given board.
For example pins that are connected to external SPI flash should not be used,
and a board may only expose a certain selection of pins.
Technical specifications and SoC datasheets
-------------------------------------------
The datasheets and other reference material for ESP32 chip are available
from the vendor site: https://www.espressif.com/en/support/download/documents?keys=esp32 .
They are the primary reference for the chip technical specifications, capabilities,
operating modes, internal functioning, etc.
For your convenience, some of technical specifications are provided below:
* Architecture: Xtensa Dual-Core 32-bit LX6
* CPU frequency: up to 240MHz
* Total RAM available: 528KB (part of it reserved for system)
* BootROM: 448KB
* Internal FlashROM: none
* External FlashROM: code and data, via SPI Flash; usual size 4MB
* GPIO: 34 (GPIOs are multiplexed with other functions, including
external FlashROM, UART, etc.)
* UART: 3 RX/TX UART (no hardware handshaking), one TX-only UART
* SPI: 4 SPI interfaces (one used for FlashROM)
* I2C: 2 I2C (bitbang implementation available on any pins)
* I2S: 2
* ADC: 12-bit SAR ADC up to 18 channels
* DAC: 2 8-bit DACs
* RMT: 8 channels allowing accurate pulse transmit/receive
* Programming: using BootROM bootloader from UART - due to external FlashROM
and always-available BootROM bootloader, the ESP32 is not brickable
For more information see the ESP32 datasheet: https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
MicroPython is implemented on top of the ESP-IDF, Espressif's development
framework for the ESP32. This is a FreeRTOS based system. See the
`ESP-IDF Programming Guide <https://docs.espressif.com/projects/esp-idf/en/latest/index.html>`_
for details.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

View File

@ -1,519 +0,0 @@
.. _esp32_quickref:
Quick reference for the ESP32
=============================
.. image:: img/esp32.jpg
:alt: ESP32 board
:width: 640px
The Espressif ESP32 Development Board (image attribution: Adafruit).
Below is a quick reference for ESP32-based boards. If it is your first time
working with this board it may be useful to get an overview of the microcontroller:
.. toctree::
:maxdepth: 1
general.rst
tutorial/intro.rst
Installing MicroPython
----------------------
See the corresponding section of tutorial: :ref:`esp32_intro`. It also includes
a troubleshooting subsection.
General board control
---------------------
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200.
Tab-completion is useful to find out what methods an object has.
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
the REPL.
The :mod:`machine` module::
import machine
machine.freq() # get the current frequency of the CPU
machine.freq(240000000) # set the CPU frequency to 240 MHz
The :mod:`esp` module::
import esp
esp.osdebug(None) # turn off vendor O/S debugging messages
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)
# low level methods to interact with flash storage
esp.flash_size()
esp.flash_user_start()
esp.flash_erase(sector_no)
esp.flash_write(byte_offset, buffer)
esp.flash_read(byte_offset, buffer)
The :mod:`esp32` module::
import esp32
esp32.hall_sensor() # read the internal hall sensor
esp32.raw_temperature() # read the internal temperature of the MCU, in Farenheit
esp32.ULP() # access to the Ultra-Low-Power Co-processor
Note that the temperature sensor in the ESP32 will typically read higher than
ambient due to the IC getting warm while it runs. This effect can be minimised
by reading the temperature sensor immediately after waking up from sleep.
Networking
----------
The :mod:`network` module::
import network
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac') # get the interface's MAC address
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.config(essid='ESP-AP') # set the ESSID of the access point
ap.active(True) # activate the interface
A useful function for connecting to your local WiFi network is::
def do_connect():
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('essid', 'password')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
Once the network is established the :mod:`socket <usocket>` module can be used
to create and use TCP/UDP sockets as usual, and the ``urequests`` module for
convenient HTTP requests.
Delay and timing
----------------
Use the :mod:`time <utime>` module::
import time
time.sleep(1) # sleep for 1 second
time.sleep_ms(500) # sleep for 500 milliseconds
time.sleep_us(10) # sleep for 10 microseconds
start = time.ticks_ms() # get millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
Timers
------
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class
with timer ID of -1::
from machine import Timer
tim = Timer(-1)
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
The period is in milliseconds.
.. _Pins_and_GPIO:
Pins and GPIO
-------------
Use the :ref:`machine.Pin <machine.Pin>` class::
from machine import Pin
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
p0.on() # set pin to "on" (high) level
p0.off() # set pin to "off" (low) level
p0.value(1) # set pin to on/high
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
print(p2.value()) # get value, 0 or 1
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
Available Pins are from the following ranges (inclusive): 0-19, 21-23, 25-27, 32-39.
These correspond to the actual GPIO pin numbers of ESP32 chip. Note that many
end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...).
For mapping between board logical pins and physical chip pins consult your board
documentation.
Notes:
* Pins 1 and 3 are REPL UART TX and RX respectively
* Pins 6, 7, 8, 11, 16, and 17 are used for connecting the embedded flash,
and are not recommended for other uses
* Pins 34-39 are input only, and also do not have internal pull-up resistors
* The pull value of some pins can be set to ``Pin.PULL_HOLD`` to reduce power
consumption during deepsleep.
PWM (pulse width modulation)
----------------------------
PWM can be enabled on all output-enabled pins. The base frequency can
range from 1Hz to 40MHz but there is a tradeoff; as the base frequency
*increases* the duty resolution *decreases*. See
`LED Control <https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html>`_
for more details.
Use the ``machine.PWM`` class::
from machine import Pin, PWM
pwm0 = PWM(Pin(0)) # create PWM object from a pin
pwm0.freq() # get current frequency
pwm0.freq(1000) # set frequency
pwm0.duty() # get current duty cycle
pwm0.duty(200) # set duty cycle
pwm0.deinit() # turn off PWM on the pin
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
ADC (analog to digital conversion)
----------------------------------
On the ESP32 ADC functionality is available on Pins 32-39. Note that, when
using the default configuration, input voltages on the ADC pin must be between
0.0v and 1.0v (anything above 1.0v will just read as 4095). Attenuation must
be applied in order to increase this usable voltage range.
Use the :ref:`machine.ADC <machine.ADC>` class::
from machine import ADC
adc = ADC(Pin(32)) # create ADC object on ADC pin
adc.read() # read value, 0-4095 across voltage range 0.0v - 1.0v
adc.atten(ADC.ATTN_11DB) # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v)
adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511)
adc.read() # read value using the newly configured attenuation and width
ESP32 specific ADC class method reference:
.. method:: ADC.atten(attenuation)
This method allows for the setting of the amount of attenuation on the
input of the ADC. This allows for a wider possible input voltage range,
at the cost of accuracy (the same number of bits now represents a wider
range). The possible attenuation options are:
- ``ADC.ATTN_0DB``: 0dB attenuation, gives a maximum input voltage
of 1.00v - this is the default configuration
- ``ADC.ATTN_2_5DB``: 2.5dB attenuation, gives a maximum input voltage
of approximately 1.34v
- ``ADC.ATTN_6DB``: 6dB attenuation, gives a maximum input voltage
of approximately 2.00v
- ``ADC.ATTN_11DB``: 11dB attenuation, gives a maximum input voltage
of approximately 3.6v
.. Warning::
Despite 11dB attenuation allowing for up to a 3.6v range, note that the
absolute maximum voltage rating for the input pins is 3.6v, and so going
near this boundary may be damaging to the IC!
.. method:: ADC.width(width)
This method allows for the setting of the number of bits to be utilised
and returned during ADC reads. Possible width options are:
- ``ADC.WIDTH_9BIT``: 9 bit data
- ``ADC.WIDTH_10BIT``: 10 bit data
- ``ADC.WIDTH_11BIT``: 11 bit data
- ``ADC.WIDTH_12BIT``: 12 bit data - this is the default configuration
Software SPI bus
----------------
There are two SPI drivers. One is implemented in software (bit-banging)
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>`
class::
from machine import Pin, SPI
# construct an SPI bus on the given pins
# polarity is the idle state of SCK
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SPI(baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
spi.init(baudrate=200000) # set the baudrate
spi.read(10) # read 10 bytes on MISO
spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI
buf = bytearray(50) # create a buffer
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
spi.write(b'12345') # write 5 bytes on MOSI
buf = bytearray(4) # create a buffer
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
.. Warning::
Currently *all* of ``sck``, ``mosi`` and ``miso`` *must* be specified when
initialising Software SPI.
Hardware SPI bus
----------------
There are two hardware SPI channels that allow faster transmission
rates (up to 80Mhz). These may be used on any IO pins that support the
required direction and are otherwise unused (see :ref:`Pins_and_GPIO`)
but if they are not configured to their default pins then they need to
pass through an extra layer of GPIO multiplexing, which can impact
their reliability at high speeds. Hardware SPI channels are limited
to 40MHz when used on pins other than the default ones listed below.
===== =========== ============
\ HSPI (id=1) VSPI (id=2)
===== =========== ============
sck 14 18
mosi 13 23
miso 12 19
===== =========== ============
Hardware SPI has the same methods as Software SPI above::
from machine import Pin, SPI
hspi = SPI(1, 10000000, sck=Pin(14), mosi=Pin(13), miso=Pin(12))
vspi = SPI(2, baudrate=80000000, polarity=0, phase=0, bits=8, firstbit=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
I2C bus
-------
The I2C driver has both software and hardware implementations, and the two
hardware peripherals have identifiers 0 and 1. Any available output-capable
pins can be used for SCL and SDA. The driver is accessed via the
:ref:`machine.I2C <machine.I2C>` class::
from machine import Pin, I2C
# construct a software I2C bus
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
# construct a hardware I2C bus
i2c = I2C(0)
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
i2c.scan() # scan for slave devices
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
buf = bytearray(10) # create a buffer with 10 bytes
i2c.writeto(0x3a, buf) # write the given buffer to the slave
Real time clock (RTC)
---------------------
See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
Deep-sleep mode
---------------
The following code can be used to sleep, wake and check the reset cause::
import machine
# check if the device woke from a deep sleep
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
# put the device to sleep for 10 seconds
machine.deepsleep(10000)
Notes:
* Calling ``deepsleep()`` without an argument will put the device to sleep
indefinitely
* A software reset does not change the reset cause
* There may be some leakage current flowing through enabled internal pullups.
To further reduce power consumption it is possible to disable the internal pullups::
p1 = Pin(4, Pin.IN, Pin.PULL_HOLD)
After leaving deepsleep it may be necessary to un-hold the pin explicitly (e.g. if
it is an output pin) via::
p1 = Pin(4, Pin.OUT, None)
RMT
---
The RMT is ESP32-specific and allows generation of accurate digital pulses with
12.5ns resolution. See :ref:`esp32.RMT <esp32.RMT>` for details. Usage is::
import esp32
from machine import Pin
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
# The channel resolution is 100ns (1/(source_freq/clock_div)).
r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
OneWire driver
--------------
The OneWire driver is implemented in software and works on all pins::
from machine import Pin
import onewire
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
ow.scan() # return a list of devices on the bus
ow.reset() # reset the bus
ow.readbyte() # read a byte
ow.writebyte(0x12) # write a byte on the bus
ow.write('123') # write bytes on the bus
ow.select_rom(b'12345678') # select a specific device by its ROM code
There is a specific driver for DS18S20 and DS18B20 devices::
import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(ds.read_temp(rom))
Be sure to put a 4.7k pull-up resistor on the data line. Note that
the ``convert_temp()`` method must be called each time you want to
sample the temperature.
NeoPixel driver
---------------
Use the ``neopixel`` module::
from machine import Pin
from neopixel import NeoPixel
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels
np[0] = (255, 255, 255) # set the first pixel to white
np.write() # write data to all pixels
r, g, b = np[0] # get first pixel colour
For low-level driving of a NeoPixel::
import esp
esp.neopixel_write(pin, grb_buf, is800khz)
.. Warning::
By default ``NeoPixel`` is configured to control the more popular *800kHz*
units. It is possible to use alternative timing to control other (typically
400kHz) devices by passing ``timing=0`` when constructing the
``NeoPixel`` object.
Capacitive Touch
----------------
Use the ``TouchPad`` class in the ``machine`` module::
from machine import TouchPad, Pin
t = TouchPad(Pin(14))
t.read() # Returns a smaller number when touched
``TouchPad.read`` returns a value relative to the capacitive variation. Small numbers (typically in
the *tens*) are common when a pin is touched, larger numbers (above *one thousand*) when
no touch is present. However the values are *relative* and can vary depending on the board
and surrounding composition so some calibration may be required.
There are ten capacitive touch-enabled pins that can be used on the ESP32: 0, 2, 4, 12, 13
14, 15, 27, 32, 33. Trying to assign to any other pins will result in a ``ValueError``.
Note that TouchPads can be used to wake an ESP32 from sleep::
import machine
from machine import TouchPad, Pin
import esp32
t = TouchPad(Pin(14))
t.config(500) # configure the threshold at which the pin is considered touched
esp32.wake_on_touch(True)
machine.lightsleep() # put the MCU to sleep until a touchpad is touched
For more details on touchpads refer to `Espressif Touch Sensor
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/touch_pad.html>`_.
DHT driver
----------
The DHT driver is implemented in software and works on all pins::
import dht
import machine
d = dht.DHT11(machine.Pin(4))
d.measure()
d.temperature() # eg. 23 (°C)
d.humidity() # eg. 41 (% RH)
d = dht.DHT22(machine.Pin(4))
d.measure()
d.temperature() # eg. 23.6 (°C)
d.humidity() # eg. 41.3 (% RH)
WebREPL (web browser interactive prompt)
----------------------------------------
WebREPL (REPL over WebSockets, accessible via a web browser) is an
experimental feature available in ESP32 port. Download web client
from https://github.com/micropython/webrepl (hosted version available
at http://micropython.org/webrepl), and configure it by executing::
import webrepl_setup
and following on-screen instructions. After reboot, it will be available
for connection. If you disabled automatic start-up on boot, you may
run configured daemon on demand using::
import webrepl
webrepl.start()
# or, start with a specific password
webrepl.start(password='mypass')
The WebREPL daemon listens on all active interfaces, which can be STA or
AP. This allows you to connect to the ESP32 via a router (the STA
interface) or directly when connected to its access point.
In addition to terminal/command prompt access, WebREPL also has provision
for file transfer (both upload and download). The web client has buttons for
the corresponding functions, or you can use the command-line client
``webrepl_cli.py`` from the repository above.
See the MicroPython forum for other community-supported alternatives
to transfer files to an ESP32 board.

View File

@ -1,139 +0,0 @@
.. _esp32_intro:
Getting started with MicroPython on the ESP32
=============================================
Using MicroPython is a great way to get the most of your ESP32 board. And
vice versa, the ESP32 chip is a great platform for using MicroPython. This
tutorial will guide you through setting up MicroPython, getting a prompt, using
WebREPL, connecting to the network and communicating with the Internet, using
the hardware peripherals, and controlling some external components.
Let's get started!
Requirements
------------
The first thing you need is a board with an ESP32 chip. The MicroPython
software supports the ESP32 chip itself and any board should work. The main
characteristic of a board is how the GPIO pins are connected to the outside
world, and whether it includes a built-in USB-serial convertor to make the
UART available to your PC.
Names of pins will be given in this tutorial using the chip names (eg GPIO2)
and it should be straightforward to find which pin this corresponds to on your
particular board.
Powering the board
------------------
If your board has a USB connector on it then most likely it is powered through
this when connected to your PC. Otherwise you will need to power it directly.
Please refer to the documentation for your board for further details.
Getting the firmware
--------------------
The first thing you need to do is download the most recent MicroPython firmware
.bin file to load onto your ESP32 device. You can download it from the
`MicroPython downloads page <https://micropython.org/download#esp32>`_.
From here, you have 3 main choices:
* Stable firmware builds
* Daily firmware builds
* Daily firmware builds with SPIRAM support
If you are just starting with MicroPython, the best bet is to go for the Stable
firmware builds. If you are an advanced, experienced MicroPython ESP32 user
who would like to follow development closely and help with testing new
features, there are daily builds. If your board has SPIRAM support you can
use either the standard firmware or the firmware with SPIRAM support, and in
the latter case you will have access to more RAM for Python objects.
Deploying the firmware
----------------------
Once you have the MicroPython firmware you need to load it onto your ESP32 device.
There are two main steps to do this: first you need to put your device in
bootloader mode, and second you need to copy across the firmware. The exact
procedure for these steps is highly dependent on the particular board and you will
need to refer to its documentation for details.
Fortunately, most boards have a USB connector, a USB-serial convertor, and the DTR
and RTS pins wired in a special way then deploying the firmware should be easy as
all steps can be done automatically. Boards that have such features
include the Adafruit Feather HUZZAH32, M5Stack, Wemos LOLIN32, and TinyPICO
boards, along with the Espressif DevKitC, PICO-KIT, WROVER-KIT dev-kits.
For best results it is recommended to first erase the entire flash of your
device before putting on new MicroPython firmware.
Currently we only support esptool.py to copy across the firmware. You can find
this tool here: `<https://github.com/espressif/esptool/>`__, or install it
using pip::
pip install esptool
Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer).
An older version (at least 1.2.1 is needed) works fine but will require Python
2.7.
Using esptool.py you can erase the flash with the command::
esptool.py --port /dev/ttyUSB0 erase_flash
And then deploy the new firmware using::
esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z 0x1000 esp32-20180511-v1.9.4.bin
Notes:
* You might need to change the "port" setting to something else relevant for your
PC
* You may need to reduce the baudrate if you get errors when flashing
(eg down to 115200 by adding ``--baud 115200`` into the command)
* For some boards with a particular FlashROM configuration you may need to
change the flash mode (eg by adding ``-fm dio`` into the command)
* The filename of the firmware should match the file that you have
If the above commands run without error then MicroPython should be installed on
your board!
Serial prompt
-------------
Once you have the firmware on the device you can access the REPL (Python prompt)
over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial
convertor, depending on your board. The baudrate is 115200.
From here you can now follow the ESP8266 tutorial, because these two Espressif chips
are very similar when it comes to using MicroPython on them. The ESP8266 tutorial
is found at :ref:`esp8266_tutorial` (but skip the Introduction section).
Troubleshooting installation problems
-------------------------------------
If you experience problems during flashing or with running firmware immediately
after it, here are troubleshooting recommendations:
* Be aware of and try to exclude hardware problems. There are 2 common
problems: bad power source quality, and worn-out/defective FlashROM.
Speaking of power source, not just raw amperage is important, but also low
ripple and noise/EMI in general. The most reliable and convenient power
source is a USB port.
* The flashing instructions above use flashing speed of 460800 baud, which is
good compromise between speed and stability. However, depending on your
module/board, USB-UART convertor, cables, host OS, etc., the above baud
rate may be too high and lead to errors. Try a more common 115200 baud
rate instead in such cases.
* To catch incorrect flash content (e.g. from a defective sector on a chip),
add ``--verify`` switch to the commands above.
* If you still experience problems with flashing the firmware please
refer to esptool.py project page, https://github.com/espressif/esptool
for additional documentation and a bug tracker where you can report problems.
* If you are able to flash the firmware but the ``--verify`` option returns
errors even after multiple retries the you may have a defective FlashROM chip.

View File

@ -1,197 +0,0 @@
.. _esp8266_general:
General information about the ESP8266 port
==========================================
ESP8266 is a popular WiFi-enabled System-on-Chip (SoC) by Espressif Systems.
Multitude of boards
-------------------
There is a multitude of modules and boards from different sources which carry
the ESP8266 chip. MicroPython tries to provide a generic port which would run on
as many boards/modules as possible, but there may be limitations. Adafruit
Feather HUZZAH board is taken as a reference board for the port (for example,
testing is performed on it). If you have another board, please make sure you
have a datasheet, schematics and other reference materials for your board
handy to look up various aspects of your board functioning.
To make a generic ESP8266 port and support as many boards as possible,
the following design and implementation decision were made:
* GPIO pin numbering is based on ESP8266 chip numbering, not some "logical"
numbering of a particular board. Please have the manual/pin diagram of your board
at hand to find correspondence between your board pins and actual ESP8266 pins.
We also encourage users of various boards to share this mapping via MicroPython
forum, with the idea to collect community-maintained reference materials
eventually.
* All pins which make sense to support, are supported by MicroPython
(for example, pins which are used to connect SPI flash
are not exposed, as they're unlikely useful for anything else, and
operating on them will lead to board lock-up). However, any particular
board may expose only subset of pins. Consult your board reference manual.
* Some boards may lack external pins/internal connectivity to support
ESP8266 deepsleep mode.
Technical specifications and SoC datasheets
-------------------------------------------
The datasheets and other reference material for ESP8266 chip are available
from the vendor site: http://bbs.espressif.com/viewtopic.php?f=67&t=225 .
They are the primary reference for the chip technical specifications, capabilities,
operating modes, internal functioning, etc.
For your convenience, some of technical specifications are provided below:
* Architecture: Xtensa lx106
* CPU frequency: 80MHz overclockable to 160MHz
* Total RAM available: 96KB (part of it reserved for system)
* BootROM: 64KB
* Internal FlashROM: None
* External FlashROM: code and data, via SPI Flash. Normal sizes 512KB-4MB.
* GPIO: 16 + 1 (GPIOs are multiplexed with other functions, including
external FlashROM, UART, deep sleep wake-up, etc.)
* UART: One RX/TX UART (no hardware handshaking), one TX-only UART.
* SPI: 2 SPI interfaces (one used for FlashROM).
* I2C: No native external I2C (bitbang implementation available on any pins).
* I2S: 1.
* Programming: using BootROM bootloader from UART. Due to external FlashROM
and always-available BootROM bootloader, ESP8266 is not brickable.
Scarcity of runtime resources
-----------------------------
ESP8266 has very modest resources (first of all, RAM memory). So, please
avoid allocating too big container objects (lists, dictionaries) and
buffers. There is also no full-fledged OS to keep track of resources
and automatically clean them up, so that's the task of a user/user
application: please be sure to close open files, sockets, etc. as soon
as possible after use.
Boot process
------------
On boot, MicroPython EPS8266 port executes ``_boot.py`` script from internal
frozen modules. It mounts filesystem in FlashROM, or if it's not available,
performs first-time setup of the module and creates the filesystem. This
part of the boot process is considered fixed, and not available for customization
for end users (even if you build from source, please refrain from changes to
it; customization of early boot process is available only to advanced users
and developers, who can diagnose themselves any issues arising from
modifying the standard process).
Once the filesystem is mounted, ``boot.py`` is executed from it. The standard
version of this file is created during first-time module set up and has
commands to start a WebREPL daemon (disabled by default, configurable
with ``webrepl_setup`` module), etc. This
file is customizable by end users (for example, you may want to set some
parameters or add other services which should be run on
a module start-up). But keep in mind that incorrect modifications to boot.py
may still lead to boot loops or lock ups, requiring to reflash a module
from scratch. (In particular, it's recommended that you use either
``webrepl_setup`` module or manual editing to configure WebREPL, but not
both).
As a final step of boot procedure, ``main.py`` is executed from filesystem,
if exists. This file is a hook to start up a user application each time
on boot (instead of going to REPL). For small test applications, you may
name them directly as ``main.py``, and upload to module, but instead it's
recommended to keep your application(s) in separate files, and have just
the following in ``main.py``::
import my_app
my_app.main()
This will allow to keep the structure of your application clear, as well as
allow to install multiple applications on a board, and switch among them.
Known Issues
------------
Real-time clock
~~~~~~~~~~~~~~~
RTC in ESP8266 has very bad accuracy, drift may be seconds per minute. As
a workaround, to measure short enough intervals you can use
``utime.time()``, etc. functions, and for wall clock time, synchronize from
the net using included ``ntptime.py`` module.
Due to limitations of the ESP8266 chip the internal real-time clock (RTC)
will overflow every 7:45h. If a long-term working RTC time is required then
``time()`` or ``localtime()`` must be called at least once within 7 hours.
MicroPython will then handle the overflow.
Sockets and WiFi buffers overflow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Socket instances remain active until they are explicitly closed. This has two
consequences. Firstly they occupy RAM, so an application which opens sockets
without closing them may eventually run out of memory. Secondly not properly
closed socket can cause the low-level part of the vendor WiFi stack to emit
``Lmac`` errors. This occurs if data comes in for a socket and is not
processed in a timely manner. This can overflow the WiFi stack input queue
and lead to a deadlock. The only recovery is by a hard reset.
The above may also happen after an application terminates and quits to the REPL
for any reason including an exception. Subsequent arrival of data provokes the
failure with the above error message repeatedly issued. So, sockets should be
closed in any case, regardless whether an application terminates successfully
or by an exception, for example using try/finally::
sock = socket(...)
try:
# Use sock
finally:
sock.close()
SSL/TLS limitations
~~~~~~~~~~~~~~~~~~~
ESP8266 uses `axTLS <http://axtls.sourceforge.net/>`_ library, which is one
of the smallest TLS libraries with the compatible licensing. However, it
also has some known issues/limitations:
1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve
cryptography (ECC). This means it can't work with sites which force
the use of these features (it works ok with classic RSA certificates).
2. Half-duplex communication nature. axTLS uses a single buffer for both
sending and receiving, which leads to considerable memory saving and
works well with protocols like HTTP. But there may be problems with
protocols which don't follow classic request-response model.
Besides axTLS own limitations, the configuration used for MicroPython is
highly optimized for code size, which leads to additional limitations
(these may be lifted in the future):
3. Optimized RSA algorithms are not enabled, which may lead to slow
SSL handshakes.
4. Stored sessions are not supported (may allow faster repeated connections
to the same site in some circumstances).
Besides axTLS specific limitations described above, there's another generic
limitation with usage of TLS on the low-memory devices:
5. The TLS standard specifies the maximum length of the TLS record (unit
of TLS communication, the entire record must be buffered before it can
be processed) as 16KB. That's almost half of the available ESP8266 memory,
and inside a more or less advanced application would be hard to allocate
due to memory fragmentation issues. As a compromise, a smaller buffer is
used, with the idea that the most interesting usage for SSL would be
accessing various REST APIs, which usually require much smaller messages.
The buffers size is on the order of 5KB, and is adjusted from time to
time, taking as a reference being able to access https://google.com .
The smaller buffer hower means that some sites can't be accessed using
it, and it's not possible to stream large amounts of data.
There are also some not implemented features specifically in MicroPython's
``ussl`` module based on axTLS:
6. Certificates are not validated (this may make connections susceptible
to man-in-the-middle attacks).
7. There is no support for client certificates (scheduled to be fixed in
1.9.4 release).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,394 +0,0 @@
.. _esp8266_quickref:
Quick reference for the ESP8266
===============================
.. image:: img/adafruit_products_pinoutstop.jpg
:alt: Adafruit Feather HUZZAH board
:width: 640px
The Adafruit Feather HUZZAH board (image attribution: Adafruit).
Below is a quick reference for ESP8266-based boards. If it is your first time
working with this board please consider reading the following sections first:
.. toctree::
:maxdepth: 1
general.rst
tutorial/index.rst
Installing MicroPython
----------------------
See the corresponding section of tutorial: :ref:`intro`. It also includes
a troubleshooting subsection.
General board control
---------------------
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200.
Tab-completion is useful to find out what methods an object has.
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
the REPL.
The :mod:`machine` module::
import machine
machine.freq() # get the current frequency of the CPU
machine.freq(160000000) # set the CPU frequency to 160 MHz
The :mod:`esp` module::
import esp
esp.osdebug(None) # turn off vendor O/S debugging messages
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)
Networking
----------
The :mod:`network` module::
import network
wlan = network.WLAN(network.STA_IF) # create station interface
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac') # get the interface's MAC adddress
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.active(True) # activate the interface
ap.config(essid='ESP-AP') # set the ESSID of the access point
A useful function for connecting to your local WiFi network is::
def do_connect():
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('essid', 'password')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
Once the network is established the :mod:`socket <usocket>` module can be used
to create and use TCP/UDP sockets as usual.
Delay and timing
----------------
Use the :mod:`time <utime>` module::
import time
time.sleep(1) # sleep for 1 second
time.sleep_ms(500) # sleep for 500 milliseconds
time.sleep_us(10) # sleep for 10 microseconds
start = time.ticks_ms() # get millisecond counter
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
Timers
------
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class
with timer ID of -1::
from machine import Timer
tim = Timer(-1)
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
The period is in milliseconds.
Pins and GPIO
-------------
Use the :ref:`machine.Pin <machine.Pin>` class::
from machine import Pin
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
p0.on() # set pin to "on" (high) level
p0.off() # set pin to "off" (low) level
p0.value(1) # set pin to on/high
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
print(p2.value()) # get value, 0 or 1
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
Available pins are: 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, which correspond
to the actual GPIO pin numbers of ESP8266 chip. Note that many end-user
boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). As
MicroPython supports different boards and modules, physical pin numbering
was chosen as the lowest common denominator. For mapping between board
logical pins and physical chip pins, consult your board documentation.
Note that Pin(1) and Pin(3) are REPL UART TX and RX respectively.
Also note that Pin(16) is a special pin (used for wakeup from deepsleep
mode) and may be not available for use with higher-level classes like
``Neopixel``.
PWM (pulse width modulation)
----------------------------
PWM can be enabled on all pins except Pin(16). There is a single frequency
for all channels, with range between 1 and 1000 (measured in Hz). The duty
cycle is between 0 and 1023 inclusive.
Use the ``machine.PWM`` class::
from machine import Pin, PWM
pwm0 = PWM(Pin(0)) # create PWM object from a pin
pwm0.freq() # get current frequency
pwm0.freq(1000) # set frequency
pwm0.duty() # get current duty cycle
pwm0.duty(200) # set duty cycle
pwm0.deinit() # turn off PWM on the pin
pwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go
ADC (analog to digital conversion)
----------------------------------
ADC is available on a dedicated pin.
Note that input voltages on the ADC pin must be between 0v and 1.0v.
Use the :ref:`machine.ADC <machine.ADC>` class::
from machine import ADC
adc = ADC(0) # create ADC object on ADC pin
adc.read() # read value, 0-1024
Software SPI bus
----------------
There are two SPI drivers. One is implemented in software (bit-banging)
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>`
class::
from machine import Pin, SPI
# construct an SPI bus on the given pins
# polarity is the idle state of SCK
# phase=0 means sample on the first edge of SCK, phase=1 means the second
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
spi.init(baudrate=200000) # set the baudrate
spi.read(10) # read 10 bytes on MISO
spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI
buf = bytearray(50) # create a buffer
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
spi.write(b'12345') # write 5 bytes on MOSI
buf = bytearray(4) # create a buffer
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
Hardware SPI bus
----------------
The hardware SPI is faster (up to 80Mhz), but only works on following pins:
``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same
methods as the bitbanging SPI class above, except for the pin parameters for the
constructor and init (as those are fixed)::
from machine import Pin, SPI
hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)
(``SPI(0)`` is used for FlashROM and not available to users.)
I2C bus
-------
The I2C driver is implemented in software and works on all pins,
and is accessed via the :ref:`machine.I2C <machine.I2C>` class::
from machine import Pin, I2C
# construct an I2C bus
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
buf = bytearray(10) # create a buffer with 10 bytes
i2c.writeto(0x3a, buf) # write the given buffer to the slave
Real time clock (RTC)
---------------------
See :ref:`machine.RTC <machine.RTC>` ::
from machine import RTC
rtc = RTC()
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
rtc.datetime() # get date and time
# synchronize with ntp
# need to be connected to wifi
import ntptime
ntptime.settime() # set the rtc datetime from the remote server
rtc.datetime() # get the date and time in UTC
.. note:: Not all methods are implemented: `RTC.now()`, `RTC.irq(handler=*) <RTC.irq>`
(using a custom handler), `RTC.init()` and `RTC.deinit()` are
currently not supported.
Deep-sleep mode
---------------
Connect GPIO16 to the reset pin (RST on HUZZAH). Then the following code
can be used to sleep, wake and check the reset cause::
import machine
# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
# check if the device woke from a deep sleep
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000)
# put the device to sleep
machine.deepsleep()
OneWire driver
--------------
The OneWire driver is implemented in software and works on all pins::
from machine import Pin
import onewire
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
ow.scan() # return a list of devices on the bus
ow.reset() # reset the bus
ow.readbyte() # read a byte
ow.writebyte(0x12) # write a byte on the bus
ow.write('123') # write bytes on the bus
ow.select_rom(b'12345678') # select a specific device by its ROM code
There is a specific driver for DS18S20 and DS18B20 devices::
import time, ds18x20
ds = ds18x20.DS18X20(ow)
roms = ds.scan()
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(ds.read_temp(rom))
Be sure to put a 4.7k pull-up resistor on the data line. Note that
the ``convert_temp()`` method must be called each time you want to
sample the temperature.
NeoPixel driver
---------------
Use the ``neopixel`` module::
from machine import Pin
from neopixel import NeoPixel
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels
np[0] = (255, 255, 255) # set the first pixel to white
np.write() # write data to all pixels
r, g, b = np[0] # get first pixel colour
For low-level driving of a NeoPixel::
import esp
esp.neopixel_write(pin, grb_buf, is800khz)
APA102 driver
-------------
Use the ``apa102`` module::
from machine import Pin
from apa102 import APA102
clock = Pin(14, Pin.OUT) # set GPIO14 to output to drive the clock
data = Pin(13, Pin.OUT) # set GPIO13 to output to drive the data
apa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixels
apa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31
apa.write() # write data to all pixels
r, g, b, brightness = apa[0] # get first pixel colour
For low-level driving of an APA102::
import esp
esp.apa102_write(clock_pin, data_pin, rgbi_buf)
DHT driver
----------
The DHT driver is implemented in software and works on all pins::
import dht
import machine
d = dht.DHT11(machine.Pin(4))
d.measure()
d.temperature() # eg. 23 (°C)
d.humidity() # eg. 41 (% RH)
d = dht.DHT22(machine.Pin(4))
d.measure()
d.temperature() # eg. 23.6 (°C)
d.humidity() # eg. 41.3 (% RH)
WebREPL (web browser interactive prompt)
----------------------------------------
WebREPL (REPL over WebSockets, accessible via a web browser) is an
experimental feature available in ESP8266 port. Download web client
from https://github.com/micropython/webrepl (hosted version available
at http://micropython.org/webrepl), and configure it by executing::
import webrepl_setup
and following on-screen instructions. After reboot, it will be available
for connection. If you disabled automatic start-up on boot, you may
run configured daemon on demand using::
import webrepl
webrepl.start()
The supported way to use WebREPL is by connecting to ESP8266 access point,
but the daemon is also started on STA interface if it is active, so if your
router is set up and works correctly, you may also use WebREPL while connected
to your normal Internet access point (use the ESP8266 AP connection method
if you face any issues).
Besides terminal/command prompt access, WebREPL also has provision for file
transfer (both upload and download). Web client has buttons for the
corresponding functions, or you can use command-line client ``webrepl_cli.py``
from the repository above.
See the MicroPython forum for other community-supported alternatives
to transfer files to ESP8266.

View File

@ -1,19 +0,0 @@
Analog to Digital Conversion
============================
The ESP8266 has a single pin (separate to the GPIO pins) which can be used to
read analog voltages and convert them to a digital value. You can construct
such an ADC pin object using::
>>> import machine
>>> adc = machine.ADC(0)
Then read its value with::
>>> adc.read()
58
The values returned from the ``read()`` function are between 0 (for 0.0 volts)
and 1024 (for 1.0 volts). Please note that this input can only tolerate a
maximum of 1.0 volts and you must use a voltage divider circuit to measure
larger voltages.

View File

@ -1,91 +0,0 @@
Controlling APA102 LEDs
=======================
APA102 LEDs, also known as DotStar LEDs, are individually addressable
full-colour RGB LEDs, generally in a string formation. They differ from
NeoPixels in that they require two pins to control - both a Clock and Data pin.
They can operate at a much higher data and PWM frequencies than NeoPixels and
are more suitable for persistence-of-vision effects.
To create an APA102 object do the following::
>>> import machine, apa102
>>> strip = apa102.APA102(machine.Pin(5), machine.Pin(4), 60)
This configures an 60 pixel APA102 strip with clock on GPIO5 and data on GPIO4.
You can adjust the pin numbers and the number of pixels to suit your needs.
The RGB colour data, as well as a brightness level, is sent to the APA102 in a
certain order. Usually this is ``(Red, Green, Blue, Brightness)``.
If you are using one of the newer APA102C LEDs the green and blue are swapped,
so the order is ``(Red, Blue, Green, Brightness)``.
The APA102 has more of a square lens while the APA102C has more of a round one.
If you are using a APA102C strip and would prefer to provide colours in RGB
order instead of RBG, you can customise the tuple colour order like so::
>>> strip.ORDER = (0, 2, 1, 3)
To set the colour of pixels use::
>>> strip[0] = (255, 255, 255, 31) # set to white, full brightness
>>> strip[1] = (255, 0, 0, 31) # set to red, full brightness
>>> strip[2] = (0, 255, 0, 15) # set to green, half brightness
>>> strip[3] = (0, 0, 255, 7) # set to blue, quarter brightness
Use the ``write()`` method to output the colours to the LEDs::
>>> strip.write()
Demonstration::
import time
import machine, apa102
# 1M strip with 60 LEDs
strip = apa102.APA102(machine.Pin(5), machine.Pin(4), 60)
brightness = 1 # 0 is off, 1 is dim, 31 is max
# Helper for converting 0-255 offset to a colour tuple
def wheel(offset, brightness):
# The colours are a transition r - g - b - back to r
offset = 255 - offset
if offset < 85:
return (255 - offset * 3, 0, offset * 3, brightness)
if offset < 170:
offset -= 85
return (0, offset * 3, 255 - offset * 3, brightness)
offset -= 170
return (offset * 3, 255 - offset * 3, 0, brightness)
# Demo 1: RGB RGB RGB
red = 0xff0000
green = red >> 8
blue = red >> 16
for i in range(strip.n):
colour = red >> (i % 3) * 8
strip[i] = ((colour & red) >> 16, (colour & green) >> 8, (colour & blue), brightness)
strip.write()
# Demo 2: Show all colours of the rainbow
for i in range(strip.n):
strip[i] = wheel((i * 256 // strip.n) % 255, brightness)
strip.write()
# Demo 3: Fade all pixels together through rainbow colours, offset each pixel
for r in range(5):
for n in range(256):
for i in range(strip.n):
strip[i] = wheel(((i * 256 // strip.n) + n) & 255, brightness)
strip.write()
time.sleep_ms(25)
# Demo 4: Same colour, different brightness levels
for b in range(31,-1,-1):
strip[0] = (255, 153, 0, b)
strip.write()
time.sleep_ms(250)
# End: Turn off all the LEDs
strip.fill((0, 0, 0, 0))
strip.write()

View File

@ -1,65 +0,0 @@
Temperature and Humidity
========================
DHT (Digital Humidity & Temperature) sensors are low cost digital sensors with
capacitive humidity sensors and thermistors to measure the surrounding air.
They feature a chip that handles analog to digital conversion and provide a
1-wire interface. Newer sensors additionally provide an I2C interface.
The DHT11 (blue) and DHT22 (white) sensors provide the same 1-wire interface,
however, the DHT22 requires a separate object as it has more complex
calculation. DHT22 have 1 decimal place resolution for both humidity and
temperature readings. DHT11 have whole number for both.
A custom 1-wire protocol, which is different to Dallas 1-wire, is used to get
the measurements from the sensor. The payload consists of a humidity value,
a temperature value and a checksum.
To use the 1-wire interface, construct the objects referring to their data pin::
>>> import dht
>>> import machine
>>> d = dht.DHT11(machine.Pin(4))
>>> import dht
>>> import machine
>>> d = dht.DHT22(machine.Pin(4))
Then measure and read their values with::
>>> d.measure()
>>> d.temperature()
>>> d.humidity()
Values returned from ``temperature()`` are in degrees Celsius and values
returned from ``humidity()`` are a percentage of relative humidity.
The DHT11 can be called no more than once per second and the DHT22 once every
two seconds for most accurate results. Sensor accuracy will degrade over time.
Each sensor supports a different operating range. Refer to the product
datasheets for specifics.
In 1-wire mode, only three of the four pins are used and in I2C mode, all four
pins are used. Older sensors may still have 4 pins even though they do not
support I2C. The 3rd pin is simply not connected.
Pin configurations:
Sensor without I2C in 1-wire mode (eg. DHT11, DHT22, AM2301, AM2302):
1=VDD, 2=Data, 3=NC, 4=GND
Sensor with I2C in 1-wire mode (eg. DHT12, AM2320, AM2321, AM2322):
1=VDD, 2=Data, 3=GND, 4=GND
Sensor with I2C in I2C mode (eg. DHT12, AM2320, AM2321, AM2322):
1=VDD, 2=SDA, 3=GND, 4=SCL
You should use pull-up resistors for the Data, SDA and SCL pins.
To make newer I2C sensors work in backwards compatible 1-wire mode, you must
connect both pins 3 and 4 to GND. This disables the I2C interface.
DHT22 sensors are now sold under the name AM2302 and are otherwise identical.

View File

@ -1,69 +0,0 @@
The internal filesystem
=======================
If your devices has 1Mbyte or more of storage then it will be set up (upon first
boot) to contain a filesystem. This filesystem uses the FAT format and is
stored in the flash after the MicroPython firmware.
Creating and reading files
--------------------------
MicroPython on the ESP8266 supports the standard way of accessing files in
Python, using the built-in ``open()`` function.
To create a file try::
>>> f = open('data.txt', 'w')
>>> f.write('some data')
9
>>> f.close()
The "9" is the number of bytes that were written with the ``write()`` method.
Then you can read back the contents of this new file using::
>>> f = open('data.txt')
>>> f.read()
'some data'
>>> f.close()
Note that the default mode when opening a file is to open it in read-only mode,
and as a text file. Specify ``'wb'`` as the second argument to ``open()`` to
open for writing in binary mode, and ``'rb'`` to open for reading in binary
mode.
Listing file and more
---------------------
The os module can be used for further control over the filesystem. First
import the module::
>>> import os
Then try listing the contents of the filesystem::
>>> os.listdir()
['boot.py', 'port_config.py', 'data.txt']
You can make directories::
>>> os.mkdir('dir')
And remove entries::
>>> os.remove('data.txt')
Start up scripts
----------------
There are two files that are treated specially by the ESP8266 when it starts up:
boot.py and main.py. The boot.py script is executed first (if it exists) and
then once it completes the main.py script is executed. You can create these
files yourself and populate them with the code that you want to run when the
device starts up.
Accessing the filesystem via WebREPL
------------------------------------
You can access the filesystem over WebREPL using the web client in a browser
or via the command-line tool. Please refer to Quick Reference and Tutorial
sections for more information about WebREPL.

View File

@ -1,34 +0,0 @@
.. _esp8266_tutorial:
MicroPython tutorial for ESP8266
================================
This tutorial is intended to get you started using MicroPython on the ESP8266
system-on-a-chip. If it is your first time it is recommended to follow the
tutorial through in the order below. Otherwise the sections are mostly self
contained, so feel free to skip to those that interest you.
The tutorial does not assume that you know Python, but it also does not attempt
to explain any of the details of the Python language. Instead it provides you
with commands that are ready to run, and hopes that you will gain a bit of
Python knowledge along the way. To learn more about Python itself please refer
to `<https://www.python.org>`__.
.. toctree::
:maxdepth: 1
:numbered:
intro.rst
repl.rst
filesystem.rst
network_basics.rst
network_tcp.rst
pins.rst
pwm.rst
adc.rst
powerctrl.rst
onewire.rst
neopixel.rst
apa102.rst
dht.rst
nextsteps.rst

View File

@ -1,202 +0,0 @@
.. _intro:
Getting started with MicroPython on the ESP8266
===============================================
Using MicroPython is a great way to get the most of your ESP8266 board. And
vice versa, the ESP8266 chip is a great platform for using MicroPython. This
tutorial will guide you through setting up MicroPython, getting a prompt, using
WebREPL, connecting to the network and communicating with the Internet, using
the hardware peripherals, and controlling some external components.
Let's get started!
Requirements
------------
The first thing you need is a board with an ESP8266 chip. The MicroPython
software supports the ESP8266 chip itself and any board should work. The main
characteristic of a board is how much flash it has, how the GPIO pins are
connected to the outside world, and whether it includes a built-in USB-serial
convertor to make the UART available to your PC.
The minimum requirement for flash size is 1Mbyte. There is also a special
build for boards with 512KB, but it is highly limited comparing to the
normal build: there is no support for filesystem, and thus features which
depend on it won't work (WebREPL, upip, etc.). As such, 512KB build will
be more interesting for users who build from source and fine-tune parameters
for their particular application.
Names of pins will be given in this tutorial using the chip names (eg GPIO0)
and it should be straightforward to find which pin this corresponds to on your
particular board.
Powering the board
------------------
If your board has a USB connector on it then most likely it is powered through
this when connected to your PC. Otherwise you will need to power it directly.
Please refer to the documentation for your board for further details.
Getting the firmware
--------------------
The first thing you need to do is download the most recent MicroPython firmware
.bin file to load onto your ESP8266 device. You can download it from the
`MicroPython downloads page <http://micropython.org/download#esp8266>`_.
From here, you have 3 main choices
* Stable firmware builds for 1024kb modules and above.
* Daily firmware builds for 1024kb modules and above.
* Daily firmware builds for 512kb modules.
If you are just starting with MicroPython, the best bet is to go for the Stable
firmware builds. If you are an advanced, experienced MicroPython ESP8266 user
who would like to follow development closely and help with testing new
features, there are daily builds (note: you actually may need some
development experience, e.g. being ready to follow git history to know
what new changes and features were introduced).
Support for 512kb modules is provided on a feature preview basis. For end
users, it's recommended to use modules with flash of 1024kb or more. As
such, only daily builds for 512kb modules are provided.
Deploying the firmware
----------------------
Once you have the MicroPython firmware (compiled code), you need to load it onto
your ESP8266 device. There are two main steps to do this: first you
need to put your device in boot-loader mode, and second you need to copy across
the firmware. The exact procedure for these steps is highly dependent on the
particular board and you will need to refer to its documentation for details.
If you have a board that has a USB connector, a USB-serial convertor, and has
the DTR and RTS pins wired in a special way then deploying the firmware should
be easy as all steps can be done automatically. Boards that have such features
include the Adafruit Feather HUZZAH and NodeMCU boards.
For best results it is recommended to first erase the entire flash of your
device before putting on new MicroPython firmware.
Currently we only support esptool.py to copy across the firmware. You can find
this tool here: `<https://github.com/espressif/esptool/>`__, or install it
using pip::
pip install esptool
Versions starting with 1.3 support both Python 2.7 and Python 3.4 (or newer).
An older version (at least 1.2.1 is needed) works fine but will require Python
2.7.
Any other flashing program should work, so feel free to try them out or refer
to the documentation for your board to see its recommendations.
Using esptool.py you can erase the flash with the command::
esptool.py --port /dev/ttyUSB0 erase_flash
And then deploy the new firmware using::
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-20170108-v1.8.7.bin
You might need to change the "port" setting to something else relevant for your
PC. You may also need to reduce the baudrate if you get errors when flashing
(eg down to 115200). The filename of the firmware should also match the file
that you have.
For some boards with a particular FlashROM configuration (e.g. some variants of
a NodeMCU board) you may need to use the following command to deploy
the firmware (note the ``-fm dio`` option)::
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-20170108-v1.8.7.bin
If the above commands run without error then MicroPython should be installed on
your board!
Serial prompt
-------------
Once you have the firmware on the device you can access the REPL (Python prompt)
over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial
convertor, depending on your board. The baudrate is 115200. The next part of
the tutorial will discuss the prompt in more detail.
WiFi
----
After a fresh install and boot the device configures itself as a WiFi access
point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx
where the x's are replaced with part of the MAC address of your device (so will
be the same everytime, and most likely different for all ESP8266 chips). The
password for the WiFi is micropythoN (note the upper-case N). Its IP address
will be 192.168.4.1 once you connect to its network. WiFi configuration will
be discussed in more detail later in the tutorial.
Troubleshooting installation problems
-------------------------------------
If you experience problems during flashing or with running firmware immediately
after it, here are troubleshooting recommendations:
* Be aware of and try to exclude hardware problems. There are 2 common problems:
bad power source quality and worn-out/defective FlashROM. Speaking of power
source, not just raw amperage is important, but also low ripple and noise/EMI
in general. If you experience issues with self-made or wall-wart style power
supply, try USB power from a computer. Unearthed power supplies are also known
to cause problems as they source of increased EMI (electromagnetic interference)
- at the very least, and may lead to electrical devices breakdown. So, you are
advised to avoid using unearthed power connections when working with ESP8266
and other boards. In regard to FlashROM hardware problems, there are independent
(not related to MicroPython in any way) reports
`(e.g.) <http://internetofhomethings.com/homethings/?p=538>`_
that on some ESP8266 modules, FlashROM can be programmed as little as 20 times
before programming errors occur. This is *much* less than 100,000 programming
cycles cited for FlashROM chips of a type used with ESP8266 by reputable
vendors, which points to either production rejects, or second-hand worn-out
flash chips to be used on some (apparently cheap) modules/boards. You may want
to use your best judgement about source, price, documentation, warranty,
post-sales support for the modules/boards you purchase.
* The flashing instructions above use flashing speed of 460800 baud, which is
good compromise between speed and stability. However, depending on your
module/board, USB-UART convertor, cables, host OS, etc., the above baud
rate may be too high and lead to errors. Try a more common 115200 baud
rate instead in such cases.
* If lower baud rate didn't help, you may want to try older version of
esptool.py, which had a different programming algorithm::
pip install esptool==1.0.1
This version doesn't support ``--flash_size=detect`` option, so you will
need to specify FlashROM size explicitly (in megabits). It also requires
Python 2.7, so you may need to use ``pip2`` instead of ``pip`` in the
command above.
* The ``--flash_size`` option in the commands above is mandatory. Omitting
it will lead to a corrupted firmware.
* To catch incorrect flash content (e.g. from a defective sector on a chip),
add ``--verify`` switch to the commands above.
* Additionally, you can check the firmware integrity from a MicroPython REPL
prompt (assuming you were able to flash it and ``--verify`` option doesn't
report errors)::
import esp
esp.check_fw()
If the last output value is True, the firmware is OK. Otherwise, it's
corrupted and need to be reflashed correctly.
* If you experience any issues with another flashing application (not
esptool.py), try esptool.py, it is a generally accepted flashing
application in the ESP8266 community.
* If you still experience problems with even flashing the firmware, please
refer to esptool.py project page, https://github.com/espressif/esptool
for additional documentation and bug tracker where you can report problems.
* If you are able to flash firmware, but ``--verify`` option or
``esp.check_fw()`` return errors even after multiple retries, you
may have a defective FlashROM chip, as explained above.

View File

@ -1,84 +0,0 @@
Controlling NeoPixels
=====================
NeoPixels, also known as WS2812 LEDs, are full-colour LEDs that are connected in
serial, are individually addressable, and can have their red, green and blue
components set between 0 and 255. They require precise timing to control them
and there is a special neopixel module to do just this.
To create a NeoPixel object do the following::
>>> import machine, neopixel
>>> np = neopixel.NeoPixel(machine.Pin(4), 8)
This configures a NeoPixel strip on GPIO4 with 8 pixels. You can adjust the
"4" (pin number) and the "8" (number of pixel) to suit your set up.
To set the colour of pixels use::
>>> np[0] = (255, 0, 0) # set to red, full brightness
>>> np[1] = (0, 128, 0) # set to green, half brightness
>>> np[2] = (0, 0, 64) # set to blue, quarter brightness
For LEDs with more than 3 colours, such as RGBW pixels or RGBY pixels, the
NeoPixel class takes a ``bpp`` parameter. To setup a NeoPixel object for an
RGBW Pixel, do the following::
>>> import machine, neopixel
>>> np = neopixel.NeoPixel(machine.Pin(4), 8, bpp=4)
In a 4-bpp mode, remember to use 4-tuples instead of 3-tuples to set the colour.
For example to set the first three pixels use::
>>> np[0] = (255, 0, 0, 128) # Orange in an RGBY Setup
>>> np[1] = (0, 255, 0, 128) # Yellow-green in an RGBY Setup
>>> np[2] = (0, 0, 255, 128) # Green-blue in an RGBY Setup
Then use the ``write()`` method to output the colours to the LEDs::
>>> np.write()
The following demo function makes a fancy show on the LEDs::
import time
def demo(np):
n = np.n
# cycle
for i in range(4 * n):
for j in range(n):
np[j] = (0, 0, 0)
np[i % n] = (255, 255, 255)
np.write()
time.sleep_ms(25)
# bounce
for i in range(4 * n):
for j in range(n):
np[j] = (0, 0, 128)
if (i // n) % 2 == 0:
np[i % n] = (0, 0, 0)
else:
np[n - 1 - (i % n)] = (0, 0, 0)
np.write()
time.sleep_ms(60)
# fade in/out
for i in range(0, 4 * 256, 8):
for j in range(n):
if (i // 256) % 2 == 0:
val = i & 0xff
else:
val = 255 - (i & 0xff)
np[j] = (val, 0, 0)
np.write()
# clear
for i in range(n):
np[i] = (0, 0, 0)
np.write()
Execute it using::
>>> demo(np)

View File

@ -1,81 +0,0 @@
Network basics
==============
The network module is used to configure the WiFi connection. There are two WiFi
interfaces, one for the station (when the ESP8266 connects to a router) and one
for the access point (for other devices to connect to the ESP8266). Create
instances of these objects using::
>>> import network
>>> sta_if = network.WLAN(network.STA_IF)
>>> ap_if = network.WLAN(network.AP_IF)
You can check if the interfaces are active by::
>>> sta_if.active()
False
>>> ap_if.active()
True
You can also check the network settings of the interface by::
>>> ap_if.ifconfig()
('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
The returned values are: IP address, netmask, gateway, DNS.
Configuration of the WiFi
-------------------------
Upon a fresh install the ESP8266 is configured in access point mode, so the
AP_IF interface is active and the STA_IF interface is inactive. You can
configure the module to connect to your own network using the STA_IF interface.
First activate the station interface::
>>> sta_if.active(True)
Then connect to your WiFi network::
>>> sta_if.connect('<your ESSID>', '<your password>')
To check if the connection is established use::
>>> sta_if.isconnected()
Once established you can check the IP address::
>>> sta_if.ifconfig()
('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8')
You can then disable the access-point interface if you no longer need it::
>>> ap_if.active(False)
Here is a function you can run (or put in your boot.py file) to automatically
connect to your WiFi network::
def do_connect():
import network
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect('<essid>', '<password>')
while not sta_if.isconnected():
pass
print('network config:', sta_if.ifconfig())
Sockets
-------
Once the WiFi is set up the way to access the network is by using sockets.
A socket represents an endpoint on a network device, and when two sockets are
connected together communication can proceed.
Internet protocols are built on top of sockets, such as email (SMTP), the web
(HTTP), telnet, ssh, among many others. Each of these protocols is assigned
a specific port, which is just an integer. Given an IP address and a port
number you can connect to a remote device and start talking with it.
The next part of the tutorial discusses how to use sockets to do some common
and useful network tasks.

View File

@ -1,122 +0,0 @@
Network - TCP sockets
=====================
The building block of most of the internet is the TCP socket. These sockets
provide a reliable stream of bytes between the connected network devices.
This part of the tutorial will show how to use TCP sockets in a few different
cases.
Star Wars Asciimation
---------------------
The simplest thing to do is to download data from the internet. In this case
we will use the Star Wars Asciimation service provided by the blinkenlights.nl
website. It uses the telnet protocol on port 23 to stream data to anyone that
connects. It's very simple to use because it doesn't require you to
authenticate (give a username or password), you can just start downloading data
straight away.
The first thing to do is make sure we have the socket module available::
>>> import socket
Then get the IP address of the server::
>>> addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23)
The ``getaddrinfo`` function actually returns a list of addresses, and each
address has more information than we need. We want to get just the first valid
address, and then just the IP address and port of the server. To do this use::
>>> addr = addr_info[0][-1]
If you type ``addr_info`` and ``addr`` at the prompt you will see exactly what
information they hold.
Using the IP address we can make a socket and connect to the server::
>>> s = socket.socket()
>>> s.connect(addr)
Now that we are connected we can download and display the data::
>>> while True:
... data = s.recv(500)
... print(str(data, 'utf8'), end='')
...
When this loop executes it should start showing the animation (use ctrl-C to
interrupt it).
You should also be able to run this same code on your PC using normal Python if
you want to try it out there.
HTTP GET request
----------------
The next example shows how to download a webpage. HTTP uses port 80 and you
first need to send a "GET" request before you can download anything. As part
of the request you need to specify the page to retrieve.
Let's define a function that can download and print a URL::
def http_get(url):
import socket
_, _, host, path = url.split('/', 3)
addr = socket.getaddrinfo(host, 80)[0][-1]
s = socket.socket()
s.connect(addr)
s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
while True:
data = s.recv(100)
if data:
print(str(data, 'utf8'), end='')
else:
break
s.close()
Then you can try::
>>> http_get('http://micropython.org/ks/test.html')
This should retrieve the webpage and print the HTML to the console.
Simple HTTP server
------------------
The following code creates an simple HTTP server which serves a single webpage
that contains a table with the state of all the GPIO pins::
import machine
pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)]
html = """<!DOCTYPE html>
<html>
<head> <title>ESP8266 Pins</title> </head>
<body> <h1>ESP8266 Pins</h1>
<table border="1"> <tr><th>Pin</th><th>Value</th></tr> %s </table>
</body>
</html>
"""
import socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('listening on', addr)
while True:
cl, addr = s.accept()
print('client connected from', addr)
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if not line or line == b'\r\n':
break
rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins]
response = html % '\n'.join(rows)
cl.send(response)
cl.close()

View File

@ -1,12 +0,0 @@
Next steps
==========
That brings us to the end of the tutorial! Hopefully by now you have a good
feel for the capabilities of MicroPython on the ESP8266 and understand how to
control both the WiFi and IO aspects of the chip.
There are many features that were not covered in this tutorial. The best way
to learn about them is to read the full documentation of the modules, and to
experiment!
Good luck creating your Internet of Things devices!

View File

@ -1,37 +0,0 @@
Controlling 1-wire devices
==========================
The 1-wire bus is a serial bus that uses just a single wire for communication
(in addition to wires for ground and power). The DS18B20 temperature sensor
is a very popular 1-wire device, and here we show how to use the onewire module
to read from such a device.
For the following code to work you need to have at least one DS18S20 or DS18B20 temperature
sensor with its data line connected to GPIO12. You must also power the sensors
and connect a 4.7k Ohm resistor between the data pin and the power pin. ::
import time
import machine
import onewire, ds18x20
# the device is on GPIO12
dat = machine.Pin(12)
# create the onewire object
ds = ds18x20.DS18X20(onewire.OneWire(dat))
# scan for devices on the bus
roms = ds.scan()
print('found devices:', roms)
# loop 10 times and print all temperatures
for i in range(10):
print('temperatures:', end=' ')
ds.convert_temp()
time.sleep_ms(750)
for rom in roms:
print(ds.read_temp(rom), end=' ')
print()
Note that you must execute the ``convert_temp()`` function to initiate a
temperature reading, then wait at least 750ms before reading the value.

View File

@ -1,76 +0,0 @@
GPIO Pins
=========
The way to connect your board to the external world, and control other
components, is through the GPIO pins. Not all pins are available to use,
in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used.
The pins are available in the machine module, so make sure you import that
first. Then you can create a pin using::
>>> pin = machine.Pin(0)
Here, the "0" is the pin that you want to access. Usually you want to
configure the pin to be input or output, and you do this when constructing
it. To make an input pin use::
>>> pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
You can either use PULL_UP or None for the input pull-mode. If it's
not specified then it defaults to None, which is no pull resistor. GPIO16
has no pull-up mode.
You can read the value on the pin using::
>>> pin.value()
0
The pin on your board may return 0 or 1 here, depending on what it's connected
to. To make an output pin use::
>>> pin = machine.Pin(0, machine.Pin.OUT)
Then set its value using::
>>> pin.value(0)
>>> pin.value(1)
Or::
>>> pin.off()
>>> pin.on()
External interrupts
-------------------
All pins except number 16 can be configured to trigger a hard interrupt if their
input changes. You can set code (a callback function) to be executed on the
trigger.
Let's first define a callback function, which must take a single argument,
being the pin that triggered the function. We will make the function just print
the pin::
>>> def callback(p):
... print('pin change', p)
Next we will create two pins and configure them as inputs::
>>> from machine import Pin
>>> p0 = Pin(0, Pin.IN)
>>> p2 = Pin(2, Pin.IN)
An finally we need to tell the pins when to trigger, and the function to call
when they detect an event::
>>> p0.irq(trigger=Pin.IRQ_FALLING, handler=callback)
>>> p2.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=callback)
We set pin 0 to trigger only on a falling edge of the input (when it goes from
high to low), and set pin 2 to trigger on both a rising and falling edge. After
entering this code you can apply high and low voltages to pins 0 and 2 to see
the interrupt being executed.
A hard interrupt will trigger as soon as the event occurs and will interrupt any
running code, including Python code. As such your callback functions are
limited in what they can do (they cannot allocate memory, for example) and
should be as short and simple as possible.

View File

@ -1,61 +0,0 @@
Power control
=============
The ESP8266 provides the ability to change the CPU frequency on the fly, and
enter a deep-sleep state. Both can be used to manage power consumption.
Changing the CPU frequency
--------------------------
The machine module has a function to get and set the CPU frequency. To get the
current frequency use::
>>> import machine
>>> machine.freq()
80000000
By default the CPU runs at 80MHz. It can be changed to 160MHz if you need more
processing power, at the expense of current consumption::
>>> machine.freq(160000000)
>>> machine.freq()
160000000
You can change to the higher frequency just while your code does the heavy
processing and then change back when it's finished.
Deep-sleep mode
---------------
The deep-sleep mode will shut down the ESP8266 and all its peripherals,
including the WiFi (but not including the real-time-clock, which is used to wake
the chip). This drastically reduces current consumption and is a good way to
make devices that can run for a while on a battery.
To be able to use the deep-sleep feature you must connect GPIO16 to the reset
pin (RST on the Adafruit Feather HUZZAH board). Then the following code can be
used to sleep and wake the device::
import machine
# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000)
# put the device to sleep
machine.deepsleep()
Note that when the chip wakes from a deep-sleep it is completely reset,
including all of the memory. The boot scripts will run as usual and you can
put code in them to check the reset cause to perhaps do something different if
the device just woke from a deep-sleep. For example, to print the reset cause
you can use::
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
else:
print('power on or hard reset')

View File

@ -1,87 +0,0 @@
Pulse Width Modulation
======================
Pulse width modulation (PWM) is a way to get an artificial analog output on a
digital pin. It achieves this by rapidly toggling the pin from low to high.
There are two parameters associated with this: the frequency of the toggling,
and the duty cycle. The duty cycle is defined to be how long the pin is high
compared with the length of a single period (low plus high time). Maximum
duty cycle is when the pin is high all of the time, and minimum is when it is
low all of the time.
On the ESP8266 the pins 0, 2, 4, 5, 12, 13, 14 and 15 all support PWM. The
limitation is that they must all be at the same frequency, and the frequency
must be between 1Hz and 1kHz.
To use PWM on a pin you must first create the pin object, for example::
>>> import machine
>>> p12 = machine.Pin(12)
Then create the PWM object using::
>>> pwm12 = machine.PWM(p12)
You can set the frequency and duty cycle using::
>>> pwm12.freq(500)
>>> pwm12.duty(512)
Note that the duty cycle is between 0 (all off) and 1023 (all on), with 512
being a 50% duty. Values beyond this min/max will be clipped. If you
print the PWM object then it will tell you its current configuration::
>>> pwm12
PWM(12, freq=500, duty=512)
You can also call the ``freq()`` and ``duty()`` methods with no arguments to
get their current values.
The pin will continue to be in PWM mode until you deinitialise it using::
>>> pwm12.deinit()
Fading an LED
-------------
Let's use the PWM feature to fade an LED. Assuming your board has an LED
connected to pin 2 (ESP-12 modules do) we can create an LED-PWM object using::
>>> led = machine.PWM(machine.Pin(2), freq=1000)
Notice that we can set the frequency in the PWM constructor.
For the next part we will use timing and some math, so import these modules::
>>> import time, math
Then create a function to pulse the LED::
>>> def pulse(l, t):
... for i in range(20):
... l.duty(int(math.sin(i / 10 * math.pi) * 500 + 500))
... time.sleep_ms(t)
You can try this function out using::
>>> pulse(led, 50)
For a nice effect you can pulse many times in a row::
>>> for i in range(10):
... pulse(led, 20)
Remember you can use ctrl-C to interrupt the code.
Control a hobby servo
---------------------
Hobby servo motors can be controlled using PWM. They require a frequency of
50Hz and then a duty between about 40 and 115, with 77 being the centre value.
If you connect a servo to the power and ground pins, and then the signal line
to pin 12 (other pins will work just as well), you can control the motor using::
>>> servo = machine.PWM(machine.Pin(12), freq=50)
>>> servo.duty(40)
>>> servo.duty(115)
>>> servo.duty(77)

View File

@ -1,212 +0,0 @@
Getting a MicroPython REPL prompt
=================================
REPL stands for Read Evaluate Print Loop, and is the name given to the
interactive MicroPython prompt that you can access on the ESP8266. Using the
REPL is by far the easiest way to test out your code and run commands.
There are two ways to access the REPL: either via a wired connection through the
UART serial port, or via WiFi.
REPL over the serial port
-------------------------
The REPL is always available on the UART0 serial peripheral, which is connected
to the pins GPIO1 for TX and GPIO3 for RX. The baudrate of the REPL is 115200.
If your board has a USB-serial convertor on it then you should be able to access
the REPL directly from your PC. Otherwise you will need to have a way of
communicating with the UART.
To access the prompt over USB-serial you need to use a terminal emulator program.
On Windows TeraTerm is a good choice, on Mac you can use the built-in screen
program, and Linux has picocom and minicom. Of course, there are many other
terminal programs that will work, so pick your favourite!
For example, on Linux you can try running::
picocom /dev/ttyUSB0 -b115200
Once you have made the connection over the serial port you can test if it is
working by hitting enter a few times. You should see the Python REPL prompt,
indicated by ``>>>``.
WebREPL - a prompt over WiFi
----------------------------
WebREPL allows you to use the Python prompt over WiFi, connecting through a
browser. The latest versions of Firefox and Chrome are supported.
For your convenience, WebREPL client is hosted at
`<http://micropython.org/webrepl>`__ . Alternatively, you can install it
locally from the the GitHub repository
`<https://github.com/micropython/webrepl>`__ .
Before connecting to WebREPL, you should set a password and enable it via
a normal serial connection. Initial versions of MicroPython for ESP8266
came with WebREPL automatically enabled on the boot and with the
ability to set a password via WiFi on the first connection, but as WebREPL
was becoming more widely known and popular, the initial setup has switched
to a wired connection for improved security::
import webrepl_setup
Follow the on-screen instructions and prompts. To make any changes active,
you will need to reboot your device.
To use WebREPL connect your computer to the ESP8266's access point
(MicroPython-xxxxxx, see the previous section about this). If you have
already reconfigured your ESP8266 to connect to a router then you can
skip this part.
Once you are on the same network as the ESP8266 you click the "Connect" button
(if you are connecting via a router then you may need to change the IP address,
by default the IP address is correct when connected to the ESP8266's access
point). If the connection succeeds then you should see a password prompt.
Once you type the password configured at the setup step above, press Enter once
more and you should get a prompt looking like ``>>>``. You can now start
typing Python commands!
Using the REPL
--------------
Once you have a prompt you can start experimenting! Anything you type at the
prompt will be executed after you press the Enter key. MicroPython will run
the code that you enter and print the result (if there is one). If there is an
error with the text that you enter then an error message is printed.
Try typing the following at the prompt::
>>> print('hello esp8266!')
hello esp8266!
Note that you shouldn't type the ``>>>`` arrows, they are there to indicate that
you should type the text after it at the prompt. And then the line following is
what the device should respond with. In the end, once you have entered the text
``print("hello esp8266!")`` and pressed the Enter key, the output on your screen
should look exactly like it does above.
If you already know some python you can now try some basic commands here. For
example::
>>> 1 + 2
3
>>> 1 / 2
0.5
>>> 12**34
4922235242952026704037113243122008064
If your board has an LED attached to GPIO2 (the ESP-12 modules do) then you can
turn it on and off using the following code::
>>> import machine
>>> pin = machine.Pin(2, machine.Pin.OUT)
>>> pin.on()
>>> pin.off()
Note that ``on`` method of a Pin might turn the LED off and ``off`` might
turn it on (or vice versa), depending on how the LED is wired on your board.
To resolve this, machine.Signal class is provided.
Line editing
~~~~~~~~~~~~
You can edit the current line that you are entering using the left and right
arrow keys to move the cursor, as well as the delete and backspace keys. Also,
pressing Home or ctrl-A moves the cursor to the start of the line, and pressing
End or ctrl-E moves to the end of the line.
Input history
~~~~~~~~~~~~~
The REPL remembers a certain number of previous lines of text that you entered
(up to 8 on the ESP8266). To recall previous lines use the up and down arrow
keys.
Tab completion
~~~~~~~~~~~~~~
Pressing the Tab key will do an auto-completion of the current word that you are
entering. This can be very useful to find out functions and methods that a
module or object has. Try it out by typing "ma" and then pressing Tab. It
should complete to "machine" (assuming you imported machine in the above
example). Then type "." and press Tab again to see a list of all the functions
that the machine module has.
Line continuation and auto-indent
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Certain things that you type will need "continuing", that is, will need more
lines of text to make a proper Python statement. In this case the prompt will
change to ``...`` and the cursor will auto-indent the correct amount so you can
start typing the next line straight away. Try this by defining the following
function::
>>> def toggle(p):
... p.value(not p.value())
...
...
...
>>>
In the above, you needed to press the Enter key three times in a row to finish
the compound statement (that's the three lines with just dots on them). The
other way to finish a compound statement is to press backspace to get to the
start of the line, then press the Enter key. (If you did something wrong and
want to escape the continuation mode then press ctrl-C; all lines will be
ignored.)
The function you just defined allows you to toggle a pin. The pin object you
created earlier should still exist (recreate it if it doesn't) and you can
toggle the LED using::
>>> toggle(pin)
Let's now toggle the LED in a loop (if you don't have an LED then you can just
print some text instead of calling toggle, to see the effect)::
>>> import time
>>> while True:
... toggle(pin)
... time.sleep_ms(500)
...
...
...
>>>
This will toggle the LED at 1Hz (half a second on, half a second off). To stop
the toggling press ctrl-C, which will raise a KeyboardInterrupt exception and
break out of the loop.
The time module provides some useful functions for making delays and doing
timing. Use tab completion to find out what they are and play around with them!
Paste mode
~~~~~~~~~~
Pressing ctrl-E will enter a special paste mode. This allows you to copy and
paste a chunk of text into the REPL. If you press ctrl-E you will see the
paste-mode prompt::
paste mode; Ctrl-C to cancel, Ctrl-D to finish
===
You can then paste (or type) your text in. Note that none of the special keys
or commands work in paste mode (eg Tab or backspace), they are just accepted
as-is. Press ctrl-D to finish entering the text and execute it.
Other control commands
~~~~~~~~~~~~~~~~~~~~~~
There are four other control commands:
* Ctrl-A on a blank line will enter raw REPL mode. This is like a permanent
paste mode, except that characters are not echoed back.
* Ctrl-B on a blank like goes to normal REPL mode.
* Ctrl-C cancels any input, or interrupts the currently running code.
* Ctrl-D on a blank line will do a soft reset.
Note that ctrl-A and ctrl-D do not work with WebREPL.

62
docs/general.rst 100644
View File

@ -0,0 +1,62 @@
General information about the pyboard
=====================================
Local filesystem and SD card
----------------------------
There is a small internal filesystem (a drive) on the pyboard, called ``/flash``,
which is stored within the microcontroller's flash memory. If a micro SD card
is inserted into the slot, it is available as ``/sd``.
When the pyboard boots up, it needs to choose a filesystem to boot from. If
there is no SD card, then it uses the internal filesystem ``/flash`` as the boot
filesystem, otherwise, it uses the SD card ``/sd``.
(Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd``
is called ``1:/``).
The boot filesystem is used for 2 things: it is the filesystem from which
the ``boot.py`` and ``main.py`` files are searched for, and it is the filesystem
which is made available on your PC over the USB cable.
The filesystem will be available as a USB flash drive on your PC. You can
save files to the drive, and edit ``boot.py`` and ``main.py``.
*Remember to eject (on Linux, unmount) the USB drive before you reset your
pyboard.*
Boot modes
----------
If you power up normally, or press the reset button, the pyboard will boot
into standard mode: the ``boot.py`` file will be executed first, then the
USB will be configured, then ``main.py`` will run.
You can override this boot sequence by holding down the user switch as
the board is booting up. Hold down user switch and press reset, and then
as you continue to hold the user switch, the LEDs will count in binary.
When the LEDs have reached the mode you want, let go of the user switch,
the LEDs for the selected mode will flash quickly, and the board will boot.
The modes are:
1. Green LED only, *standard boot*: run ``boot.py`` then ``main.py``.
2. Orange LED only, *safe boot*: don't run any scripts on boot-up.
3. Green and orange LED together, *filesystem reset*: resets the flash
filesystem to its factory state, then boots in safe mode.
If your filesystem becomes corrupt, boot into mode 3 to fix it.
If resetting the filesystem while plugged into your compute doesn't work,
you can try doing the same procedure while the board is plugged into a USB
charger, or other USB power supply without data connection.
Errors: flashing LEDs
---------------------
There are currently 2 kinds of errors that you might see:
1. If the red and green LEDs flash alternatively, then a Python script
(eg ``main.py``) has an error. Use the REPL to debug it.
2. If all 4 LEDs cycle on and off slowly, then there was a hard fault.
This cannot be recovered from and you need to do a hard reset.

View File

@ -0,0 +1,29 @@
.. _hardware_index:
The pyboard hardware
====================
For the pyboard:
* `PYBv1.0 schematics and layout <http://micropython.org/resources/PYBv10b.pdf>`_ (2.4MiB PDF)
* `PYBv1.0 metric dimensions <http://micropython.org/resources/PYBv10b-metric-dimensions.pdf>`_ (360KiB PDF)
* `PYBv1.0 imperial dimensions <http://micropython.org/resources/PYBv10b-imperial-dimensions.pdf>`_ (360KiB PDF)
For the official skin modules:
* `LCD32MKv1.0 schematics <http://micropython.org/resources/LCD32MKv10-schematics.pdf>`_ (194KiB PDF)
* `AMPv1.0 schematics <http://micropython.org/resources/AMPv10-schematics.pdf>`_ (209KiB PDF)
Datasheets for the components on the pyboard
============================================
* The microcontroller: `STM32F405RGT6 <http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144>`_ (link to manufacturer's site)
* The accelerometer: `Freescale MMA7660 <http://micropython.org/resources/datasheets/MMA7660FC.pdf>`_ (800kiB PDF)
* The LDO voltage regulator: `Microchip MCP1802 <http://micropython.org/resources/datasheets/MCP1802-22053C.pdf>`_ (400kiB PDF)
Datasheets for other components
===============================
* The LCD display on the LCD touch-sensor skin: `Newhaven Display NHD-C12832A1Z-FSW-FBW-3V3 <http://micropython.org/resources/datasheets/NHD-C12832A1Z-FSW-FBW-3V3.pdf>`_ (460KiB PDF)
* The touch sensor chip on the LCD touch-sensor skin: `Freescale MPR121 <http://micropython.org/resources/datasheets/MPR121.pdf>`_ (280KiB PDF)
* The digital potentiometer on the audio skin: `Microchip MCP4541 <http://micropython.org/resources/datasheets/MCP4541-22107B.pdf>`_ (2.7MiB PDF)

View File

@ -1,14 +1,19 @@
MicroPython documentation and references
========================================
Micro Python documentation and references
=========================================
.. toctree::
library/index.rst
reference/index.rst
genrst/index.rst
develop/index.rst
license.rst
pyboard/quickref.rst
esp8266/quickref.rst
esp32/quickref.rst
wipy/quickref.rst
quickref.rst
general.rst
tutorial/index.rst
library/index.rst
hardware/index.rst
license.rst
contents.rst
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -1,12 +0,0 @@
:mod:`_thread` -- multithreading support
========================================
.. module:: _thread
:synopsis: multithreading support
|see_cpython_module| :mod:`python:_thread`.
This module implements multithreading support.
This module is highly experimental and its API is not yet fully settled
and not yet described in this documentation.

View File

@ -1,159 +0,0 @@
:mod:`btree` -- simple BTree database
=====================================
.. module:: btree
:synopsis: simple BTree database
The ``btree`` module implements a simple key-value database using external
storage (disk files, or in general case, a random-access `stream`). Keys are
stored sorted in the database, and besides efficient retrieval by a key
value, a database also supports efficient ordered range scans (retrieval
of values with the keys in a given range). On the application interface
side, BTree database work as close a possible to a way standard `dict`
type works, one notable difference is that both keys and values must
be `bytes` objects (so, if you want to store objects of other types, you
need to serialize them to `bytes` first).
The module is based on the well-known BerkelyDB library, version 1.xx.
Example::
import btree
# First, we need to open a stream which holds a database
# This is usually a file, but can be in-memory database
# using uio.BytesIO, a raw flash partition, etc.
# Oftentimes, you want to create a database file if it doesn't
# exist and open if it exists. Idiom below takes care of this.
# DO NOT open database with "a+b" access mode.
try:
f = open("mydb", "r+b")
except OSError:
f = open("mydb", "w+b")
# Now open a database itself
db = btree.open(f)
# The keys you add will be sorted internally in the database
db[b"3"] = b"three"
db[b"1"] = b"one"
db[b"2"] = b"two"
# Assume that any changes are cached in memory unless
# explicitly flushed (or database closed). Flush database
# at the end of each "transaction".
db.flush()
# Prints b'two'
print(db[b"2"])
# Iterate over sorted keys in the database, starting from b"2"
# until the end of the database, returning only values.
# Mind that arguments passed to values() method are *key* values.
# Prints:
# b'two'
# b'three'
for word in db.values(b"2"):
print(word)
del db[b"2"]
# No longer true, prints False
print(b"2" in db)
# Prints:
# b"1"
# b"3"
for key in db:
print(key)
db.close()
# Don't forget to close the underlying stream!
f.close()
Functions
---------
.. function:: open(stream, \*, flags=0, pagesize=0, cachesize=0, minkeypage=0)
Open a database from a random-access `stream` (like an open file). All
other parameters are optional and keyword-only, and allow to tweak advanced
parameters of the database operation (most users will not need them):
* *flags* - Currently unused.
* *pagesize* - Page size used for the nodes in BTree. Acceptable range
is 512-65536. If 0, a port-specific default will be used, optimized for
port's memory usage and/or performance.
* *cachesize* - Suggested memory cache size in bytes. For a
board with enough memory using larger values may improve performance.
Cache policy is as follows: entire cache is not allocated at once;
instead, accessing a new page in database will allocate a memory buffer
for it, until value specified by *cachesize* is reached. Then, these
buffers will be managed using LRU (least recently used) policy. More
buffers may still be allocated if needed (e.g., if a database contains
big keys and/or values). Allocated cache buffers aren't reclaimed.
* *minkeypage* - Minimum number of keys to store per page. Default value
of 0 equivalent to 2.
Returns a BTree object, which implements a dictionary protocol (set
of methods), and some additional methods described below.
Methods
-------
.. method:: btree.close()
Close the database. It's mandatory to close the database at the end of
processing, as some unwritten data may be still in the cache. Note that
this does not close underlying stream with which the database was opened,
it should be closed separately (which is also mandatory to make sure that
data flushed from buffer to the underlying storage).
.. method:: btree.flush()
Flush any data in cache to the underlying stream.
.. method:: btree.__getitem__(key)
btree.get(key, default=None)
btree.__setitem__(key, val)
btree.__detitem__(key)
btree.__contains__(key)
Standard dictionary methods.
.. method:: btree.__iter__()
A BTree object can be iterated over directly (similar to a dictionary)
to get access to all keys in order.
.. method:: btree.keys([start_key, [end_key, [flags]]])
btree.values([start_key, [end_key, [flags]]])
btree.items([start_key, [end_key, [flags]]])
These methods are similar to standard dictionary methods, but also can
take optional parameters to iterate over a key sub-range, instead of
the entire database. Note that for all 3 methods, *start_key* and
*end_key* arguments represent key values. For example, `values()`
method will iterate over values corresponding to they key range
given. None values for *start_key* means "from the first key", no
*end_key* or its value of None means "until the end of database".
By default, range is inclusive of *start_key* and exclusive of
*end_key*, you can include *end_key* in iteration by passing *flags*
of `btree.INCL`. You can iterate in descending key direction
by passing *flags* of `btree.DESC`. The flags values can be ORed
together.
Constants
---------
.. data:: INCL
A flag for `keys()`, `values()`, `items()` methods to specify that
scanning should be inclusive of the end key.
.. data:: DESC
A flag for `keys()`, `values()`, `items()` methods to specify that
scanning should be in descending direction of keys.

View File

@ -1,199 +0,0 @@
Builtin functions and exceptions
================================
All builtin functions and exceptions are described here. They are also
available via ``builtins`` module.
Functions and types
-------------------
.. function:: abs()
.. function:: all()
.. function:: any()
.. function:: bin()
.. class:: bool()
.. class:: bytearray()
.. class:: bytes()
|see_cpython| `python:bytes`.
.. function:: callable()
.. function:: chr()
.. function:: classmethod()
.. function:: compile()
.. class:: complex()
.. function:: delattr(obj, name)
The argument *name* should be a string, and this function deletes the named
attribute from the object given by *obj*.
.. class:: dict()
.. function:: dir()
.. function:: divmod()
.. function:: enumerate()
.. function:: eval()
.. function:: exec()
.. function:: filter()
.. class:: float()
.. class:: frozenset()
.. function:: getattr()
.. function:: globals()
.. function:: hasattr()
.. function:: hash()
.. function:: hex()
.. function:: id()
.. function:: input()
.. class:: int()
.. classmethod:: from_bytes(bytes, byteorder)
In MicroPython, `byteorder` parameter must be positional (this is
compatible with CPython).
.. method:: to_bytes(size, byteorder)
In MicroPython, `byteorder` parameter must be positional (this is
compatible with CPython).
.. function:: isinstance()
.. function:: issubclass()
.. function:: iter()
.. function:: len()
.. class:: list()
.. function:: locals()
.. function:: map()
.. function:: max()
.. class:: memoryview()
.. function:: min()
.. function:: next()
.. class:: object()
.. function:: oct()
.. function:: open()
.. function:: ord()
.. function:: pow()
.. function:: print()
.. function:: property()
.. function:: range()
.. function:: repr()
.. function:: reversed()
.. function:: round()
.. class:: set()
.. function:: setattr()
.. class:: slice()
The *slice* builtin is the type that slice objects have.
.. function:: sorted()
.. function:: staticmethod()
.. class:: str()
.. function:: sum()
.. function:: super()
.. class:: tuple()
.. function:: type()
.. function:: zip()
Exceptions
----------
.. exception:: AssertionError
.. exception:: AttributeError
.. exception:: Exception
.. exception:: ImportError
.. exception:: IndexError
.. exception:: KeyboardInterrupt
.. exception:: KeyError
.. exception:: MemoryError
.. exception:: NameError
.. exception:: NotImplementedError
.. exception:: OSError
|see_cpython| `python:OSError`. MicroPython doesn't implement ``errno``
attribute, instead use the standard way to access exception arguments:
``exc.args[0]``.
.. exception:: RuntimeError
.. exception:: StopIteration
.. exception:: SyntaxError
.. exception:: SystemExit
|see_cpython| `python:SystemExit`.
.. exception:: TypeError
|see_cpython| `python:TypeError`.
.. exception:: ValueError
.. exception:: ZeroDivisionError

View File

@ -4,14 +4,9 @@
.. module:: cmath
:synopsis: mathematical functions for complex numbers
|see_cpython_module| :mod:`python:cmath`.
The ``cmath`` module provides some basic mathematical functions for
The ``cmath`` module provides some basic mathematical funtions for
working with complex numbers.
Availability: not available on WiPy and ESP8266. Floating point support
required for this module.
Functions
---------

View File

@ -1,101 +0,0 @@
:mod:`esp` --- functions related to the ESP8266 and ESP32
=========================================================
.. module:: esp
:synopsis: functions related to the ESP8266 and ESP32
The ``esp`` module contains specific functions related to both the ESP8266 and
ESP32 modules. Some functions are only available on one or the other of these
ports.
Functions
---------
.. function:: sleep_type([sleep_type])
**Note**: ESP8266 only
Get or set the sleep type.
If the *sleep_type* parameter is provided, sets the sleep type to its
value. If the function is called without parameters, returns the current
sleep type.
The possible sleep types are defined as constants:
* ``SLEEP_NONE`` -- all functions enabled,
* ``SLEEP_MODEM`` -- modem sleep, shuts down the WiFi Modem circuit.
* ``SLEEP_LIGHT`` -- light sleep, shuts down the WiFi Modem circuit
and suspends the processor periodically.
The system enters the set sleep mode automatically when possible.
.. function:: deepsleep(time=0)
**Note**: ESP8266 only - use `machine.deepsleep()` on ESP32
Enter deep sleep.
The whole module powers down, except for the RTC clock circuit, which can
be used to restart the module after the specified time if the pin 16 is
connected to the reset pin. Otherwise the module will sleep until manually
reset.
.. function:: flash_id()
**Note**: ESP8266 only
Read the device ID of the flash memory.
.. function:: flash_size()
Read the total size of the flash memory.
.. function:: flash_user_start()
Read the memory offset at which the user flash space begins.
.. function:: flash_read(byte_offset, length_or_buffer)
.. function:: flash_write(byte_offset, bytes)
.. function:: flash_erase(sector_no)
.. function:: set_native_code_location(start, length)
**Note**: ESP8266 only
Set the location that native code will be placed for execution after it is
compiled. Native code is emitted when the ``@micropython.native``,
``@micropython.viper`` and ``@micropython.asm_xtensa`` decorators are applied
to a function. The ESP8266 must execute code from either iRAM or the lower
1MByte of flash (which is memory mapped), and this function controls the
location.
If *start* and *length* are both ``None`` then the native code location is
set to the unused portion of memory at the end of the iRAM1 region. The
size of this unused portion depends on the firmware and is typically quite
small (around 500 bytes), and is enough to store a few very small
functions. The advantage of using this iRAM1 region is that it does not
get worn out by writing to it.
If neither *start* nor *length* are ``None`` then they should be integers.
*start* should specify the byte offset from the beginning of the flash at
which native code should be stored. *length* specifies how many bytes of
flash from *start* can be used to store native code. *start* and *length*
should be multiples of the sector size (being 4096 bytes). The flash will
be automatically erased before writing to it so be sure to use a region of
flash that is not otherwise used, for example by the firmware or the
filesystem.
When using the flash to store native code *start+length* must be less
than or equal to 1MByte. Note that the flash can be worn out if repeated
erasures (and writes) are made so use this feature sparingly.
In particular, native code needs to be recompiled and rewritten to flash
on each boot (including wake from deepsleep).
In both cases above, using iRAM1 or flash, if there is no more room left
in the specified region then the use of a native decorator on a function
will lead to `MemoryError` exception being raised during compilation of
that function.

View File

@ -1,202 +0,0 @@
.. currentmodule:: esp32
:mod:`esp32` --- functionality specific to the ESP32
====================================================
.. module:: esp32
:synopsis: functionality specific to the ESP32
The ``esp32`` module contains functions and classes specifically aimed at
controlling ESP32 modules.
Functions
---------
.. function:: wake_on_touch(wake)
Configure whether or not a touch will wake the device from sleep.
*wake* should be a boolean value.
.. function:: wake_on_ext0(pin, level)
Configure how EXT0 wakes the device from sleep. *pin* can be ``None``
or a valid Pin object. *level* should be ``esp32.WAKEUP_ALL_LOW`` or
``esp32.WAKEUP_ANY_HIGH``.
.. function:: wake_on_ext1(pins, level)
Configure how EXT1 wakes the device from sleep. *pins* can be ``None``
or a tuple/list of valid Pin objects. *level* should be ``esp32.WAKEUP_ALL_LOW``
or ``esp32.WAKEUP_ANY_HIGH``.
.. function:: raw_temperature()
Read the raw value of the internal temperature sensor, returning an integer.
.. function:: hall_sensor()
Read the raw value of the internal Hall sensor, returning an integer.
Flash partitions
----------------
This class gives access to the partitions in the device's flash memory.
.. class:: Partition(id)
Create an object representing a partition. *id* can be a string which is the label
of the partition to retrieve, or one of the constants: ``BOOT`` or ``RUNNING``.
.. classmethod:: Partition.find(type=TYPE_APP, subtype=0xff, label=None)
Find a partition specified by *type*, *subtype* and *label*. Returns a
(possibly empty) list of Partition objects.
.. method:: Partition.info()
Returns a 6-tuple ``(type, subtype, addr, size, label, encrypted)``.
.. method:: Partition.readblocks(block_num, buf)
.. method:: Partition.readblocks(block_num, buf, offset)
.. method:: Partition.writeblocks(block_num, buf)
.. method:: Partition.writeblocks(block_num, buf, offset)
.. method:: Partition.ioctl(cmd, arg)
These methods implement the simple and :ref:`extended
<block-device-interface>` block protocol defined by
:class:`uos.AbstractBlockDev`.
.. method:: Partition.set_boot()
Sets the partition as the boot partition.
.. method:: Partition.get_next_update()
Gets the next update partition after this one, and returns a new Partition object.
Constants
~~~~~~~~~
.. data:: Partition.BOOT
Partition.RUNNING
Used in the `Partition` constructor to fetch various partitions.
.. data:: Partition.TYPE_APP
Partition.TYPE_DATA
Used in `Partition.find` to specify the partition type.
.. _esp32.RMT:
RMT
---
The RMT (Remote Control) module, specific to the ESP32, was originally designed
to send and receive infrared remote control signals. However, due to a flexible
design and very accurate (as low as 12.5ns) pulse generation, it can also be
used to transmit or receive many other types of digital signals::
import esp32
from machine import Pin
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
# The channel resolution is 100ns (1/(source_freq/clock_div)).
r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
The input to the RMT module is an 80MHz clock (in the future it may be able to
configure the input clock but, for now, it's fixed). ``clock_div`` *divides*
the clock input which determines the resolution of the RMT channel. The
numbers specificed in ``write_pulses`` are multiplied by the resolution to
define the pulses.
``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by
multiplying the resolution by a 15-bit (0-32,768) number. There are eight
channels (0-7) and each can have a different clock divider.
So, in the example above, the 80MHz clock is divided by 8. Thus the
resolution is (1/(80Mhz/8)) 100ns. Since the ``start`` level is 0 and toggles
with each number, the bitstream is ``0101`` with durations of [100ns, 2000ns,
100ns, 4000ns].
For more details see Espressif's `ESP-IDF RMT documentation.
<https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/rmt.html>`_.
.. Warning::
The current MicroPython RMT implementation lacks some features, most notably
receiving pulses and carrier transmit. RMT should be considered a
*beta feature* and the interface may change in the future.
.. class:: RMT(channel, \*, pin=None, clock_div=8)
This class provides access to one of the eight RMT channels. *channel* is
required and identifies which RMT channel (0-7) will be configured. *pin*,
also required, configures which Pin is bound to the RMT channel. *clock_div*
is an 8-bit clock divider that divides the source clock (80MHz) to the RMT
channel allowing the resolution to be specified.
.. method:: RMT.source_freq()
Returns the source clock frequency. Currently the source clock is not
configurable so this will always return 80MHz.
.. method:: RMT.clock_div()
Return the clock divider. Note that the channel resolution is
``1 / (source_freq / clock_div)``.
.. method:: RMT.wait_done(timeout=0)
Returns True if `RMT.write_pulses` has completed.
If *timeout* (defined in ticks of ``source_freq / clock_div``) is specified
the method will wait for *timeout* or until `RMT.write_pulses` is complete,
returning ``False`` if the channel continues to transmit.
.. Warning::
Avoid using ``wait_done()`` if looping is enabled.
.. method:: RMT.loop(enable_loop)
Configure looping on the channel, allowing a stream of pulses to be
indefinitely repeated. *enable_loop* is bool, set to True to enable looping.
.. method:: RMT.write_pulses(pulses, start)
Begin sending *pulses*, a list or tuple defining the stream of pulses. The
length of each pulse is defined by a number to be multiplied by the channel
resolution ``(1 / (source_freq / clock_div))``. *start* defines whether the
stream starts at 0 or 1.
The Ultra-Low-Power co-processor
--------------------------------
.. class:: ULP()
This class provides access to the Ultra-Low-Power co-processor.
.. method:: ULP.set_wakeup_period(period_index, period_us)
Set the wake-up period.
.. method:: ULP.load_binary(load_addr, program_binary)
Load a *program_binary* into the ULP at the given *load_addr*.
.. method:: ULP.run(entry_point)
Start the ULP running at the given *entry_point*.
Constants
---------
.. data:: esp32.WAKEUP_ALL_LOW
esp32.WAKEUP_ANY_HIGH
Selects the wake level for pins.

View File

@ -1,161 +0,0 @@
:mod:`framebuf` --- Frame buffer manipulation
=============================================
.. module:: framebuf
:synopsis: Frame buffer manipulation
This module provides a general frame buffer which can be used to create
bitmap images, which can then be sent to a display.
class FrameBuffer
-----------------
The FrameBuffer class provides a pixel buffer which can be drawn upon with
pixels, lines, rectangles, text and even other FrameBuffer's. It is useful
when generating output for displays.
For example::
import framebuf
# FrameBuffer needs 2 bytes for every RGB565 pixel
fbuf = framebuf.FrameBuffer(bytearray(10 * 100 * 2), 10, 100, framebuf.RGB565)
fbuf.fill(0)
fbuf.text('MicroPython!', 0, 0, 0xffff)
fbuf.hline(0, 10, 96, 0xffff)
Constructors
------------
.. class:: FrameBuffer(buffer, width, height, format, stride=width)
Construct a FrameBuffer object. The parameters are:
- *buffer* is an object with a buffer protocol which must be large
enough to contain every pixel defined by the width, height and
format of the FrameBuffer.
- *width* is the width of the FrameBuffer in pixels
- *height* is the height of the FrameBuffer in pixels
- *format* specifies the type of pixel used in the FrameBuffer;
permissible values are listed under Constants below. These set the
number of bits used to encode a color value and the layout of these
bits in *buffer*.
Where a color value c is passed to a method, c is a small integer
with an encoding that is dependent on the format of the FrameBuffer.
- *stride* is the number of pixels between each horizontal line
of pixels in the FrameBuffer. This defaults to *width* but may
need adjustments when implementing a FrameBuffer within another
larger FrameBuffer or screen. The *buffer* size must accommodate
an increased step size.
One must specify valid *buffer*, *width*, *height*, *format* and
optionally *stride*. Invalid *buffer* size or dimensions may lead to
unexpected errors.
Drawing primitive shapes
------------------------
The following methods draw shapes onto the FrameBuffer.
.. method:: FrameBuffer.fill(c)
Fill the entire FrameBuffer with the specified color.
.. method:: FrameBuffer.pixel(x, y[, c])
If *c* is not given, get the color value of the specified pixel.
If *c* is given, set the specified pixel to the given color.
.. method:: FrameBuffer.hline(x, y, w, c)
.. method:: FrameBuffer.vline(x, y, h, c)
.. method:: FrameBuffer.line(x1, y1, x2, y2, c)
Draw a line from a set of coordinates using the given color and
a thickness of 1 pixel. The `line` method draws the line up to
a second set of coordinates whereas the `hline` and `vline`
methods draw horizontal and vertical lines respectively up to
a given length.
.. method:: FrameBuffer.rect(x, y, w, h, c)
.. method:: FrameBuffer.fill_rect(x, y, w, h, c)
Draw a rectangle at the given location, size and color. The `rect`
method draws only a 1 pixel outline whereas the `fill_rect` method
draws both the outline and interior.
Drawing text
------------
.. method:: FrameBuffer.text(s, x, y[, c])
Write text to the FrameBuffer using the the coordinates as the upper-left
corner of the text. The color of the text can be defined by the optional
argument but is otherwise a default value of 1. All characters have
dimensions of 8x8 pixels and there is currently no way to change the font.
Other methods
-------------
.. method:: FrameBuffer.scroll(xstep, ystep)
Shift the contents of the FrameBuffer by the given vector. This may
leave a footprint of the previous colors in the FrameBuffer.
.. method:: FrameBuffer.blit(fbuf, x, y[, key])
Draw another FrameBuffer on top of the current one at the given coordinates.
If *key* is specified then it should be a color integer and the
corresponding color will be considered transparent: all pixels with that
color value will not be drawn.
This method works between FrameBuffer instances utilising different formats,
but the resulting colors may be unexpected due to the mismatch in color
formats.
Constants
---------
.. data:: framebuf.MONO_VLSB
Monochrome (1-bit) color format
This defines a mapping where the bits in a byte are vertically mapped with
bit 0 being nearest the top of the screen. Consequently each byte occupies
8 vertical pixels. Subsequent bytes appear at successive horizontal
locations until the rightmost edge is reached. Further bytes are rendered
at locations starting at the leftmost edge, 8 pixels lower.
.. data:: framebuf.MONO_HLSB
Monochrome (1-bit) color format
This defines a mapping where the bits in a byte are horizontally mapped.
Each byte occupies 8 horizontal pixels with bit 0 being the leftmost.
Subsequent bytes appear at successive horizontal locations until the
rightmost edge is reached. Further bytes are rendered on the next row, one
pixel lower.
.. data:: framebuf.MONO_HMSB
Monochrome (1-bit) color format
This defines a mapping where the bits in a byte are horizontally mapped.
Each byte occupies 8 horizontal pixels with bit 7 being the leftmost.
Subsequent bytes appear at successive horizontal locations until the
rightmost edge is reached. Further bytes are rendered on the next row, one
pixel lower.
.. data:: framebuf.RGB565
Red Green Blue (16-bit, 5+6+5) color format
.. data:: framebuf.GS2_HMSB
Grayscale (2-bit) color format
.. data:: framebuf.GS4_HMSB
Grayscale (4-bit) color format
.. data:: framebuf.GS8
Grayscale (8-bit) color format

View File

@ -4,8 +4,6 @@
.. module:: gc
:synopsis: control the garbage collector
|see_cpython_module| :mod:`python:gc`.
Functions
---------
@ -26,41 +24,6 @@ Functions
Return the number of bytes of heap RAM that are allocated.
.. admonition:: Difference to CPython
:class: attention
This function is MicroPython extension.
.. function:: mem_free()
Return the number of bytes of available heap RAM, or -1 if this amount
is not known.
.. admonition:: Difference to CPython
:class: attention
This function is MicroPython extension.
.. function:: threshold([amount])
Set or query the additional GC allocation threshold. Normally, a collection
is triggered only when a new allocation cannot be satisfied, i.e. on an
out-of-memory (OOM) condition. If this function is called, in addition to
OOM, a collection will be triggered each time after *amount* bytes have been
allocated (in total, since the previous time such an amount of bytes
have been allocated). *amount* is usually specified as less than the
full heap size, with the intention to trigger a collection earlier than when the
heap becomes exhausted, and in the hope that an early collection will prevent
excessive memory fragmentation. This is a heuristic measure, the effect
of which will vary from application to application, as well as
the optimal value of the *amount* parameter.
Calling the function without argument will return the current value of
the threshold. A value of -1 means a disabled allocation threshold.
.. admonition:: Difference to CPython
:class: attention
This function is a MicroPython extension. CPython has a similar
function - ``set_threshold()``, but due to different GC
implementations, its signature and semantics are different.
Return the number of bytes of available heap RAM.

View File

@ -1,133 +1,50 @@
.. _micropython_lib:
Micro Python libraries
======================
MicroPython libraries
=====================
Python standard libraries
-------------------------
.. warning::
The following standard Python libraries are built in to Micro Python.
Important summary of this section
For additional libraries, please download them from the `micropython-lib repository
<https://github.com/micropython/micropython-lib>`_.
* MicroPython implements a subset of Python functionality for each module.
* To ease extensibility, MicroPython versions of standard Python modules
usually have ``u`` ("micro") prefix.
* Any particular MicroPython variant or port may miss any feature/function
described in this general documentation (due to resource constraints or
other limitations).
.. toctree::
:maxdepth: 1
cmath.rst
gc.rst
math.rst
os.rst
select.rst
struct.rst
sys.rst
time.rst
This chapter describes modules (function and class libraries) which are built
into MicroPython. There are a few categories of such modules:
* Modules which implement a subset of standard Python functionality and are not
intended to be extended by the user.
* Modules which implement a subset of Python functionality, with a provision
for extension by the user (via Python code).
* Modules which implement MicroPython extensions to the Python standard libraries.
* Modules specific to a particular `MicroPython port` and thus not portable.
Note about the availability of the modules and their contents: This documentation
in general aspires to describe all modules and functions/classes which are
implemented in MicroPython project. However, MicroPython is highly configurable, and
each port to a particular board/embedded system makes available only a subset
of MicroPython libraries. For officially supported ports, there is an effort
to either filter out non-applicable items, or mark individual descriptions
with "Availability:" clauses describing which ports provide a given feature.
With that in mind, please still be warned that some functions/classes
in a module (or even the entire module) described in this documentation **may be
unavailable** in a particular build of MicroPython on a particular system. The
best place to find general information of the availability/non-availability
of a particular feature is the "General Information" section which contains
information pertaining to a specific `MicroPython port`.
On some ports you are able to discover the available, built-in libraries that
can be imported by entering the following at the REPL::
help('modules')
Beyond the built-in libraries described in this documentation, many more
modules from the Python standard library, as well as further MicroPython
extensions to it, can be found in `micropython-lib`.
Python standard libraries and micro-libraries
---------------------------------------------
Python micro-libraries
----------------------
The following standard Python libraries have been "micro-ified" to fit in with
the philosophy of MicroPython. They provide the core functionality of that
the philosophy of Micro Python. They provide the core functionality of that
module and are intended to be a drop-in replacement for the standard Python
library. Some modules below use a standard Python name, but prefixed with "u",
e.g. ``ujson`` instead of ``json``. This is to signify that such a module is
micro-library, i.e. implements only a subset of CPython module functionality.
By naming them differently, a user has a choice to write a Python-level module
to extend functionality for better compatibility with CPython (indeed, this is
what done by the `micropython-lib` project mentioned above).
library.
On some embedded platforms, where it may be cumbersome to add Python-level
wrapper modules to achieve naming compatibility with CPython, micro-modules
are available both by their u-name, and also by their non-u-name. The
non-u-name can be overridden by a file of that name in your library path (``sys.path``).
For example, ``import json`` will first search for a file ``json.py`` (or package
directory ``json``) and load that module if it is found. If nothing is found,
The modules are available by their u-name, and also by their non-u-name. The
non-u-name can be overridden by a file of that name in your package path.
For example, ``import json`` will first search for a file ``json.py`` or
directory ``json`` and load that package if it is found. If nothing is found,
it will fallback to loading the built-in ``ujson`` module.
.. toctree::
:maxdepth: 1
builtins.rst
cmath.rst
gc.rst
math.rst
sys.rst
uarray.rst
ubinascii.rst
ucollections.rst
uerrno.rst
uhashlib.rst
uheapq.rst
uio.rst
ujson.rst
uos.rst
ure.rst
uselect.rst
usocket.rst
ussl.rst
ustruct.rst
utime.rst
uzlib.rst
_thread.rst
MicroPython-specific libraries
------------------------------
Functionality specific to the MicroPython implementation is available in
the following libraries.
.. toctree::
:maxdepth: 1
btree.rst
framebuf.rst
machine.rst
micropython.rst
network.rst
ubluetooth.rst
ucryptolib.rst
uctypes.rst
Port-specific libraries
-----------------------
In some cases the following port/board-specific libraries have functions or
classes similar to those in the :mod:`machine` library. Where this occurs, the
entry in the port specific library exposes hardware functionality unique to
that platform.
To write portable code use functions and classes from the :mod:`machine` module.
To access platform-specific hardware use the appropriate library, e.g.
:mod:`pyb` in the case of the Pyboard.
Libraries specific to the pyboard
---------------------------------
@ -135,32 +52,7 @@ Libraries specific to the pyboard
The following libraries are specific to the pyboard.
.. toctree::
:maxdepth: 2
:maxdepth: 2
pyb.rst
lcd160cr.rst
Libraries specific to the WiPy
------------------------------
The following libraries and classes are specific to the WiPy.
.. toctree::
:maxdepth: 2
wipy.rst
machine.ADCWiPy.rst
machine.TimerWiPy.rst
Libraries specific to the ESP8266 and ESP32
-------------------------------------------
The following libraries are specific to the ESP8266 and ESP32.
.. toctree::
:maxdepth: 2
esp.rst
esp32.rst
pyb.rst
network.rst

View File

@ -1,394 +0,0 @@
:mod:`lcd160cr` --- control of LCD160CR display
===============================================
.. module:: lcd160cr
:synopsis: control of LCD160CR display
This module provides control of the MicroPython LCD160CR display.
.. image:: http://micropython.org/resources/LCD160CRv10-persp.jpg
:alt: LCD160CRv1.0 picture
:width: 640px
Further resources are available via the following links:
* `LCD160CRv1.0 reference manual <http://micropython.org/resources/LCD160CRv10-refmanual.pdf>`_ (100KiB PDF)
* `LCD160CRv1.0 schematics <http://micropython.org/resources/LCD160CRv10-schematics.pdf>`_ (1.6MiB PDF)
class LCD160CR
--------------
The LCD160CR class provides an interface to the display. Create an
instance of this class and use its methods to draw to the LCD and get
the status of the touch panel.
For example::
import lcd160cr
lcd = lcd160cr.LCD160CR('X')
lcd.set_orient(lcd160cr.PORTRAIT)
lcd.set_pos(0, 0)
lcd.set_text_color(lcd.rgb(255, 0, 0), lcd.rgb(0, 0, 0))
lcd.set_font(1)
lcd.write('Hello MicroPython!')
print('touch:', lcd.get_touch())
Constructors
------------
.. class:: LCD160CR(connect=None, \*, pwr=None, i2c=None, spi=None, i2c_addr=98)
Construct an LCD160CR object. The parameters are:
- *connect* is a string specifying the physical connection of the LCD
display to the board; valid values are "X", "Y", "XY", "YX".
Use "X" when the display is connected to a pyboard in the X-skin
position, and "Y" when connected in the Y-skin position. "XY"
and "YX" are used when the display is connected to the right or
left side of the pyboard, respectively.
- *pwr* is a Pin object connected to the LCD's power/enabled pin.
- *i2c* is an I2C object connected to the LCD's I2C interface.
- *spi* is an SPI object connected to the LCD's SPI interface.
- *i2c_addr* is the I2C address of the display.
One must specify either a valid *connect* or all of *pwr*, *i2c* and *spi*.
If a valid *connect* is given then any of *pwr*, *i2c* or *spi* which are
not passed as parameters (i.e. they are ``None``) will be created based on the
value of *connect*. This allows to override the default interface to the
display if needed.
The default values are:
- "X" is for the X-skin and uses:
``pwr=Pin("X4")``, ``i2c=I2C("X")``, ``spi=SPI("X")``
- "Y" is for the Y-skin and uses:
``pwr=Pin("Y4")``, ``i2c=I2C("Y")``, ``spi=SPI("Y")``
- "XY" is for the right-side and uses:
``pwr=Pin("X4")``, ``i2c=I2C("Y")``, ``spi=SPI("X")``
- "YX" is for the left-side and uses:
``pwr=Pin("Y4")``, ``i2c=I2C("X")``, ``spi=SPI("Y")``
See `this image <http://micropython.org/resources/LCD160CRv10-positions.jpg>`_
for how the display can be connected to the pyboard.
Static methods
--------------
.. staticmethod:: LCD160CR.rgb(r, g, b)
Return a 16-bit integer representing the given rgb color values. The
16-bit value can be used to set the font color (see
:meth:`LCD160CR.set_text_color`) pen color (see :meth:`LCD160CR.set_pen`)
and draw individual pixels.
.. staticmethod:: LCD160CR.clip_line(data, w, h):
Clip the given line data. This is for internal use.
Instance members
----------------
The following instance members are publicly accessible.
.. data:: LCD160CR.w
.. data:: LCD160CR.h
The width and height of the display, respectively, in pixels. These
members are updated when calling :meth:`LCD160CR.set_orient` and should
be considered read-only.
Setup commands
--------------
.. method:: LCD160CR.set_power(on)
Turn the display on or off, depending on the given value of *on*: 0 or ``False``
will turn the display off, and 1 or ``True`` will turn it on.
.. method:: LCD160CR.set_orient(orient)
Set the orientation of the display. The *orient* parameter can be one
of `PORTRAIT`, `LANDSCAPE`, `PORTRAIT_UPSIDEDOWN`, `LANDSCAPE_UPSIDEDOWN`.
.. method:: LCD160CR.set_brightness(value)
Set the brightness of the display, between 0 and 31.
.. method:: LCD160CR.set_i2c_addr(addr)
Set the I2C address of the display. The *addr* value must have the
lower 2 bits cleared.
.. method:: LCD160CR.set_uart_baudrate(baudrate)
Set the baudrate of the UART interface.
.. method:: LCD160CR.set_startup_deco(value)
Set the start-up decoration of the display. The *value* parameter can be a
logical or of `STARTUP_DECO_NONE`, `STARTUP_DECO_MLOGO`, `STARTUP_DECO_INFO`.
.. method:: LCD160CR.save_to_flash()
Save the following parameters to flash so they persist on restart and power up:
initial decoration, orientation, brightness, UART baud rate, I2C address.
Pixel access methods
--------------------
The following methods manipulate individual pixels on the display.
.. method:: LCD160CR.set_pixel(x, y, c)
Set the specified pixel to the given color. The color should be a 16-bit
integer and can be created by :meth:`LCD160CR.rgb`.
.. method:: LCD160CR.get_pixel(x, y)
Get the 16-bit value of the specified pixel.
.. method:: LCD160CR.get_line(x, y, buf)
Low-level method to get a line of pixels into the given buffer.
To read *n* pixels *buf* should be *2*n+1* bytes in length. The first byte
is a dummy byte and should be ignored, and subsequent bytes represent the
pixels in the line starting at coordinate *(x, y)*.
.. method:: LCD160CR.screen_dump(buf, x=0, y=0, w=None, h=None)
Dump the contents of the screen to the given buffer. The parameters *x* and *y*
specify the starting coordinate, and *w* and *h* the size of the region. If *w*
or *h* are ``None`` then they will take on their maximum values, set by the size
of the screen minus the given *x* and *y* values. *buf* should be large enough
to hold ``2*w*h`` bytes. If it's smaller then only the initial horizontal lines
will be stored.
.. method:: LCD160CR.screen_load(buf)
Load the entire screen from the given buffer.
Drawing text
------------
To draw text one sets the position, color and font, and then uses
`LCD160CR.write` to draw the text.
.. method:: LCD160CR.set_pos(x, y)
Set the position for text output using :meth:`LCD160CR.write`. The position
is the upper-left corner of the text.
.. method:: LCD160CR.set_text_color(fg, bg)
Set the foreground and background color of the text.
.. method:: LCD160CR.set_font(font, scale=0, bold=0, trans=0, scroll=0)
Set the font for the text. Subsequent calls to `write` will use the newly
configured font. The parameters are:
- *font* is the font family to use, valid values are 0, 1, 2, 3.
- *scale* is a scaling value for each character pixel, where the pixels
are drawn as a square with side length equal to *scale + 1*. The value
can be between 0 and 63.
- *bold* controls the number of pixels to overdraw each character pixel,
making a bold effect. The lower 2 bits of *bold* are the number of
pixels to overdraw in the horizontal direction, and the next 2 bits are
for the vertical direction. For example, a *bold* value of 5 will
overdraw 1 pixel in both the horizontal and vertical directions.
- *trans* can be either 0 or 1 and if set to 1 the characters will be
drawn with a transparent background.
- *scroll* can be either 0 or 1 and if set to 1 the display will do a
soft scroll if the text moves to the next line.
.. method:: LCD160CR.write(s)
Write text to the display, using the current position, color and font.
As text is written the position is automatically incremented. The
display supports basic VT100 control codes such as newline and backspace.
Drawing primitive shapes
------------------------
Primitive drawing commands use a foreground and background color set by the
`set_pen` method.
.. method:: LCD160CR.set_pen(line, fill)
Set the line and fill color for primitive shapes.
.. method:: LCD160CR.erase()
Erase the entire display to the pen fill color.
.. method:: LCD160CR.dot(x, y)
Draw a single pixel at the given location using the pen line color.
.. method:: LCD160CR.rect(x, y, w, h)
.. method:: LCD160CR.rect_outline(x, y, w, h)
.. method:: LCD160CR.rect_interior(x, y, w, h)
Draw a rectangle at the given location and size using the pen line
color for the outline, and the pen fill color for the interior.
The `rect` method draws the outline and interior, while the other methods
just draw one or the other.
.. method:: LCD160CR.line(x1, y1, x2, y2)
Draw a line between the given coordinates using the pen line color.
.. method:: LCD160CR.dot_no_clip(x, y)
.. method:: LCD160CR.rect_no_clip(x, y, w, h)
.. method:: LCD160CR.rect_outline_no_clip(x, y, w, h)
.. method:: LCD160CR.rect_interior_no_clip(x, y, w, h)
.. method:: LCD160CR.line_no_clip(x1, y1, x2, y2)
These methods are as above but don't do any clipping on the input
coordinates. They are faster than the clipping versions and can be
used when you know that the coordinates are within the display.
.. method:: LCD160CR.poly_dot(data)
Draw a sequence of dots using the pen line color.
The *data* should be a buffer of bytes, with each successive pair of
bytes corresponding to coordinate pairs (x, y).
.. method:: LCD160CR.poly_line(data)
Similar to :meth:`LCD160CR.poly_dot` but draws lines between the dots.
Touch screen methods
--------------------
.. method:: LCD160CR.touch_config(calib=False, save=False, irq=None)
Configure the touch panel:
- If *calib* is ``True`` then the call will trigger a touch calibration of
the resistive touch sensor. This requires the user to touch various
parts of the screen.
- If *save* is ``True`` then the touch parameters will be saved to NVRAM
to persist across reset/power up.
- If *irq* is ``True`` then the display will be configured to pull the IRQ
line low when a touch force is detected. If *irq* is ``False`` then this
feature is disabled. If *irq* is ``None`` (the default value) then no
change is made to this setting.
.. method:: LCD160CR.is_touched()
Returns a boolean: ``True`` if there is currently a touch force on the screen,
``False`` otherwise.
.. method:: LCD160CR.get_touch()
Returns a 3-tuple of: *(active, x, y)*. If there is currently a touch force
on the screen then *active* is 1, otherwise it is 0. The *x* and *y* values
indicate the position of the current or most recent touch.
Advanced commands
-----------------
.. method:: LCD160CR.set_spi_win(x, y, w, h)
Set the window that SPI data is written to.
.. method:: LCD160CR.fast_spi(flush=True)
Ready the display to accept RGB pixel data on the SPI bus, resetting the location
of the first byte to go to the top-left corner of the window set by
:meth:`LCD160CR.set_spi_win`.
The method returns an SPI object which can be used to write the pixel data.
Pixels should be sent as 16-bit RGB values in the 5-6-5 format. The destination
counter will increase as data is sent, and data can be sent in arbitrary sized
chunks. Once the destination counter reaches the end of the window specified by
:meth:`LCD160CR.set_spi_win` it will wrap around to the top-left corner of that window.
.. method:: LCD160CR.show_framebuf(buf)
Show the given buffer on the display. *buf* should be an array of bytes containing
the 16-bit RGB values for the pixels, and they will be written to the area
specified by :meth:`LCD160CR.set_spi_win`, starting from the top-left corner.
The `framebuf <framebuf.html>`_ module can be used to construct frame buffers
and provides drawing primitives. Using a frame buffer will improve
performance of animations when compared to drawing directly to the screen.
.. method:: LCD160CR.set_scroll(on)
Turn scrolling on or off. This controls globally whether any window regions will
scroll.
.. method:: LCD160CR.set_scroll_win(win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0)
Configure a window region for scrolling:
- *win* is the window id to configure. There are 0..7 standard windows for
general purpose use. Window 8 is the text scroll window (the ticker).
- *x*, *y*, *w*, *h* specify the location of the window in the display.
- *vec* specifies the direction and speed of scroll: it is a 16-bit value
of the form ``0bF.ddSSSSSSSSSSSS``. *dd* is 0, 1, 2, 3 for +x, +y, -x,
-y scrolling. *F* sets the speed format, with 0 meaning that the window
is shifted *S % 256* pixel every frame, and 1 meaning that the window
is shifted 1 pixel every *S* frames.
- *pat* is a 16-bit pattern mask for the background.
- *fill* is the fill color.
- *color* is the extra color, either of the text or pattern foreground.
.. method:: LCD160CR.set_scroll_win_param(win, param, value)
Set a single parameter of a scrolling window region:
- *win* is the window id, 0..8.
- *param* is the parameter number to configure, 0..7, and corresponds
to the parameters in the `set_scroll_win` method.
- *value* is the value to set.
.. method:: LCD160CR.set_scroll_buf(s)
Set the string for scrolling in window 8. The parameter *s* must be a string
with length 32 or less.
.. method:: LCD160CR.jpeg(buf)
Display a JPEG. *buf* should contain the entire JPEG data. JPEG data should
not include EXIF information. The following encodings are supported: Baseline
DCT, Huffman coding, 8 bits per sample, 3 color components, YCbCr4:2:2.
The origin of the JPEG is set by :meth:`LCD160CR.set_pos`.
.. method:: LCD160CR.jpeg_start(total_len)
.. method:: LCD160CR.jpeg_data(buf)
Display a JPEG with the data split across multiple buffers. There must be
a single call to `jpeg_start` to begin with, specifying the total number of
bytes in the JPEG. Then this number of bytes must be transferred to the
display using one or more calls to the `jpeg_data` command.
.. method:: LCD160CR.feed_wdt()
The first call to this method will start the display's internal watchdog
timer. Subsequent calls will feed the watchdog. The timeout is roughly 30
seconds.
.. method:: LCD160CR.reset()
Reset the display.
Constants
---------
.. data:: lcd160cr.PORTRAIT
lcd160cr.LANDSCAPE
lcd160cr.PORTRAIT_UPSIDEDOWN
lcd160cr.LANDSCAPE_UPSIDEDOWN
Orientations of the display, used by :meth:`LCD160CR.set_orient`.
.. data:: lcd160cr.STARTUP_DECO_NONE
lcd160cr.STARTUP_DECO_MLOGO
lcd160cr.STARTUP_DECO_INFO
Types of start-up decoration, can be OR'ed together, used by
:meth:`LCD160CR.set_startup_deco`.

View File

@ -1,35 +0,0 @@
.. currentmodule:: machine
.. _machine.ADC:
class ADC -- analog to digital conversion
=========================================
The ADC class provides an interface to analog-to-digital convertors, and
represents a single endpoint that can sample a continuous voltage and
convert it to a discretised value.
Example usage::
import machine
adc = machine.ADC(pin) # create an ADC object acting on a pin
val = adc.read_u16() # read a raw analog value in the range 0-65535
Constructors
------------
.. class:: ADC(id)
Access the ADC associated with a source identified by *id*. This
*id* may be an integer (usually specifying a channel number), a
:ref:`Pin <machine.Pin>` object, or other value supported by the
underlying machine.
Methods
-------
.. method:: ADC.read_u16()
Take an analog reading and return an integer in the range 0-65535.
The return value represents the raw reading taken by the ADC, scaled
such that the minimum value is 0 and the maximum value is 65535.

View File

@ -1,81 +0,0 @@
.. currentmodule:: machine
.. _machine.ADCWiPy:
class ADCWiPy -- analog to digital conversion
=============================================
.. note::
This class is a non-standard ADC implementation for the WiPy.
It is available simply as ``machine.ADC`` on the WiPy but is named in the
documentation below as ``machine.ADCWiPy`` to distinguish it from the
more general :ref:`machine.ADC <machine.ADC>` class.
Usage::
import machine
adc = machine.ADC() # create an ADC object
apin = adc.channel(pin='GP3') # create an analog pin on GP3
val = apin() # read an analog value
Constructors
------------
.. class:: ADCWiPy(id=0, \*, bits=12)
Create an ADC object associated with the given pin.
This allows you to then read analog values on that pin.
For more info check the `pinout and alternate functions
table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_
.. warning::
ADC pin input range is 0-1.4V (being 1.8V the absolute maximum that it
can withstand). When GP2, GP3, GP4 or GP5 are remapped to the
ADC block, 1.8 V is the maximum. If these pins are used in digital mode,
then the maximum allowed input is 3.6V.
Methods
-------
.. method:: ADCWiPy.channel(id, \*, pin)
Create an analog pin. If only channel ID is given, the correct pin will
be selected. Alternatively, only the pin can be passed and the correct
channel will be selected. Examples::
# all of these are equivalent and enable ADC channel 1 on GP3
apin = adc.channel(1)
apin = adc.channel(pin='GP3')
apin = adc.channel(id=1, pin='GP3')
.. method:: ADCWiPy.init()
Enable the ADC block.
.. method:: ADCWiPy.deinit()
Disable the ADC block.
class ADCChannel --- read analog values from internal or external sources
=========================================================================
ADC channels can be connected to internal points of the MCU or to GPIO pins.
ADC channels are created using the ADC.channel method.
.. method:: adcchannel()
Fast method to read the channel value.
.. method:: adcchannel.value()
Read the channel value.
.. method:: adcchannel.init()
Re-init (and effectively enable) the ADC channel.
.. method:: adcchannel.deinit()
Disable the ADC channel.

View File

@ -1,180 +0,0 @@
.. currentmodule:: machine
.. _machine.I2C:
class I2C -- a two-wire serial protocol
=======================================
I2C is a two-wire protocol for communicating between devices. At the physical
level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
I2C objects are created attached to a specific bus. They can be initialised
when created, or initialised later on.
Printing the I2C object gives you information about its configuration.
Example usage::
from machine import I2C
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
# depending on the port, extra parameters may be required
# to select the peripheral and/or pins to use
i2c.scan() # scan for slaves, returning a list of 7-bit addresses
i2c.writeto(42, b'123') # write 3 bytes to slave with 7-bit address 42
i2c.readfrom(42, 4) # read 4 bytes from slave with 7-bit address 42
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of slave 42,
# starting at memory-address 8 in the slave
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42
# starting at address 2 in the slave
Constructors
------------
.. class:: I2C(id=-1, \*, scl, sda, freq=400000)
Construct and return a new I2C object using the following parameters:
- *id* identifies a particular I2C peripheral. The default
value of -1 selects a software implementation of I2C which can
work (in most cases) with arbitrary pins for SCL and SDA.
If *id* is -1 then *scl* and *sda* must be specified. Other
allowed values for *id* depend on the particular port/board,
and specifying *scl* and *sda* may or may not be required or
allowed in this case.
- *scl* should be a pin object specifying the pin to use for SCL.
- *sda* should be a pin object specifying the pin to use for SDA.
- *freq* should be an integer which sets the maximum frequency
for SCL.
General Methods
---------------
.. method:: I2C.init(scl, sda, \*, freq=400000)
Initialise the I2C bus with the given arguments:
- *scl* is a pin object for the SCL line
- *sda* is a pin object for the SDA line
- *freq* is the SCL clock rate
.. method:: I2C.deinit()
Turn off the I2C bus.
Availability: WiPy.
.. method:: I2C.scan()
Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of
those that respond. A device responds if it pulls the SDA line low after
its address (including a write bit) is sent on the bus.
Primitive I2C operations
------------------------
The following methods implement the primitive I2C master bus operations and can
be combined to make any I2C transaction. They are provided if you need more
control over the bus, otherwise the standard methods (see below) can be used.
These methods are available on software I2C only.
.. method:: I2C.start()
Generate a START condition on the bus (SDA transitions to low while SCL is high).
.. method:: I2C.stop()
Generate a STOP condition on the bus (SDA transitions to high while SCL is high).
.. method:: I2C.readinto(buf, nack=True)
Reads bytes from the bus and stores them into *buf*. The number of bytes
read is the length of *buf*. An ACK will be sent on the bus after
receiving all but the last byte. After the last byte is received, if *nack*
is true then a NACK will be sent, otherwise an ACK will be sent (and in this
case the slave assumes more bytes are going to be read in a later call).
.. method:: I2C.write(buf)
Write the bytes from *buf* to the bus. Checks that an ACK is received
after each byte and stops transmitting the remaining bytes if a NACK is
received. The function returns the number of ACKs that were received.
Standard bus operations
-----------------------
The following methods implement the standard I2C master read and write
operations that target a given slave device.
.. method:: I2C.readfrom(addr, nbytes, stop=True)
Read *nbytes* from the slave specified by *addr*.
If *stop* is true then a STOP condition is generated at the end of the transfer.
Returns a `bytes` object with the data read.
.. method:: I2C.readfrom_into(addr, buf, stop=True)
Read into *buf* from the slave specified by *addr*.
The number of bytes read will be the length of *buf*.
If *stop* is true then a STOP condition is generated at the end of the transfer.
The method returns ``None``.
.. method:: I2C.writeto(addr, buf, stop=True)
Write the bytes from *buf* to the slave specified by *addr*. If a
NACK is received following the write of a byte from *buf* then the
remaining bytes are not sent. If *stop* is true then a STOP condition is
generated at the end of the transfer, even if a NACK is received.
The function returns the number of ACKs that were received.
.. method:: I2C.writevto(addr, vector, stop=True)
Write the bytes contained in *vector* to the slave specified by *addr*.
*vector* should be a tuple or list of objects with the buffer protocol.
The *addr* is sent once and then the bytes from each object in *vector*
are written out sequentially. The objects in *vector* may be zero bytes
in length in which case they don't contribute to the output.
If a NACK is received following the write of a byte from one of the
objects in *vector* then the remaining bytes, and any remaining objects,
are not sent. If *stop* is true then a STOP condition is generated at
the end of the transfer, even if a NACK is received. The function
returns the number of ACKs that were received.
Memory operations
-----------------
Some I2C devices act as a memory device (or set of registers) that can be read
from and written to. In this case there are two addresses associated with an
I2C transaction: the slave address and the memory address. The following
methods are convenience functions to communicate with such devices.
.. method:: I2C.readfrom_mem(addr, memaddr, nbytes, \*, addrsize=8)
Read *nbytes* from the slave specified by *addr* starting from the memory
address specified by *memaddr*.
The argument *addrsize* specifies the address size in bits.
Returns a `bytes` object with the data read.
.. method:: I2C.readfrom_mem_into(addr, memaddr, buf, \*, addrsize=8)
Read into *buf* from the slave specified by *addr* starting from the
memory address specified by *memaddr*. The number of bytes read is the
length of *buf*.
The argument *addrsize* specifies the address size in bits (on ESP8266
this argument is not recognised and the address size is always 8 bits).
The method returns ``None``.
.. method:: I2C.writeto_mem(addr, memaddr, buf, \*, addrsize=8)
Write *buf* to the slave specified by *addr* starting from the
memory address specified by *memaddr*.
The argument *addrsize* specifies the address size in bits (on ESP8266
this argument is not recognised and the address size is always 8 bits).
The method returns ``None``.

View File

@ -1,254 +0,0 @@
.. currentmodule:: machine
.. _machine.Pin:
class Pin -- control I/O pins
=============================
A pin object is used to control I/O pins (also known as GPIO - general-purpose
input/output). Pin objects are commonly associated with a physical pin that can
drive an output voltage and read input voltages. The pin class has methods to set the mode of
the pin (IN, OUT, etc) and methods to get and set the digital logic level.
For analog control of a pin, see the :class:`ADC` class.
A pin object is constructed by using an identifier which unambiguously
specifies a certain I/O pin. The allowed forms of the identifier and the
physical pin that the identifier maps to are port-specific. Possibilities
for the identifier are an integer, a string or a tuple with port and pin
number.
Usage Model::
from machine import Pin
# create an output pin on pin #0
p0 = Pin(0, Pin.OUT)
# set the value low then high
p0.value(0)
p0.value(1)
# create an input pin on pin #2, with a pull up resistor
p2 = Pin(2, Pin.IN, Pin.PULL_UP)
# read and print the pin value
print(p2.value())
# reconfigure pin #0 in input mode
p0.mode(p0.IN)
# configure an irq callback
p0.irq(lambda p:print(p))
Constructors
------------
.. class:: Pin(id, mode=-1, pull=-1, \*, value, drive, alt)
Access the pin peripheral (GPIO pin) associated with the given ``id``. If
additional arguments are given in the constructor then they are used to initialise
the pin. Any settings that are not specified will remain in their previous state.
The arguments are:
- ``id`` is mandatory and can be an arbitrary object. Among possible value
types are: int (an internal Pin identifier), str (a Pin name), and tuple
(pair of [port, pin]).
- ``mode`` specifies the pin mode, which can be one of:
- ``Pin.IN`` - Pin is configured for input. If viewed as an output the pin
is in high-impedance state.
- ``Pin.OUT`` - Pin is configured for (normal) output.
- ``Pin.OPEN_DRAIN`` - Pin is configured for open-drain output. Open-drain
output works in the following way: if the output value is set to 0 the pin
is active at a low level; if the output value is 1 the pin is in a high-impedance
state. Not all ports implement this mode, or some might only on certain pins.
- ``Pin.ALT`` - Pin is configured to perform an alternative function, which is
port specific. For a pin configured in such a way any other Pin methods
(except :meth:`Pin.init`) are not applicable (calling them will lead to undefined,
or a hardware-specific, result). Not all ports implement this mode.
- ``Pin.ALT_OPEN_DRAIN`` - The Same as ``Pin.ALT``, but the pin is configured as
open-drain. Not all ports implement this mode.
- ``pull`` specifies if the pin has a (weak) pull resistor attached, and can be
one of:
- ``None`` - No pull up or down resistor.
- ``Pin.PULL_UP`` - Pull up resistor enabled.
- ``Pin.PULL_DOWN`` - Pull down resistor enabled.
- ``value`` is valid only for Pin.OUT and Pin.OPEN_DRAIN modes and specifies initial
output pin value if given, otherwise the state of the pin peripheral remains
unchanged.
- ``drive`` specifies the output power of the pin and can be one of: ``Pin.LOW_POWER``,
``Pin.MED_POWER`` or ``Pin.HIGH_POWER``. The actual current driving capabilities
are port dependent. Not all ports implement this argument.
- ``alt`` specifies an alternate function for the pin and the values it can take are
port dependent. This argument is valid only for ``Pin.ALT`` and ``Pin.ALT_OPEN_DRAIN``
modes. It may be used when a pin supports more than one alternate function. If only
one pin alternate function is supported the this argument is not required. Not all
ports implement this argument.
As specified above, the Pin class allows to set an alternate function for a particular
pin, but it does not specify any further operations on such a pin. Pins configured in
alternate-function mode are usually not used as GPIO but are instead driven by other
hardware peripherals. The only operation supported on such a pin is re-initialising,
by calling the constructor or :meth:`Pin.init` method. If a pin that is configured in
alternate-function mode is re-initialised with ``Pin.IN``, ``Pin.OUT``, or
``Pin.OPEN_DRAIN``, the alternate function will be removed from the pin.
Methods
-------
.. method:: Pin.init(mode=-1, pull=-1, \*, value, drive, alt)
Re-initialise the pin using the given parameters. Only those arguments that
are specified will be set. The rest of the pin peripheral state will remain
unchanged. See the constructor documentation for details of the arguments.
Returns ``None``.
.. method:: Pin.value([x])
This method allows to set and get the value of the pin, depending on whether
the argument ``x`` is supplied or not.
If the argument is omitted then this method gets the digital logic level of
the pin, returning 0 or 1 corresponding to low and high voltage signals
respectively. The behaviour of this method depends on the mode of the pin:
- ``Pin.IN`` - The method returns the actual input value currently present
on the pin.
- ``Pin.OUT`` - The behaviour and return value of the method is undefined.
- ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and
return value of the method is undefined. Otherwise, if the pin is in
state '1', the method returns the actual input value currently present
on the pin.
If the argument is supplied then this method sets the digital logic level of
the pin. The argument ``x`` can be anything that converts to a boolean.
If it converts to ``True``, the pin is set to state '1', otherwise it is set
to state '0'. The behaviour of this method depends on the mode of the pin:
- ``Pin.IN`` - The value is stored in the output buffer for the pin. The
pin state does not change, it remains in the high-impedance state. The
stored value will become active on the pin as soon as it is changed to
``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode.
- ``Pin.OUT`` - The output buffer is set to the given value immediately.
- ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage
state. Otherwise the pin is set to high-impedance state.
When setting the value this method returns ``None``.
.. method:: Pin.__call__([x])
Pin objects are callable. The call method provides a (fast) shortcut to set
and get the value of the pin. It is equivalent to Pin.value([x]).
See :meth:`Pin.value` for more details.
.. method:: Pin.on()
Set pin to "1" output level.
.. method:: Pin.off()
Set pin to "0" output level.
.. method:: Pin.mode([mode])
Get or set the pin mode.
See the constructor documentation for details of the ``mode`` argument.
.. method:: Pin.pull([pull])
Get or set the pin pull state.
See the constructor documentation for details of the ``pull`` argument.
.. method:: Pin.drive([drive])
Get or set the pin drive strength.
See the constructor documentation for details of the ``drive`` argument.
Not all ports implement this method.
Availability: WiPy.
.. method:: Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), \*, priority=1, wake=None, hard=False)
Configure an interrupt handler to be called when the trigger source of the
pin is active. If the pin mode is ``Pin.IN`` then the trigger source is
the external value on the pin. If the pin mode is ``Pin.OUT`` then the
trigger source is the output buffer of the pin. Otherwise, if the pin mode
is ``Pin.OPEN_DRAIN`` then the trigger source is the output buffer for
state '0' and the external pin value for state '1'.
The arguments are:
- ``handler`` is an optional function to be called when the interrupt
triggers. The handler must take exactly one argument which is the
``Pin`` instance.
- ``trigger`` configures the event which can generate an interrupt.
Possible values are:
- ``Pin.IRQ_FALLING`` interrupt on falling edge.
- ``Pin.IRQ_RISING`` interrupt on rising edge.
- ``Pin.IRQ_LOW_LEVEL`` interrupt on low level.
- ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level.
These values can be OR'ed together to trigger on multiple events.
- ``priority`` sets the priority level of the interrupt. The values it
can take are port-specific, but higher values always represent higher
priorities.
- ``wake`` selects the power mode in which this interrupt can wake up the
system. It can be ``machine.IDLE``, ``machine.SLEEP`` or ``machine.DEEPSLEEP``.
These values can also be OR'ed together to make a pin generate interrupts in
more than one power mode.
- ``hard`` if true a hardware interrupt is used. This reduces the delay
between the pin change and the handler being called. Hard interrupt
handlers may not allocate memory; see :ref:`isr_rules`.
This method returns a callback object.
Constants
---------
The following constants are used to configure the pin objects. Note that
not all constants are available on all ports.
.. data:: Pin.IN
Pin.OUT
Pin.OPEN_DRAIN
Pin.ALT
Pin.ALT_OPEN_DRAIN
Selects the pin mode.
.. data:: Pin.PULL_UP
Pin.PULL_DOWN
Pin.PULL_HOLD
Selects whether there is a pull up/down resistor. Use the value
``None`` for no pull.
.. data:: Pin.LOW_POWER
Pin.MED_POWER
Pin.HIGH_POWER
Selects the pin drive strength.
.. data:: Pin.IRQ_FALLING
Pin.IRQ_RISING
Pin.IRQ_LOW_LEVEL
Pin.IRQ_HIGH_LEVEL
Selects the IRQ trigger type.

View File

@ -1,69 +0,0 @@
.. currentmodule:: machine
.. _machine.RTC:
class RTC -- real time clock
============================
The RTC is and independent clock that keeps track of the date
and time.
Example usage::
rtc = machine.RTC()
rtc.init((2014, 5, 1, 4, 13, 0, 0, 0))
print(rtc.now())
Constructors
------------
.. class:: RTC(id=0, ...)
Create an RTC object. See init for parameters of initialization.
Methods
-------
.. method:: RTC.init(datetime)
Initialise the RTC. Datetime is a tuple of the form:
``(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])``
.. method:: RTC.now()
Get get the current datetime tuple.
.. method:: RTC.deinit()
Resets the RTC to the time of January 1, 2015 and starts running it again.
.. method:: RTC.alarm(id, time, \*, repeat=False)
Set the RTC alarm. Time might be either a millisecond value to program the alarm to
current time + time_in_ms in the future, or a datetimetuple. If the time passed is in
milliseconds, repeat can be set to ``True`` to make the alarm periodic.
.. method:: RTC.alarm_left(alarm_id=0)
Get the number of milliseconds left before the alarm expires.
.. method:: RTC.cancel(alarm_id=0)
Cancel a running alarm.
.. method:: RTC.irq(\*, trigger, handler=None, wake=machine.IDLE)
Create an irq object triggered by a real time clock alarm.
- ``trigger`` must be ``RTC.ALARM0``
- ``handler`` is the function to be called when the callback is triggered.
- ``wake`` specifies the sleep mode from where this interrupt can wake
up the system.
Constants
---------
.. data:: RTC.ALARM0
irq trigger source

View File

@ -1,47 +0,0 @@
.. currentmodule:: machine
.. _machine.SD:
class SD -- secure digital memory card (cc3200 port only)
=========================================================
.. warning::
This is a non-standard class and is only available on the cc3200 port.
The SD card class allows to configure and enable the memory card
module of the WiPy and automatically mount it as ``/sd`` as part
of the file system. There are several pin combinations that can be
used to wire the SD card socket to the WiPy and the pins used can
be specified in the constructor. Please check the `pinout and alternate functions
table. <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ for
more info regarding the pins which can be remapped to be used with a SD card.
Example usage::
from machine import SD
import os
# clk cmd and dat0 pins must be passed along with
# their respective alternate functions
sd = machine.SD(pins=('GP10', 'GP11', 'GP15'))
os.mount(sd, '/sd')
# do normal file operations
Constructors
------------
.. class:: SD(id,... )
Create a SD card object. See ``init()`` for parameters if initialization.
Methods
-------
.. method:: SD.init(id=0, pins=('GP10', 'GP11', 'GP15'))
Enable the SD card. In order to initialize the card, give it a 3-tuple:
``(clk_pin, cmd_pin, dat0_pin)``.
.. method:: SD.deinit()
Disable the SD card.

View File

@ -1,122 +0,0 @@
.. currentmodule:: machine
.. _machine.SDCard:
class SDCard -- secure digital memory card
==========================================
SD cards are one of the most common small form factor removable storage media.
SD cards come in a variety of sizes and physical form factors. MMC cards are
similar removable storage devices while eMMC devices are electrically similar
storage devices designed to be embedded into other systems. All three form
share a common protocol for communication with their host system and high-level
support looks the same for them all. As such in MicroPython they are implemented
in a single class called :class:`machine.SDCard` .
Both SD and MMC interfaces support being accessed with a variety of bus widths.
When being accessed with a 1-bit wide interface they can be accessed using the
SPI protocol. Different MicroPython hardware platforms support different widths
and pin configurations but for most platforms there is a standard configuration
for any given hardware. In general constructing an ``SDCard`` object with without
passing any parameters will initialise the interface to the default card slot
for the current hardware. The arguments listed below represent the common
arguments that might need to be set in order to use either a non-standard slot
or a non-standard pin assignment. The exact subset of arguments supported will
vary from platform to platform.
.. class:: SDCard(slot=1, width=1, cd=None, wp=None, sck=None, miso=None, mosi=None, cs=None)
This class provides access to SD or MMC storage cards using either
a dedicated SD/MMC interface hardware or through an SPI channel.
The class implements the block protocol defined by :class:`uos.AbstractBlockDev`.
This allows the mounting of an SD card to be as simple as::
uos.mount(machine.SDCard(), "/sd")
The constructor takes the following parameters:
- *slot* selects which of the available interfaces to use. Leaving this
unset will select the default interface.
- *width* selects the bus width for the SD/MMC interface.
- *cd* can be used to specify a card-detect pin.
- *wp* can be used to specify a write-protect pin.
- *sck* can be used to specify an SPI clock pin.
- *miso* can be used to specify an SPI miso pin.
- *mosi* can be used to specify an SPI mosi pin.
- *cs* can be used to specify an SPI chip select pin.
Implementation-specific details
-------------------------------
Different implementations of the ``SDCard`` class on different hardware support
varying subsets of the options above.
PyBoard
```````
The standard PyBoard has just one slot. No arguments are necessary or supported.
ESP32
`````
The ESP32 provides two channels of SD/MMC hardware and also supports
access to SD Cards through either of the two SPI ports that are
generally available to the user. As a result the *slot* argument can
take a value between 0 and 3, inclusive. Slots 0 and 1 use the
built-in SD/MMC hardware while slots 2 and 3 use the SPI ports. Slot 0
supports 1, 4 or 8-bit wide access while slot 1 supports 1 or 4-bit
access; the SPI slots only support 1-bit access.
.. note:: Slot 0 is used to communicate with on-board flash memory
on most ESP32 modules and so will be unavailable to the
user.
.. note:: Most ESP32 modules that provide an SD card slot using the
dedicated hardware only wire up 1 data pin, so the default
value for *width* is 1.
The pins used by the dedicated SD/MMC hardware are fixed. The pins
used by the SPI hardware can be reassigned.
.. note:: If any of the SPI signals are remapped then all of the SPI
signals will pass through a GPIO multiplexer unit which
can limit the performance of high frequency signals. Since
the normal operating speed for SD cards is 40MHz this can
cause problems on some cards.
The default (and preferred) pin assignment are as follows:
====== ====== ====== ====== ======
Slot 0 1 2 3
------ ------ ------ ------ ------
Signal Pin Pin Pin Pin
====== ====== ====== ====== ======
sck 6 14 18 14
cmd 11 15
cs 5 15
miso 19 12
mosi 23 13
D0 7 2
D1 8 4
D2 9 12
D3 10 13
D4 16
D5 17
D6 5
D7 18
====== ====== ====== ====== ======
cc3200
``````
You can set the pins used for SPI access by passing a tuple as the
*pins* argument.
*Note:* The current cc3200 SD card implementation names the this class
:class:`machine.SD` rather than :class:`machine.SDCard` .

View File

@ -1,101 +0,0 @@
.. currentmodule:: machine
.. _machine.SPI:
class SPI -- a Serial Peripheral Interface bus protocol (master side)
=====================================================================
SPI is a synchronous serial protocol that is driven by a master. At the
physical level, a bus consists of 3 lines: SCK, MOSI, MISO. Multiple devices
can share the same bus. Each device should have a separate, 4th signal,
SS (Slave Select), to select a particular device on a bus with which
communication takes place. Management of an SS signal should happen in
user code (via machine.Pin class).
Constructors
------------
.. class:: SPI(id, ...)
Construct an SPI object on the given bus, ``id``. Values of ``id`` depend
on a particular port and its hardware. Values 0, 1, etc. are commonly used
to select hardware SPI block #0, #1, etc. Value -1 can be used for
bitbanging (software) implementation of SPI (if supported by a port).
With no additional parameters, the SPI object is created but not
initialised (it has the settings from the last initialisation of
the bus, if any). If extra arguments are given, the bus is initialised.
See ``init`` for parameters of initialisation.
Methods
-------
.. method:: SPI.init(baudrate=1000000, \*, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))
Initialise the SPI bus with the given parameters:
- ``baudrate`` is the SCK clock rate.
- ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
- ``phase`` can be 0 or 1 to sample data on the first or second clock edge
respectively.
- ``bits`` is the width in bits of each transfer. Only 8 is guaranteed to be supported by all hardware.
- ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
- ``sck``, ``mosi``, ``miso`` are pins (machine.Pin) objects to use for bus signals. For most
hardware SPI blocks (as selected by ``id`` parameter to the constructor), pins are fixed
and cannot be changed. In some cases, hardware blocks allow 2-3 alternative pin sets for
a hardware SPI block. Arbitrary pin assignments are possible only for a bitbanging SPI driver
(``id`` = -1).
- ``pins`` - WiPy port doesn't ``sck``, ``mosi``, ``miso`` arguments, and instead allows to
specify them as a tuple of ``pins`` parameter.
In the case of hardware SPI the actual clock frequency may be lower than the
requested baudrate. This is dependant on the platform hardware. The actual
rate may be determined by printing the SPI object.
.. method:: SPI.deinit()
Turn off the SPI bus.
.. method:: SPI.read(nbytes, write=0x00)
Read a number of bytes specified by ``nbytes`` while continuously writing
the single byte given by ``write``.
Returns a ``bytes`` object with the data that was read.
.. method:: SPI.readinto(buf, write=0x00)
Read into the buffer specified by ``buf`` while continuously writing the
single byte given by ``write``.
Returns ``None``.
Note: on WiPy this function returns the number of bytes read.
.. method:: SPI.write(buf)
Write the bytes contained in ``buf``.
Returns ``None``.
Note: on WiPy this function returns the number of bytes written.
.. method:: SPI.write_readinto(write_buf, read_buf)
Write the bytes from ``write_buf`` while reading into ``read_buf``. The
buffers can be the same or different, but both buffers must have the
same length.
Returns ``None``.
Note: on WiPy this function returns the number of bytes written.
Constants
---------
.. data:: SPI.MASTER
for initialising the SPI bus to master; this is only used for the WiPy
.. data:: SPI.MSB
set the first bit to be the most significant bit
.. data:: SPI.LSB
set the first bit to be the least significant bit

View File

@ -1,123 +0,0 @@
.. currentmodule:: machine
.. _machine.Signal:
class Signal -- control and sense external I/O devices
======================================================
The Signal class is a simple extension of the `Pin` class. Unlike Pin, which
can be only in "absolute" 0 and 1 states, a Signal can be in "asserted"
(on) or "deasserted" (off) states, while being inverted (active-low) or
not. In other words, it adds logical inversion support to Pin functionality.
While this may seem a simple addition, it is exactly what is needed to
support wide array of simple digital devices in a way portable across
different boards, which is one of the major MicroPython goals. Regardless
of whether different users have an active-high or active-low LED, a normally
open or normally closed relay - you can develop a single, nicely looking
application which works with each of them, and capture hardware
configuration differences in few lines in the config file of your app.
Example::
from machine import Pin, Signal
# Suppose you have an active-high LED on pin 0
led1_pin = Pin(0, Pin.OUT)
# ... and active-low LED on pin 1
led2_pin = Pin(1, Pin.OUT)
# Now to light up both of them using Pin class, you'll need to set
# them to different values
led1_pin.value(1)
led2_pin.value(0)
# Signal class allows to abstract away active-high/active-low
# difference
led1 = Signal(led1_pin, invert=False)
led2 = Signal(led2_pin, invert=True)
# Now lighting up them looks the same
led1.value(1)
led2.value(1)
# Even better:
led1.on()
led2.on()
Following is the guide when Signal vs Pin should be used:
* Use Signal: If you want to control a simple on/off (including software
PWM!) devices like LEDs, multi-segment indicators, relays, buzzers, or
read simple binary sensors, like normally open or normally closed buttons,
pulled high or low, Reed switches, moisture/flame detectors, etc. etc.
Summing up, if you have a real physical device/sensor requiring GPIO
access, you likely should use a Signal.
* Use Pin: If you implement a higher-level protocol or bus to communicate
with more complex devices.
The split between Pin and Signal come from the usecases above and the
architecture of MicroPython: Pin offers the lowest overhead, which may
be important when bit-banging protocols. But Signal adds additional
flexibility on top of Pin, at the cost of minor overhead (much smaller
than if you implemented active-high vs active-low device differences in
Python manually!). Also, Pin is a low-level object which needs to be
implemented for each support board, while Signal is a high-level object
which comes for free once Pin is implemented.
If in doubt, give the Signal a try! Once again, it is offered to save
developers from the need to handle unexciting differences like active-low
vs active-high signals, and allow other users to share and enjoy your
application, instead of being frustrated by the fact that it doesn't
work for them simply because their LEDs or relays are wired in a slightly
different way.
Constructors
------------
.. class:: Signal(pin_obj, invert=False)
Signal(pin_arguments..., \*, invert=False)
Create a Signal object. There're two ways to create it:
* By wrapping existing Pin object - universal method which works for
any board.
* By passing required Pin parameters directly to Signal constructor,
skipping the need to create intermediate Pin object. Available on
many, but not all boards.
The arguments are:
- ``pin_obj`` is existing Pin object.
- ``pin_arguments`` are the same arguments as can be passed to Pin constructor.
- ``invert`` - if True, the signal will be inverted (active low).
Methods
-------
.. method:: Signal.value([x])
This method allows to set and get the value of the signal, depending on whether
the argument ``x`` is supplied or not.
If the argument is omitted then this method gets the signal level, 1 meaning
signal is asserted (active) and 0 - signal inactive.
If the argument is supplied then this method sets the signal level. The
argument ``x`` can be anything that converts to a boolean. If it converts
to ``True``, the signal is active, otherwise it is inactive.
Correspondence between signal being active and actual logic level on the
underlying pin depends on whether signal is inverted (active-low) or not.
For non-inverted signal, active status corresponds to logical 1, inactive -
to logical 0. For inverted/active-low signal, active status corresponds
to logical 0, while inactive - to logical 1.
.. method:: Signal.on()
Activate signal.
.. method:: Signal.off()
Deactivate signal.

View File

@ -1,64 +0,0 @@
.. currentmodule:: machine
.. _machine.Timer:
class Timer -- control hardware timers
======================================
Hardware timers deal with timing of periods and events. Timers are perhaps
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
differently greatly from a model to a model. MicroPython's Timer class
defines a baseline operation of executing a callback with a given period
(or once after some delay), and allow specific boards to define more
non-standard behavior (which thus won't be portable to other boards).
See discussion of :ref:`important constraints <machine_callbacks>` on
Timer callbacks.
.. note::
Memory can't be allocated inside irq handlers (an interrupt) and so
exceptions raised within a handler don't give much information. See
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
limitation.
If you are using a WiPy board please refer to :ref:`machine.TimerWiPy <machine.TimerWiPy>`
instead of this class.
Constructors
------------
.. class:: Timer(id, ...)
Construct a new timer object of the given id. Id of -1 constructs a
virtual timer (if supported by a board).
Methods
-------
.. method:: Timer.init(\*, mode=Timer.PERIODIC, period=-1, callback=None)
Initialise the timer. Example::
tim.init(period=100) # periodic with 100ms period
tim.init(mode=Timer.ONE_SHOT, period=1000) # one shot firing after 1000ms
Keyword arguments:
- ``mode`` can be one of:
- ``Timer.ONE_SHOT`` - The timer runs once until the configured
period of the channel expires.
- ``Timer.PERIODIC`` - The timer runs periodically at the configured
frequency of the channel.
.. method:: Timer.deinit()
Deinitialises the timer. Stops the timer, and disables the timer peripheral.
Constants
---------
.. data:: Timer.ONE_SHOT
Timer.PERIODIC
Timer operating mode.

View File

@ -1,159 +0,0 @@
.. currentmodule:: machine
.. _machine.TimerWiPy:
class TimerWiPy -- control hardware timers
==========================================
.. note::
This class is a non-standard Timer implementation for the WiPy.
It is available simply as ``machine.Timer`` on the WiPy but is named in the
documentation below as ``machine.TimerWiPy`` to distinguish it from the
more general :ref:`machine.Timer <machine.Timer>` class.
Hardware timers deal with timing of periods and events. Timers are perhaps
the most flexible and heterogeneous kind of hardware in MCUs and SoCs,
differently greatly from a model to a model. MicroPython's Timer class
defines a baseline operation of executing a callback with a given period
(or once after some delay), and allow specific boards to define more
non-standard behavior (which thus won't be portable to other boards).
See discussion of :ref:`important constraints <machine_callbacks>` on
Timer callbacks.
.. note::
Memory can't be allocated inside irq handlers (an interrupt) and so
exceptions raised within a handler don't give much information. See
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
limitation.
Constructors
------------
.. class:: TimerWiPy(id, ...)
Construct a new timer object of the given id. Id of -1 constructs a
virtual timer (if supported by a board).
Methods
-------
.. method:: TimerWiPy.init(mode, \*, width=16)
Initialise the timer. Example::
tim.init(Timer.PERIODIC) # periodic 16-bit timer
tim.init(Timer.ONE_SHOT, width=32) # one shot 32-bit timer
Keyword arguments:
- ``mode`` can be one of:
- ``TimerWiPy.ONE_SHOT`` - The timer runs once until the configured
period of the channel expires.
- ``TimerWiPy.PERIODIC`` - The timer runs periodically at the configured
frequency of the channel.
- ``TimerWiPy.PWM`` - Output a PWM signal on a pin.
- ``width`` must be either 16 or 32 (bits). For really low frequencies < 5Hz
(or large periods), 32-bit timers should be used. 32-bit mode is only available
for ``ONE_SHOT`` AND ``PERIODIC`` modes.
.. method:: TimerWiPy.deinit()
Deinitialises the timer. Stops the timer, and disables the timer peripheral.
.. method:: TimerWiPy.channel(channel, \**, freq, period, polarity=TimerWiPy.POSITIVE, duty_cycle=0)
If only a channel identifier passed, then a previously initialized channel
object is returned (or ``None`` if there is no previous channel).
Otherwise, a TimerChannel object is initialized and returned.
The operating mode is is the one configured to the Timer object that was used to
create the channel.
- ``channel`` if the width of the timer is 16-bit, then must be either ``TIMER.A``, ``TIMER.B``.
If the width is 32-bit then it **must be** ``TIMER.A | TIMER.B``.
Keyword only arguments:
- ``freq`` sets the frequency in Hz.
- ``period`` sets the period in microseconds.
.. note::
Either ``freq`` or ``period`` must be given, never both.
- ``polarity`` this is applicable for ``PWM``, and defines the polarity of the duty cycle
- ``duty_cycle`` only applicable to ``PWM``. It's a percentage (0.00-100.00). Since the WiPy
doesn't support floating point numbers the duty cycle must be specified in the range 0-10000,
where 10000 would represent 100.00, 5050 represents 50.50, and so on.
.. note::
When the channel is in PWM mode, the corresponding pin is assigned automatically, therefore
there's no need to assign the alternate function of the pin via the ``Pin`` class. The pins which
support PWM functionality are the following:
- ``GP24`` on Timer 0 channel A.
- ``GP25`` on Timer 1 channel A.
- ``GP9`` on Timer 2 channel B.
- ``GP10`` on Timer 3 channel A.
- ``GP11`` on Timer 3 channel B.
class TimerChannel --- setup a channel for a timer
==================================================
Timer channels are used to generate/capture a signal using a timer.
TimerChannel objects are created using the Timer.channel() method.
Methods
-------
.. method:: timerchannel.irq(\*, trigger, priority=1, handler=None)
The behavior of this callback is heavily dependent on the operating
mode of the timer channel:
- If mode is ``TimerWiPy.PERIODIC`` the callback is executed periodically
with the configured frequency or period.
- If mode is ``TimerWiPy.ONE_SHOT`` the callback is executed once when
the configured timer expires.
- If mode is ``TimerWiPy.PWM`` the callback is executed when reaching the duty
cycle value.
The accepted params are:
- ``priority`` level of the interrupt. Can take values in the range 1-7.
Higher values represent higher priorities.
- ``handler`` is an optional function to be called when the interrupt is triggered.
- ``trigger`` must be ``TimerWiPy.TIMEOUT`` when the operating mode is either ``TimerWiPy.PERIODIC`` or
``TimerWiPy.ONE_SHOT``. In the case that mode is ``TimerWiPy.PWM`` then trigger must be equal to
``TimerWiPy.MATCH``.
Returns a callback object.
.. method:: timerchannel.freq([value])
Get or set the timer channel frequency (in Hz).
.. method:: timerchannel.period([value])
Get or set the timer channel period (in microseconds).
.. method:: timerchannel.duty_cycle([value])
Get or set the duty cycle of the PWM signal. It's a percentage (0.00-100.00). Since the WiPy
doesn't support floating point numbers the duty cycle must be specified in the range 0-10000,
where 10000 would represent 100.00, 5050 represents 50.50, and so on.
Constants
---------
.. data:: TimerWiPy.ONE_SHOT
.. data:: TimerWiPy.PERIODIC
Timer operating mode.

View File

@ -1,152 +0,0 @@
.. currentmodule:: machine
.. _machine.UART:
class UART -- duplex serial communication bus
=============================================
UART implements the standard UART/USART duplex serial communications protocol. At
the physical level it consists of 2 lines: RX and TX. The unit of communication
is a character (not to be confused with a string character) which can be 8 or 9
bits wide.
UART objects can be created and initialised using::
from machine import UART
uart = UART(1, 9600) # init with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters
Supported parameters differ on a board:
Pyboard: Bits can be 7, 8 or 9. Stop can be 1 or 2. With *parity=None*,
only 8 and 9 bits are supported. With parity enabled, only 7 and 8 bits
are supported.
WiPy/CC3200: Bits can be 5, 6, 7, 8. Stop can be 1 or 2.
A UART object acts like a `stream` object and reading and writing is done
using the standard stream methods::
uart.read(10) # read 10 characters, returns a bytes object
uart.read() # read all available characters
uart.readline() # read a line
uart.readinto(buf) # read and store into the given buffer
uart.write('abc') # write the 3 characters
Constructors
------------
.. class:: UART(id, ...)
Construct a UART object of the given id.
Methods
-------
.. method:: UART.init(baudrate=9600, bits=8, parity=None, stop=1, \*, ...)
Initialise the UART bus with the given parameters:
- *baudrate* is the clock rate.
- *bits* is the number of bits per character, 7, 8 or 9.
- *parity* is the parity, ``None``, 0 (even) or 1 (odd).
- *stop* is the number of stop bits, 1 or 2.
Additional keyword-only parameters that may be supported by a port are:
- *tx* specifies the TX pin to use.
- *rx* specifies the RX pin to use.
- *txbuf* specifies the length in characters of the TX buffer.
- *rxbuf* specifies the length in characters of the RX buffer.
On the WiPy only the following keyword-only parameter is supported:
- *pins* is a 4 or 2 item list indicating the TX, RX, RTS and CTS pins (in that order).
Any of the pins can be None if one wants the UART to operate with limited functionality.
If the RTS pin is given the the RX pin must be given as well. The same applies to CTS.
When no pins are given, then the default set of TX and RX pins is taken, and hardware
flow control will be disabled. If *pins* is ``None``, no pin assignment will be made.
.. method:: UART.deinit()
Turn off the UART bus.
.. method:: UART.any()
Returns an integer counting the number of characters that can be read without
blocking. It will return 0 if there are no characters available and a positive
number if there are characters. The method may return 1 even if there is more
than one character available for reading.
For more sophisticated querying of available characters use select.poll::
poll = select.poll()
poll.register(uart, select.POLLIN)
poll.poll(timeout)
.. method:: UART.read([nbytes])
Read characters. If ``nbytes`` is specified then read at most that many bytes,
otherwise read as much data as possible.
Return value: a bytes object containing the bytes read in. Returns ``None``
on timeout.
.. method:: UART.readinto(buf[, nbytes])
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
that many bytes. Otherwise, read at most ``len(buf)`` bytes.
Return value: number of bytes read and stored into ``buf`` or ``None`` on
timeout.
.. method:: UART.readline()
Read a line, ending in a newline character.
Return value: the line read or ``None`` on timeout.
.. method:: UART.write(buf)
Write the buffer of bytes to the bus.
Return value: number of bytes written or ``None`` on timeout.
.. method:: UART.sendbreak()
Send a break condition on the bus. This drives the bus low for a duration
longer than required for a normal transmission of a character.
.. method:: UART.irq(trigger, priority=1, handler=None, wake=machine.IDLE)
Create a callback to be triggered when data is received on the UART.
- *trigger* can only be ``UART.RX_ANY``
- *priority* level of the interrupt. Can take values in the range 1-7.
Higher values represent higher priorities.
- *handler* an optional function to be called when new characters arrive.
- *wake* can only be ``machine.IDLE``.
.. note::
The handler will be called whenever any of the following two conditions are met:
- 8 new characters have been received.
- At least 1 new character is waiting in the Rx buffer and the Rx line has been
silent for the duration of 1 complete frame.
This means that when the handler function is called there will be between 1 to 8
characters waiting.
Returns an irq object.
Availability: WiPy.
Constants
---------
.. data:: UART.RX_ANY
IRQ trigger sources
Availability: WiPy.

View File

@ -1,36 +0,0 @@
.. currentmodule:: machine
.. _machine.WDT:
class WDT -- watchdog timer
===========================
The WDT is used to restart the system when the application crashes and ends
up into a non recoverable state. Once started it cannot be stopped or
reconfigured in any way. After enabling, the application must "feed" the
watchdog periodically to prevent it from expiring and resetting the system.
Example usage::
from machine import WDT
wdt = WDT(timeout=2000) # enable it with a timeout of 2s
wdt.feed()
Availability of this class: pyboard, WiPy.
Constructors
------------
.. class:: WDT(id=0, timeout=5000)
Create a WDT object and start it. The timeout must be given in seconds and
the minimum value that is accepted is 1 second. Once it is running the timeout
cannot be changed and the WDT cannot be stopped either.
Methods
-------
.. method:: wdt.feed()
Feed the WDT to prevent it from resetting the system. The application
should place this call in a sensible place ensuring that the WDT is
only fed after verifying that everything is functioning correctly.

View File

@ -1,171 +0,0 @@
:mod:`machine` --- functions related to the hardware
====================================================
.. module:: machine
:synopsis: functions related to the hardware
The ``machine`` module contains specific functions related to the hardware
on a particular board. Most functions in this module allow to achieve direct
and unrestricted access to and control of hardware blocks on a system
(like CPU, timers, buses, etc.). Used incorrectly, this can lead to
malfunction, lockups, crashes of your board, and in extreme cases, hardware
damage.
.. _machine_callbacks:
A note of callbacks used by functions and class methods of :mod:`machine` module:
all these callbacks should be considered as executing in an interrupt context.
This is true for both physical devices with IDs >= 0 and "virtual" devices
with negative IDs like -1 (these "virtual" devices are still thin shims on
top of real hardware and real hardware interrupts). See :ref:`isr_rules`.
Reset related functions
-----------------------
.. function:: reset()
Resets the device in a manner similar to pushing the external RESET
button.
.. function:: reset_cause()
Get the reset cause. See :ref:`constants <machine_constants>` for the possible return values.
Interrupt related functions
---------------------------
.. function:: disable_irq()
Disable interrupt requests.
Returns the previous IRQ state which should be considered an opaque value.
This return value should be passed to the `enable_irq()` function to restore
interrupts to their original state, before `disable_irq()` was called.
.. function:: enable_irq(state)
Re-enable interrupt requests.
The *state* parameter should be the value that was returned from the most
recent call to the `disable_irq()` function.
Power related functions
-----------------------
.. function:: freq()
Returns CPU frequency in hertz.
.. function:: idle()
Gates the clock to the CPU, useful to reduce power consumption at any time during
short or long periods. Peripherals continue working and execution resumes as soon
as any interrupt is triggered (on many ports this includes system timer
interrupt occurring at regular intervals on the order of millisecond).
.. function:: sleep()
.. note:: This function is deprecated, use `lightsleep()` instead with no arguments.
.. function:: lightsleep([time_ms])
deepsleep([time_ms])
Stops execution in an attempt to enter a low power state.
If *time_ms* is specified then this will be the maximum time in milliseconds that
the sleep will last for. Otherwise the sleep can last indefinitely.
With or without a timout, execution may resume at any time if there are events
that require processing. Such events, or wake sources, should be configured before
sleeping, like `Pin` change or `RTC` timeout.
The precise behaviour and power-saving capabilities of lightsleep and deepsleep is
highly dependent on the underlying hardware, but the general properties are:
* A lightsleep has full RAM and state retention. Upon wake execution is resumed
from the point where the sleep was requested, with all subsystems operational.
* A deepsleep may not retain RAM or any other state of the system (for example
peripherals or network interfaces). Upon wake execution is resumed from the main
script, similar to a hard or power-on reset. The `reset_cause()` function will
return `machine.DEEPSLEEP` and this can be used to distinguish a deepsleep wake
from other resets.
.. function:: wake_reason()
Get the wake reason. See :ref:`constants <machine_constants>` for the possible return values.
Availability: ESP32, WiPy.
Miscellaneous functions
-----------------------
.. function:: unique_id()
Returns a byte string with a unique identifier of a board/SoC. It will vary
from a board/SoC instance to another, if underlying hardware allows. Length
varies by hardware (so use substring of a full value if you expect a short
ID). In some MicroPython ports, ID corresponds to the network MAC address.
.. function:: time_pulse_us(pin, pulse_level, timeout_us=1000000)
Time a pulse on the given *pin*, and return the duration of the pulse in
microseconds. The *pulse_level* argument should be 0 to time a low pulse
or 1 to time a high pulse.
If the current input value of the pin is different to *pulse_level*,
the function first (*) waits until the pin input becomes equal to *pulse_level*,
then (**) times the duration that the pin is equal to *pulse_level*.
If the pin is already equal to *pulse_level* then timing starts straight away.
The function will return -2 if there was timeout waiting for condition marked
(*) above, and -1 if there was timeout during the main measurement, marked (**)
above. The timeout is the same for both cases and given by *timeout_us* (which
is in microseconds).
.. function:: rng()
Return a 24-bit software generated random number.
Availability: WiPy.
.. _machine_constants:
Constants
---------
.. data:: machine.IDLE
machine.SLEEP
machine.DEEPSLEEP
IRQ wake values.
.. data:: machine.PWRON_RESET
machine.HARD_RESET
machine.WDT_RESET
machine.DEEPSLEEP_RESET
machine.SOFT_RESET
Reset causes.
.. data:: machine.WLAN_WAKE
machine.PIN_WAKE
machine.RTC_WAKE
Wake-up reasons.
Classes
-------
.. toctree::
:maxdepth: 1
machine.Pin.rst
machine.Signal.rst
machine.ADC.rst
machine.UART.rst
machine.SPI.rst
machine.I2C.rst
machine.RTC.rst
machine.Timer.rst
machine.WDT.rst
machine.SD.rst
machine.SDCard.rst

View File

@ -4,16 +4,11 @@
.. module:: math
:synopsis: mathematical functions
|see_cpython_module| :mod:`python:math`.
The ``math`` module provides some basic mathematical functions for
The ``math`` module provides some basic mathematical funtions for
working with floating-point numbers.
*Note:* On the pyboard, floating-point numbers have 32-bit precision.
Availability: not available on WiPy. Floating point support required
for this module.
Functions
---------
@ -95,10 +90,7 @@ Functions
.. function:: frexp(x)
Decomposes a floating-point number into its mantissa and exponent.
The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e``
exactly. If ``x == 0`` then the function returns ``(0.0, 0)``, otherwise
the relation ``0.5 <= abs(m) < 1`` holds.
Converts a floating-point number to fractional and integral components.
.. function:: gamma(x)

View File

@ -1,140 +0,0 @@
:mod:`micropython` -- access and control MicroPython internals
==============================================================
.. module:: micropython
:synopsis: access and control MicroPython internals
Functions
---------
.. function:: const(expr)
Used to declare that the expression is a constant so that the compile can
optimise it. The use of this function should be as follows::
from micropython import const
CONST_X = const(123)
CONST_Y = const(2 * CONST_X + 1)
Constants declared this way are still accessible as global variables from
outside the module they are declared in. On the other hand, if a constant
begins with an underscore then it is hidden, it is not available as a global
variable, and does not take up any memory during execution.
This `const` function is recognised directly by the MicroPython parser and is
provided as part of the :mod:`micropython` module mainly so that scripts can be
written which run under both CPython and MicroPython, by following the above
pattern.
.. function:: opt_level([level])
If *level* is given then this function sets the optimisation level for subsequent
compilation of scripts, and returns ``None``. Otherwise it returns the current
optimisation level.
The optimisation level controls the following compilation features:
- Assertions: at level 0 assertion statements are enabled and compiled into the
bytecode; at levels 1 and higher assertions are not compiled.
- Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``;
at levels 1 and higher it expands to ``False``.
- Source-code line numbers: at levels 0, 1 and 2 source-code line number are
stored along with the bytecode so that exceptions can report the line number
they occurred at; at levels 3 and higher line numbers are not stored.
The default optimisation level is usually level 0.
.. function:: alloc_emergency_exception_buf(size)
Allocate *size* bytes of RAM for the emergency exception buffer (a good
size is around 100 bytes). The buffer is used to create exceptions in cases
when normal RAM allocation would fail (eg within an interrupt handler) and
therefore give useful traceback information in these situations.
A good way to use this function is to put it at the start of your main script
(eg ``boot.py`` or ``main.py``) and then the emergency exception buffer will be active
for all the code following it.
.. function:: mem_info([verbose])
Print information about currently used memory. If the *verbose* argument
is given then extra information is printed.
The information that is printed is implementation dependent, but currently
includes the amount of stack and heap used. In verbose mode it prints out
the entire heap indicating which blocks are used and which are free.
.. function:: qstr_info([verbose])
Print information about currently interned strings. If the *verbose*
argument is given then extra information is printed.
The information that is printed is implementation dependent, but currently
includes the number of interned strings and the amount of RAM they use. In
verbose mode it prints out the names of all RAM-interned strings.
.. function:: stack_use()
Return an integer representing the current amount of stack that is being
used. The absolute value of this is not particularly useful, rather it
should be used to compute differences in stack usage at different points.
.. function:: heap_lock()
.. function:: heap_unlock()
Lock or unlock the heap. When locked no memory allocation can occur and a
`MemoryError` will be raised if any heap allocation is attempted.
These functions can be nested, ie `heap_lock()` can be called multiple times
in a row and the lock-depth will increase, and then `heap_unlock()` must be
called the same number of times to make the heap available again.
If the REPL becomes active with the heap locked then it will be forcefully
unlocked.
.. function:: kbd_intr(chr)
Set the character that will raise a `KeyboardInterrupt` exception. By
default this is set to 3 during script execution, corresponding to Ctrl-C.
Passing -1 to this function will disable capture of Ctrl-C, and passing 3
will restore it.
This function can be used to prevent the capturing of Ctrl-C on the
incoming stream of characters that is usually used for the REPL, in case
that stream is used for other purposes.
.. function:: schedule(func, arg)
Schedule the function *func* to be executed "very soon". The function
is passed the value *arg* as its single argument. "Very soon" means that
the MicroPython runtime will do its best to execute the function at the
earliest possible time, given that it is also trying to be efficient, and
that the following conditions hold:
- A scheduled function will never preempt another scheduled function.
- Scheduled functions are always executed "between opcodes" which means
that all fundamental Python operations (such as appending to a list)
are guaranteed to be atomic.
- A given port may define "critical regions" within which scheduled
functions will never be executed. Functions may be scheduled within
a critical region but they will not be executed until that region
is exited. An example of a critical region is a preempting interrupt
handler (an IRQ).
A use for this function is to schedule a callback from a preempting IRQ.
Such an IRQ puts restrictions on the code that runs in the IRQ (for example
the heap may be locked) and scheduling a function to call later will lift
those restrictions.
Note: If `schedule()` is called from a preempting IRQ, when memory
allocation is not allowed and the callback to be passed to `schedule()` is
a bound method, passing this directly will fail. This is because creating a
reference to a bound method causes memory allocation. A solution is to
create a reference to the method in the class constructor and to pass that
reference to `schedule()`. This is discussed in detail here
:ref:`reference documentation <isr_rules>` under "Creation of Python
objects".
There is a finite queue to hold the scheduled functions and `schedule()`
will raise a `RuntimeError` if the queue is full.

View File

@ -1,89 +0,0 @@
.. currentmodule:: network
.. _network.CC3K:
class CC3K -- control CC3000 WiFi modules
=========================================
This class provides a driver for CC3000 WiFi modules. Example usage::
import network
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
nic.connect('your-ssid', 'your-password')
while not nic.isconnected():
pyb.delay(50)
print(nic.ifconfig())
# now use socket as usual
...
For this example to work the CC3000 module must have the following connections:
- MOSI connected to Y8
- MISO connected to Y7
- CLK connected to Y6
- CS connected to Y5
- VBEN connected to Y4
- IRQ connected to Y3
It is possible to use other SPI busses and other pins for CS, VBEN and IRQ.
Constructors
------------
.. class:: CC3K(spi, pin_cs, pin_en, pin_irq)
Create a CC3K driver object, initialise the CC3000 module using the given SPI bus
and pins, and return the CC3K object.
Arguments are:
- *spi* is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the CC3000 is
connected to (the MOSI, MISO and CLK pins).
- *pin_cs* is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 CS pin.
- *pin_en* is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 VBEN pin.
- *pin_irq* is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 IRQ pin.
All of these objects will be initialised by the driver, so there is no need to
initialise them yourself. For example, you can use::
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
Methods
-------
.. method:: CC3K.connect(ssid, key=None, \*, security=WPA2, bssid=None)
Connect to a WiFi access point using the given SSID, and other security
parameters.
.. method:: CC3K.disconnect()
Disconnect from the WiFi access point.
.. method:: CC3K.isconnected()
Returns True if connected to a WiFi access point and has a valid IP address,
False otherwise.
.. method:: CC3K.ifconfig()
Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server,
MAC address, SSID).
.. method:: CC3K.patch_version()
Return the version of the patch program (firmware) on the CC3000.
.. method:: CC3K.patch_program('pgm')
Upload the current firmware to the CC3000. You must pass 'pgm' as the first
argument in order for the upload to proceed.
Constants
---------
.. data:: CC3K.WEP
.. data:: CC3K.WPA
.. data:: CC3K.WPA2
security type to use

View File

@ -1,71 +0,0 @@
.. currentmodule:: network
.. _network.WIZNET5K:
class WIZNET5K -- control WIZnet5x00 Ethernet modules
=====================================================
This class allows you to control WIZnet5x00 Ethernet adaptors based on
the W5200 and W5500 chipsets. The particular chipset that is supported
by the firmware is selected at compile-time via the MICROPY_PY_WIZNET5K
option.
Example usage::
import network
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
print(nic.ifconfig())
# now use socket as usual
...
For this example to work the WIZnet5x00 module must have the following connections:
- MOSI connected to X8
- MISO connected to X7
- SCLK connected to X6
- nSS connected to X5
- nRESET connected to X4
It is possible to use other SPI busses and other pins for nSS and nRESET.
Constructors
------------
.. class:: WIZNET5K(spi, pin_cs, pin_rst)
Create a WIZNET5K driver object, initialise the WIZnet5x00 module using the given
SPI bus and pins, and return the WIZNET5K object.
Arguments are:
- *spi* is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the WIZnet5x00 is
connected to (the MOSI, MISO and SCLK pins).
- *pin_cs* is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nSS pin.
- *pin_rst* is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nRESET pin.
All of these objects will be initialised by the driver, so there is no need to
initialise them yourself. For example, you can use::
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
Methods
-------
.. method:: WIZNET5K.isconnected()
Returns ``True`` if the physical Ethernet link is connected and up.
Returns ``False`` otherwise.
.. method:: WIZNET5K.ifconfig([(ip, subnet, gateway, dns)])
Get/set IP address, subnet mask, gateway and DNS.
When called with no arguments, this method returns a 4-tuple with the above information.
To set the above values, pass a 4-tuple with the required information. For example::
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
.. method:: WIZNET5K.regs()
Dump the WIZnet5x00 registers. Useful for debugging.

View File

@ -1,132 +0,0 @@
.. currentmodule:: network
.. _network.WLAN:
class WLAN -- control built-in WiFi interfaces
==============================================
This class provides a driver for WiFi network processors. Example usage::
import network
# enable station interface and connect to WiFi access point
nic = network.WLAN(network.STA_IF)
nic.active(True)
nic.connect('your-ssid', 'your-password')
# now use sockets as usual
Constructors
------------
.. class:: WLAN(interface_id)
Create a WLAN network interface object. Supported interfaces are
``network.STA_IF`` (station aka client, connects to upstream WiFi access
points) and ``network.AP_IF`` (access point, allows other WiFi clients to
connect). Availability of the methods below depends on interface type.
For example, only STA interface may `WLAN.connect()` to an access point.
Methods
-------
.. method:: WLAN.active([is_active])
Activate ("up") or deactivate ("down") network interface, if boolean
argument is passed. Otherwise, query current state if no argument is
provided. Most other methods require active interface.
.. method:: WLAN.connect(ssid=None, password=None, \*, bssid=None)
Connect to the specified wireless network, using the specified password.
If *bssid* is given then the connection will be restricted to the
access-point with that MAC address (the *ssid* must also be specified
in this case).
.. method:: WLAN.disconnect()
Disconnect from the currently connected wireless network.
.. method:: WLAN.scan()
Scan for the available wireless networks.
Scanning is only possible on STA interface. Returns list of tuples with
the information about WiFi access points:
(ssid, bssid, channel, RSSI, authmode, hidden)
*bssid* is hardware address of an access point, in binary form, returned as
bytes object. You can use `ubinascii.hexlify()` to convert it to ASCII form.
There are five values for authmode:
* 0 -- open
* 1 -- WEP
* 2 -- WPA-PSK
* 3 -- WPA2-PSK
* 4 -- WPA/WPA2-PSK
and two for hidden:
* 0 -- visible
* 1 -- hidden
.. method:: WLAN.status([param])
Return the current status of the wireless connection.
When called with no argument the return value describes the network link status.
The possible statuses are defined as constants:
* ``STAT_IDLE`` -- no connection and no activity,
* ``STAT_CONNECTING`` -- connecting in progress,
* ``STAT_WRONG_PASSWORD`` -- failed due to incorrect password,
* ``STAT_NO_AP_FOUND`` -- failed because no access point replied,
* ``STAT_CONNECT_FAIL`` -- failed due to other problems,
* ``STAT_GOT_IP`` -- connection successful.
When called with one argument *param* should be a string naming the status
parameter to retrieve. Supported parameters in WiFI STA mode are: ``'rssi'``.
.. method:: WLAN.isconnected()
In case of STA mode, returns ``True`` if connected to a WiFi access
point and has a valid IP address. In AP mode returns ``True`` when a
station is connected. Returns ``False`` otherwise.
.. method:: WLAN.ifconfig([(ip, subnet, gateway, dns)])
Get/set IP-level network interface parameters: IP address, subnet mask,
gateway and DNS server. When called with no arguments, this method returns
a 4-tuple with the above information. To set the above values, pass a
4-tuple with the required information. For example::
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
.. method:: WLAN.config('param')
.. method:: WLAN.config(param=value, ...)
Get or set general network interface parameters. These methods allow to work
with additional parameters beyond standard IP configuration (as dealt with by
`WLAN.ifconfig()`). These include network-specific and hardware-specific
parameters. For setting parameters, keyword argument syntax should be used,
multiple parameters can be set at once. For querying, parameters name should
be quoted as a string, and only one parameter can be queries at time::
# Set WiFi access point name (formally known as ESSID) and WiFi channel
ap.config(essid='My AP', channel=11)
# Query params one by one
print(ap.config('essid'))
print(ap.config('channel'))
Following are commonly supported parameters (availability of a specific parameter
depends on network technology type, driver, and `MicroPython port`).
============= ===========
Parameter Description
============= ===========
mac MAC address (bytes)
essid WiFi access point name (string)
channel WiFi channel (integer)
hidden Whether ESSID is hidden (boolean)
authmode Authentication mode supported (enumeration, see module constants)
password Access password (string)
dhcp_hostname The DHCP hostname to use
============= ===========

View File

@ -1,161 +0,0 @@
.. currentmodule:: network
.. _network.WLANWiPy:
class WLANWiPy -- WiPy specific WiFi control
============================================
.. note::
This class is a non-standard WLAN implementation for the WiPy.
It is available simply as ``network.WLAN`` on the WiPy but is named in the
documentation below as ``network.WLANWiPy`` to distinguish it from the
more general :ref:`network.WLAN <network.WLAN>` class.
This class provides a driver for the WiFi network processor in the WiPy. Example usage::
import network
import time
# setup as a station
wlan = network.WLAN(mode=WLAN.STA)
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
while not wlan.isconnected():
time.sleep_ms(50)
print(wlan.ifconfig())
# now use socket as usual
...
Constructors
------------
.. class:: WLANWiPy(id=0, ...)
Create a WLAN object, and optionally configure it. See `init()` for params of configuration.
.. note::
The ``WLAN`` constructor is special in the sense that if no arguments besides the id are given,
it will return the already existing ``WLAN`` instance without re-configuring it. This is
because ``WLAN`` is a system feature of the WiPy. If the already existing instance is not
initialized it will do the same as the other constructors an will initialize it with default
values.
Methods
-------
.. method:: WLANWiPy.init(mode, \*, ssid, auth, channel, antenna)
Set or get the WiFi network processor configuration.
Arguments are:
- *mode* can be either ``WLAN.STA`` or ``WLAN.AP``.
- *ssid* is a string with the ssid name. Only needed when mode is ``WLAN.AP``.
- *auth* is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``,
``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password.
If ``sec`` is ``WLAN.WEP`` the key must be a string representing hexadecimal
values (e.g. 'ABC1DE45BF'). Only needed when mode is ``WLAN.AP``.
- *channel* a number in the range 1-11. Only needed when mode is ``WLAN.AP``.
- *antenna* selects between the internal and the external antenna. Can be either
``WLAN.INT_ANT`` or ``WLAN.EXT_ANT``.
For example, you can do::
# create and configure as an access point
wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channel=7, antenna=WLAN.INT_ANT)
or::
# configure as an station
wlan.init(mode=WLAN.STA)
.. method:: WLANWiPy.connect(ssid, \*, auth=None, bssid=None, timeout=None)
Connect to a WiFi access point using the given SSID, and other security
parameters.
- *auth* is a tuple with (sec, key). Security can be ``None``, ``WLAN.WEP``,
``WLAN.WPA`` or ``WLAN.WPA2``. The key is a string with the network password.
If ``sec`` is ``WLAN.WEP`` the key must be a string representing hexadecimal
values (e.g. 'ABC1DE45BF').
- *bssid* is the MAC address of the AP to connect to. Useful when there are several
APs with the same ssid.
- *timeout* is the maximum time in milliseconds to wait for the connection to succeed.
.. method:: WLANWiPy.scan()
Performs a network scan and returns a list of named tuples with (ssid, bssid, sec, channel, rssi).
Note that channel is always ``None`` since this info is not provided by the WiPy.
.. method:: WLANWiPy.disconnect()
Disconnect from the WiFi access point.
.. method:: WLANWiPy.isconnected()
In case of STA mode, returns ``True`` if connected to a WiFi access point and has a valid IP address.
In AP mode returns ``True`` when a station is connected, ``False`` otherwise.
.. method:: WLANWiPy.ifconfig(if_id=0, config=['dhcp' or configtuple])
With no parameters given returns a 4-tuple of *(ip, subnet_mask, gateway, DNS_server)*.
if ``'dhcp'`` is passed as a parameter then the DHCP client is enabled and the IP params
are negotiated with the AP.
If the 4-tuple config is given then a static IP is configured. For instance::
wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
.. method:: WLANWiPy.mode([mode])
Get or set the WLAN mode.
.. method:: WLANWiPy.ssid([ssid])
Get or set the SSID when in AP mode.
.. method:: WLANWiPy.auth([auth])
Get or set the authentication type when in AP mode.
.. method:: WLANWiPy.channel([channel])
Get or set the channel (only applicable in AP mode).
.. method:: WLANWiPy.antenna([antenna])
Get or set the antenna type (external or internal).
.. method:: WLANWiPy.mac([mac_addr])
Get or set a 6-byte long bytes object with the MAC address.
.. method:: WLANWiPy.irq(\*, handler, wake)
Create a callback to be triggered when a WLAN event occurs during ``machine.SLEEP``
mode. Events are triggered by socket activity or by WLAN connection/disconnection.
- *handler* is the function that gets called when the IRQ is triggered.
- *wake* must be ``machine.SLEEP``.
Returns an IRQ object.
Constants
---------
.. data:: WLANWiPy.STA
.. data:: WLANWiPy.AP
selects the WLAN mode
.. data:: WLANWiPy.WEP
.. data:: WLANWiPy.WPA
.. data:: WLANWiPy.WPA2
selects the network security
.. data:: WLANWiPy.INT_ANT
.. data:: WLANWiPy.EXT_ANT
selects the antenna type

View File

@ -5,29 +5,21 @@
.. module:: network
:synopsis: network configuration
This module provides network drivers and routing configuration. To use this
module, a MicroPython variant/build with network capabilities must be installed.
Network drivers for specific hardware are available within this module and are
used to configure hardware network interface(s). Network services provided
by configured interfaces are then available for use via the :mod:`usocket`
module.
This module provides network drivers and routing configuration. Network
drivers for specific hardware are available within this module and are
used to configure a hardware network interface. Configured interfaces
are then available for use via the :mod:`socket` module.
For example::
# connect/ show IP config a specific network interface
# configure a specific network interface
# see below for examples of specific drivers
import network
import utime
nic = network.Driver(...)
if not nic.isconnected():
nic.connect()
print("Waiting for connection...")
while not nic.isconnected():
utime.sleep(1)
print(nic.ifconfig())
# now use usocket as usual
import usocket as socket
# now use socket as usual
import socket
addr = socket.getaddrinfo('micropython.org', 80)[0][-1]
s = socket.socket()
s.connect(addr)
@ -35,139 +27,151 @@ For example::
data = s.recv(1000)
s.close()
Common network adapter interface
================================
class CC3K
==========
This section describes an (implied) abstract base class for all network
interface classes implemented by `MicroPython ports <MicroPython port>`
for different hardware. This means that MicroPython does not actually
provide ``AbstractNIC`` class, but any actual NIC class, as described
in the following sections, implements methods as described here.
This class provides a driver for CC3000 wifi modules. Example usage::
.. class:: AbstractNIC(id=None, ...)
import network
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
nic.connect('your-ssid', 'your-password')
while not nic.isconnected():
pyb.delay(50)
print(nic.ifconfig())
Instantiate a network interface object. Parameters are network interface
dependent. If there are more than one interface of the same type, the first
parameter should be `id`.
# now use socket as usual
...
.. method:: AbstractNIC.active([is_active])
For this example to work the CC3000 module must have the following connections:
Activate ("up") or deactivate ("down") the network interface, if
a boolean argument is passed. Otherwise, query current state if
no argument is provided. Most other methods require an active
interface (behavior of calling them on inactive interface is
undefined).
- MOSI connected to Y8
- MISO connected to Y7
- CLK connected to Y6
- CS connected to Y5
- VBEN connected to Y4
- IRQ connected to Y3
.. method:: AbstractNIC.connect([service_id, key=None, \*, ...])
It is possible to use other SPI busses and other pins for CS, VBEN and IRQ.
Connect the interface to a network. This method is optional, and
available only for interfaces which are not "always connected".
If no parameters are given, connect to the default (or the only)
service. If a single parameter is given, it is the primary identifier
of a service to connect to. It may be accompanied by a key
(password) required to access said service. There can be further
arbitrary keyword-only parameters, depending on the networking medium
type and/or particular device. Parameters can be used to: a)
specify alternative service identifier types; b) provide additional
connection parameters. For various medium types, there are different
sets of predefined/recommended parameters, among them:
Constructors
------------
* WiFi: *bssid* keyword to connect to a specific BSSID (MAC address)
.. class:: CC3K(spi, pin_cs, pin_en, pin_irq)
.. method:: AbstractNIC.disconnect()
Create a CC3K driver object, initialise the CC3000 module using the given SPI bus
and pins, and return the CC3K object.
Disconnect from network.
Arguments are:
.. method:: AbstractNIC.isconnected()
- ``spi`` is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the CC3000 is
connected to (the MOSI, MISO and CLK pins).
- ``pin_cs`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 CS pin.
- ``pin_en`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 VBEN pin.
- ``pin_irq`` is a :ref:`Pin object <pyb.Pin>` which is connected to the CC3000 IRQ pin.
Returns ``True`` if connected to network, otherwise returns ``False``.
All of these objects will be initialised by the driver, so there is no need to
initialise them yourself. For example, you can use::
.. method:: AbstractNIC.scan(\*, ...)
nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3)
Scan for the available network services/connections. Returns a
list of tuples with discovered service parameters. For various
network media, there are different variants of predefined/
recommended tuple formats, among them:
Methods
-------
* WiFi: (ssid, bssid, channel, RSSI, authmode, hidden). There
may be further fields, specific to a particular device.
.. method:: cc3k.connect(ssid, key=None, \*, security=WPA2, bssid=None)
The function may accept additional keyword arguments to filter scan
results (e.g. scan for a particular service, on a particular channel,
for services of a particular set, etc.), and to affect scan
duration and other parameters. Where possible, parameter names
should match those in connect().
Connect to a wifi access point using the given SSID, and other security
parameters.
.. method:: AbstractNIC.status([param])
.. method:: cc3k.disconnect()
Query dynamic status information of the interface. When called with no
argument the return value describes the network link status. Otherwise
*param* should be a string naming the particular status parameter to
retrieve.
Disconnect from the wifi access point.
The return types and values are dependent on the network
medium/technology. Some of the parameters that may be supported are:
.. method:: cc3k.isconnected()
* WiFi STA: use ``'rssi'`` to retrieve the RSSI of the AP signal
* WiFi AP: use ``'stations'`` to retrieve a list of all the STAs
connected to the AP. The list contains tuples of the form
(MAC, RSSI).
Returns True if connected to a wifi access point and has a valid IP address,
False otherwise.
.. method:: AbstractNIC.ifconfig([(ip, subnet, gateway, dns)])
.. method:: cc3k.ifconfig()
Get/set IP-level network interface parameters: IP address, subnet mask,
gateway and DNS server. When called with no arguments, this method returns
a 4-tuple with the above information. To set the above values, pass a
4-tuple with the required information. For example::
Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server,
MAC address, SSID).
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
.. method:: cc3k.patch_version()
.. method:: AbstractNIC.config('param')
AbstractNIC.config(param=value, ...)
Return the version of the patch program (firmware) on the CC3000.
Get or set general network interface parameters. These methods allow to work
with additional parameters beyond standard IP configuration (as dealt with by
`ifconfig()`). These include network-specific and hardware-specific
parameters. For setting parameters, the keyword argument
syntax should be used, and multiple parameters can be set at once. For
querying, a parameter name should be quoted as a string, and only one
parameter can be queried at a time::
.. method:: cc3k.patch_program('pgm')
# Set WiFi access point name (formally known as ESSID) and WiFi channel
ap.config(essid='My AP', channel=11)
# Query params one by one
print(ap.config('essid'))
print(ap.config('channel'))
Upload the current firmware to the CC3000. You must pass 'pgm' as the first
argument in order for the upload to proceed.
Specific network class implementations
======================================
Constants
---------
The following concrete classes implement the AbstractNIC interface and
provide a way to control networking interfaces of various kinds.
.. data:: CC3K.WEP
.. data:: CC3K.WPA
.. data:: CC3K.WPA2
.. toctree::
:maxdepth: 1
security type to use
network.WLAN.rst
network.WLANWiPy.rst
network.CC3K.rst
network.WIZNET5K.rst
class WIZNET5K
==============
Network functions
=================
This class allows you to control WIZnet5x00 Ethernet adaptors based on
the W5200 and W5500 chipsets (only W5200 tested).
The following are functions available in the network module.
Example usage::
.. function:: phy_mode([mode])
import network
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
print(nic.ifconfig())
Get or set the PHY mode.
# now use socket as usual
...
If the *mode* parameter is provided, sets the mode to its value. If
the function is called without parameters, returns the current mode.
For this example to work the WIZnet5x00 module must have the following connections:
The possible modes are defined as constants:
* ``MODE_11B`` -- IEEE 802.11b,
* ``MODE_11G`` -- IEEE 802.11g,
* ``MODE_11N`` -- IEEE 802.11n.
- MOSI connected to X8
- MISO connected to X7
- SCLK connected to X6
- nSS connected to X5
- nRESET connected to X4
Availability: ESP8266.
It is possible to use other SPI busses and other pins for nSS and nRESET.
Constructors
------------
.. class:: WIZNET5K(spi, pin_cs, pin_rst)
Create a WIZNET5K driver object, initialise the WIZnet5x00 module using the given
SPI bus and pins, and return the WIZNET5K object.
Arguments are:
- ``spi`` is an :ref:`SPI object <pyb.SPI>` which is the SPI bus that the WIZnet5x00 is
connected to (the MOSI, MISO and SCLK pins).
- ``pin_cs`` is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nSS pin.
- ``pin_rst`` is a :ref:`Pin object <pyb.Pin>` which is connected to the WIZnet5x00 nRESET pin.
All of these objects will be initialised by the driver, so there is no need to
initialise them yourself. For example, you can use::
nic = network.WIZNET5K(pyb.SPI(1), pyb.Pin.board.X5, pyb.Pin.board.X4)
Methods
-------
.. method:: wiznet5k.ifconfig([(ip, subnet, gateway, dns)])
Get/set IP address, subnet mask, gateway and DNS.
When called with no arguments, this method returns a 4-tuple with the above information.
To set the above values, pass a 4-tuple with the required information. For example::
nic.ifconfig(('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
.. method:: wiznet5k.regs()
Dump the WIZnet5x00 registers. Useful for debugging.

View File

@ -0,0 +1,67 @@
:mod:`os` -- basic "operating system" services
==============================================
.. module:: os
:synopsis: basic "operating system" services
The ``os`` module contains functions for filesystem access and ``urandom``.
Pyboard specifics
-----------------
The filesystem on the pyboard has ``/`` as the root directory and the
available physical drives are accessible from here. They are currently:
``/flash`` -- the internal flash filesystem
``/sd`` -- the SD card (if it exists)
On boot up, the current directory is ``/flash`` if no SD card is inserted,
otherwise it is ``/sd``.
Functions
---------
.. function:: chdir(path)
Change current directory.
.. function:: getcwd()
Get the current directory.
.. function:: listdir([dir])
With no argument, list the current directory. Otherwise list the given directory.
.. function:: mkdir(path)
Create a new directory.
.. function:: remove(path)
Remove a file.
.. function:: rmdir(path)
Remove a directory.
.. function:: stat(path)
Get the status of a file or directory.
.. function:: sync()
Sync all filesystems.
.. function:: urandom(n)
Return a bytes object with n random bytes, generated by the hardware
random number generator.
Constants
---------
.. data:: sep
separation character used in paths

View File

@ -1,23 +1,20 @@
.. currentmodule:: pyb
.. _pyb.ADC:
class ADC -- analog to digital conversion
=========================================
class ADC -- analog to digital conversion: read analog values on a pin
======================================================================
Usage::
import pyb
adc = pyb.ADC(pin) # create an analog object from a pin
val = adc.read() # read an analog value
adc = pyb.ADC(pin) # create an analog object from a pin
val = adc.read() # read an analog value
adc = pyb.ADCAll(resolution) # create an ADCAll object
adc = pyb.ADCAll(resolution, mask) # create an ADCAll object for selected analog channels
val = adc.read_channel(channel) # read the given channel
val = adc.read_core_temp() # read MCU temperature
val = adc.read_core_vbat() # read MCU VBAT
val = adc.read_core_vref() # read MCU VREF
val = adc.read_vref() # read MCU supply voltage
adc = pyb.ADCAll(resolution) # creale an ADCAll object
val = adc.read_channel(channel) # read the given channel
val = adc.read_core_temp() # read MCU temperature
val = adc.read_core_vbat() # read MCU VBAT
val = adc.read_core_vref() # read MCU VREF
Constructors
@ -28,140 +25,28 @@ Constructors
Create an ADC object associated with the given pin.
This allows you to then read analog values on that pin.
Methods
-------
.. method:: ADC.read()
.. method:: adc.read()
Read the value on the analog pin and return it. The returned value
will be between 0 and 4095.
.. method:: ADC.read_timed(buf, timer)
Read analog values into ``buf`` at a rate set by the ``timer`` object.
``buf`` can be bytearray or array.array for example. The ADC values have
12-bit resolution and are stored directly into ``buf`` if its element size is
16 bits or greater. If ``buf`` has only 8-bit elements (eg a bytearray) then
the sample resolution will be reduced to 8 bits.
``timer`` should be a Timer object, and a sample is read each time the timer
triggers. The timer must already be initialised and running at the desired
sampling frequency.
To support previous behaviour of this function, ``timer`` can also be an
integer which specifies the frequency (in Hz) to sample at. In this case
Timer(6) will be automatically configured to run at the given frequency.
Example using a Timer object (preferred way)::
adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
tim = pyb.Timer(6, freq=10) # create a timer running at 10Hz
buf = bytearray(100) # creat a buffer to store the samples
adc.read_timed(buf, tim) # sample 100 values, taking 10s
Example using an integer for the frequency::
.. method:: adc.read_timed(buf, freq)
Read analog values into the given buffer at the given frequency. Buffer
can be bytearray or array.array for example. If a buffer with 8-bit elements
is used, sample resolution will be reduced to 8 bits.
Example::
adc = pyb.ADC(pyb.Pin.board.X19) # create an ADC on pin X19
buf = bytearray(100) # create a buffer of 100 bytes
adc.read_timed(buf, 10) # read analog values into buf at 10Hz
# this will take 10 seconds to finish
for val in buf: # loop over all values
print(val) # print the value out
This function does not allocate any heap memory. It has blocking behaviour:
it does not return to the calling program until the buffer is full.
.. method:: ADC.read_timed_multi((adcx, adcy, ...), (bufx, bufy, ...), timer)
This is a static method. It can be used to extract relative timing or
phase data from multiple ADC's.
It reads analog values from multiple ADC's into buffers at a rate set by
the *timer* object. Each time the timer triggers a sample is rapidly
read from each ADC in turn.
ADC and buffer instances are passed in tuples with each ADC having an
associated buffer. All buffers must be of the same type and length and
the number of buffers must equal the number of ADC's.
Buffers can be ``bytearray`` or ``array.array`` for example. The ADC values
have 12-bit resolution and are stored directly into the buffer if its element
size is 16 bits or greater. If buffers have only 8-bit elements (eg a
``bytearray``) then the sample resolution will be reduced to 8 bits.
*timer* must be a Timer object. The timer must already be initialised
and running at the desired sampling frequency.
Example reading 3 ADC's::
adc0 = pyb.ADC(pyb.Pin.board.X1) # Create ADC's
adc1 = pyb.ADC(pyb.Pin.board.X2)
adc2 = pyb.ADC(pyb.Pin.board.X3)
tim = pyb.Timer(8, freq=100) # Create timer
rx0 = array.array('H', (0 for i in range(100))) # ADC buffers of
rx1 = array.array('H', (0 for i in range(100))) # 100 16-bit words
rx2 = array.array('H', (0 for i in range(100)))
# read analog values into buffers at 100Hz (takes one second)
pyb.ADC.read_timed_multi((adc0, adc1, adc2), (rx0, rx1, rx2), tim)
for n in range(len(rx0)):
print(rx0[n], rx1[n], rx2[n])
This function does not allocate any heap memory. It has blocking behaviour:
it does not return to the calling program until the buffers are full.
The function returns ``True`` if all samples were acquired with correct
timing. At high sample rates the time taken to acquire a set of samples
can exceed the timer period. In this case the function returns ``False``,
indicating a loss of precision in the sample interval. In extreme cases
samples may be missed.
The maximum rate depends on factors including the data width and the
number of ADC's being read. In testing two ADC's were sampled at a timer
rate of 210kHz without overrun. Samples were missed at 215kHz. For three
ADC's the limit is around 140kHz, and for four it is around 110kHz.
At high sample rates disabling interrupts for the duration can reduce the
risk of sporadic data loss.
The ADCAll Object
-----------------
Instantiating this changes all masked ADC pins to analog inputs. The preprocessed MCU temperature,
VREF and VBAT data can be accessed on ADC channels 16, 17 and 18 respectively.
Appropriate scaling is handled according to reference voltage used (usually 3.3V).
The temperature sensor on the chip is factory calibrated and allows to read the die temperature
to +/- 1 degree centigrade. Although this sounds pretty accurate, don't forget that the MCU's internal
temperature is measured. Depending on processing loads and I/O subsystems active the die temperature
may easily be tens of degrees above ambient temperature. On the other hand a pyboard woken up after a
long standby period will show correct ambient temperature within limits mentioned above.
The ``ADCAll`` ``read_core_vbat()``, ``read_vref()`` and ``read_core_vref()`` methods read
the backup battery voltage, reference voltage and the (1.21V nominal) reference voltage using the
actual supply as a reference. All results are floating point numbers giving direct voltage values.
``read_core_vbat()`` returns the voltage of the backup battery. This voltage is also adjusted according
to the actual supply voltage. To avoid analog input overload the battery voltage is measured
via a voltage divider and scaled according to the divider value. To prevent excessive loads
to the backup battery, the voltage divider is only active during ADC conversion.
``read_vref()`` is evaluated by measuring the internal voltage reference and backscale it using
factory calibration value of the internal voltage reference. In most cases the reading would be close
to 3.3V. If the pyboard is operated from a battery, the supply voltage may drop to values below 3.3V.
The pyboard will still operate fine as long as the operating conditions are met. With proper settings
of MCU clock, flash access speed and programming mode it is possible to run the pyboard down to
2 V and still get useful ADC conversion.
It is very important to make sure analog input voltages never exceed actual supply voltage.
Other analog input channels (0..15) will return unscaled integer values according to the selected
precision.
To avoid unwanted activation of analog inputs (channel 0..15) a second parameter can be specified.
This parameter is a binary pattern where each requested analog input has the corresponding bit set.
The default value is 0xffffffff which means all analog inputs are active. If just the internal
channels (16..18) are required, the mask value should be 0x70000.
Example::
adcall = pyb.ADCAll(12, 0x70000) # 12 bit resolution, internal channels
temp = adcall.read_core_temp()
This function does not allocate any memory.

View File

@ -1,6 +1,3 @@
.. currentmodule:: pyb
.. _pyb.Accel:
class Accel -- accelerometer control
====================================
@ -19,39 +16,36 @@ Constructors
.. class:: pyb.Accel()
Create and return an accelerometer object.
Note: if you read accelerometer values immediately after creating this object
you will get 0. It takes around 20ms for the first sample to be ready, so,
unless you have some other code between creating this object and reading its
values, you should put a ``pyb.delay(20)`` after creating it. For example::
accel = pyb.Accel()
pyb.delay(20)
print(accel.x())
Methods
-------
.. method:: Accel.filtered_xyz()
.. method:: accel.filtered_xyz()
Get a 3-tuple of filtered x, y and z values.
Implementation note: this method is currently implemented as taking the
sum of 4 samples, sampled from the 3 previous calls to this function along
with the sample from the current call. Returned values are therefore 4
times the size of what they would be from the raw x(), y() and z() calls.
.. method:: Accel.tilt()
.. method:: accel.tilt()
Get the tilt register.
.. method:: Accel.x()
.. method:: accel.x()
Get the x-axis value.
.. method:: Accel.y()
.. method:: accel.y()
Get the y-axis value.
.. method:: Accel.z()
.. method:: accel.z()
Get the z-axis value.
Hardware Note
-------------
The accelerometer uses I2C bus 1 to communicate with the processor. Consequently
when readings are being taken pins X9 and X10 should be unused (other than for
I2C). Other devices using those pins, and which therefore cannot be used
concurrently, are UART 1 and Timer 4 channels 1 and 2.

View File

@ -1,6 +1,3 @@
.. currentmodule:: pyb
.. _pyb.CAN:
class CAN -- controller area network communication bus
======================================================
@ -24,49 +21,46 @@ Constructors
.. class:: pyb.CAN(bus, ...)
Construct a CAN object on the given bus. *bus* can be 1-2, or ``'YA'`` or ``'YB'``.
Construct a CAN object on the given bus. ``bus`` can be 1-2, or 'YA' or 'YB'.
With no additional parameters, the CAN object is created but not
initialised (it has the settings from the last initialisation of
the bus, if any). If extra arguments are given, the bus is initialised.
See :meth:`CAN.init` for parameters of initialisation.
See ``init`` for parameters of initialisation.
The physical pins of the CAN busses are:
- ``CAN(1)`` is on ``YA``: ``(RX, TX) = (Y3, Y4) = (PB8, PB9)``
- ``CAN(2)`` is on ``YB``: ``(RX, TX) = (Y5, Y6) = (PB12, PB13)``
Class Methods
-------------
.. classmethod:: CAN.initfilterbanks(nr)
.. method:: CAN.initfilterbanks(nr)
Reset and disable all filter banks and assign how many banks should be available for CAN(1).
STM32F405 has 28 filter banks that are shared between the two available CAN bus controllers.
This function configures how many filter banks should be assigned to each. *nr* is the number of banks
that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2).
This function configures how many filter banks should be assigned to each. ``nr`` is the number of banks
that will be assigned to CAN(1), the rest of the 28 are assigned to CAN(2).
At boot, 14 banks are assigned to each controller.
Methods
-------
.. method:: CAN.init(mode, extframe=False, prescaler=100, \*, sjw=1, bs1=6, bs2=8, auto_restart=False)
.. method:: can.init(mode, extframe=False, prescaler=100, \*, sjw=1, bs1=6, bs2=8)
Initialise the CAN bus with the given parameters:
- *mode* is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
- if *extframe* is True then the bus uses extended identifiers in the frames
- ``mode`` is one of: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
- if ``extframe`` is True then the bus uses extended identifiers in the frames
(29 bits); otherwise it uses standard 11 bit identifiers
- *prescaler* is used to set the duration of 1 time quanta; the time quanta
- ``prescaler`` is used to set the duration of 1 time quanta; the time quanta
will be the input clock (PCLK1, see :meth:`pyb.freq()`) divided by the prescaler
- *sjw* is the resynchronisation jump width in units of the time quanta;
- ``sjw`` is the resynchronisation jump width in units of the time quanta;
it can be 1, 2, 3, 4
- *bs1* defines the location of the sample point in units of the time quanta;
- ``bs1`` defines the location of the sample point in units of the time quanta;
it can be between 1 and 1024 inclusive
- *bs2* defines the location of the transmit point in units of the time quanta;
- ``bs2`` defines the location of the transmit point in units of the time quanta;
it can be between 1 and 16 inclusive
- *auto_restart* sets whether the controller will automatically try and restart
communications after entering the bus-off state; if this is disabled then
:meth:`~CAN.restart()` can be used to leave the bus-off state
The time quanta tq is the basic unit of time for the CAN bus. tq is the CAN
prescaler value divided by PCLK1 (the frequency of internal peripheral bus 1);
@ -84,68 +78,21 @@ Methods
See page 680 of the STM32F405 datasheet for more details.
.. method:: CAN.deinit()
.. method:: can.deinit()
Turn off the CAN bus.
.. method:: CAN.restart()
Force a software restart of the CAN controller without resetting its
configuration.
If the controller enters the bus-off state then it will no longer participate
in bus activity. If the controller is not configured to automatically restart
(see :meth:`~CAN.init()`) then this method can be used to trigger a restart,
and the controller will follow the CAN protocol to leave the bus-off state and
go into the error active state.
.. method:: CAN.state()
Return the state of the controller. The return value can be one of:
- ``CAN.STOPPED`` -- the controller is completely off and reset;
- ``CAN.ERROR_ACTIVE`` -- the controller is on and in the Error Active state
(both TEC and REC are less than 96);
- ``CAN.ERROR_WARNING`` -- the controller is on and in the Error Warning state
(at least one of TEC or REC is 96 or greater);
- ``CAN.ERROR_PASSIVE`` -- the controller is on and in the Error Passive state
(at least one of TEC or REC is 128 or greater);
- ``CAN.BUS_OFF`` -- the controller is on but not participating in bus activity
(TEC overflowed beyond 255).
.. method:: CAN.info([list])
Get information about the controller's error states and TX and RX buffers.
If *list* is provided then it should be a list object with at least 8 entries,
which will be filled in with the information. Otherwise a new list will be
created and filled in. In both cases the return value of the method is the
populated list.
The values in the list are:
- TEC value
- REC value
- number of times the controller enterted the Error Warning state (wrapped
around to 0 after 65535)
- number of times the controller enterted the Error Passive state (wrapped
around to 0 after 65535)
- number of times the controller enterted the Bus Off state (wrapped
around to 0 after 65535)
- number of pending TX messages
- number of pending RX messages on fifo 0
- number of pending RX messages on fifo 1
.. method:: CAN.setfilter(bank, mode, fifo, params, \*, rtr)
.. method:: can.setfilter(bank, mode, fifo, params)
Configure a filter bank:
- *bank* is the filter bank that is to be configured.
- *mode* is the mode the filter should operate in.
- *fifo* is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter.
- *params* is an array of values the defines the filter. The contents of the array depends on the *mode* argument.
- ``bank`` is the filter bank that is to be configured.
- ``mode`` is the mode the filter should operate in.
- ``fifo`` is which fifo (0 or 1) a message should be stored in, if it is accepted by this filter.
- ``params`` is an array of values the defines the filter. The contents of the array depends on the ``mode`` argument.
+-----------+---------------------------------------------------------+
|*mode* |contents of *params* array |
|``mode`` |contents of parameter array |
+===========+=========================================================+
|CAN.LIST16 |Four 16 bit ids that will be accepted |
+-----------+---------------------------------------------------------+
@ -159,142 +106,49 @@ Methods
+-----------+---------------------------------------------------------+
|CAN.MASK32 |As with CAN.MASK16 but with only one 32 bit id/mask pair.|
+-----------+---------------------------------------------------------+
- *rtr* is an array of booleans that states if a filter should accept a
remote transmission request message. If this argument is not given
then it defaults to ``False`` for all entries. The length of the array
depends on the *mode* argument.
+-----------+----------------------+
|*mode* |length of *rtr* array |
+===========+======================+
|CAN.LIST16 |4 |
+-----------+----------------------+
|CAN.LIST32 |2 |
+-----------+----------------------+
|CAN.MASK16 |2 |
+-----------+----------------------+
|CAN.MASK32 |1 |
+-----------+----------------------+
.. method:: CAN.clearfilter(bank)
.. method:: can.clearfilter(bank)
Clear and disables a filter bank:
- ``bank`` is the filter bank that is to be cleared.
- *bank* is the filter bank that is to be cleared.
.. method:: CAN.any(fifo)
.. method:: can.any(fifo)
Return ``True`` if any message waiting on the FIFO, else ``False``.
.. method:: CAN.recv(fifo, list=None, \*, timeout=5000)
.. method:: can.recv(fifo, \*, timeout=5000)
Receive data on the bus:
- ``fifo`` is an integer, which is the FIFO to receive on
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: buffer of data bytes.
- *fifo* is an integer, which is the FIFO to receive on
- *list* is an optional list object to be used as the return value
- *timeout* is the timeout in milliseconds to wait for the receive.
Return value: A tuple containing four values.
- The id of the message.
- A boolean that indicates if the message is an RTR message.
- The FMI (Filter Match Index) value.
- An array containing the data.
If *list* is ``None`` then a new tuple will be allocated, as well as a new
bytes object to contain the data (as the fourth element in the tuple).
If *list* is not ``None`` then it should be a list object with a least four
elements. The fourth element should be a memoryview object which is created
from either a bytearray or an array of type 'B' or 'b', and this array must
have enough room for at least 8 bytes. The list object will then be
populated with the first three return values above, and the memoryview object
will be resized inplace to the size of the data and filled in with that data.
The same list and memoryview objects can be reused in subsequent calls to
this method, providing a way of receiving data without using the heap.
For example::
buf = bytearray(8)
lst = [0, 0, 0, memoryview(buf)]
# No heap memory is allocated in the following call
can.recv(0, lst)
.. method:: CAN.send(data, id, \*, timeout=0, rtr=False)
.. method:: can.send(send, addr, \*, timeout=5000)
Send a message on the bus:
- *data* is the data to send (an integer to send, or a buffer object).
- *id* is the id of the message to be sent.
- *timeout* is the timeout in milliseconds to wait for the send.
- *rtr* is a boolean that specifies if the message shall be sent as
a remote transmission request. If *rtr* is True then only the length
of *data* is used to fill in the DLC slot of the frame; the actual
bytes in *data* are unused.
If timeout is 0 the message is placed in a buffer in one of three hardware
buffers and the method returns immediately. If all three buffers are in use
an exception is thrown. If timeout is not 0, the method waits until the
message is transmitted. If the message can't be transmitted within the
specified time an exception is thrown.
- ``send`` is the data to send (an integer to send, or a buffer object).
- ``addr`` is the address to send to
- ``timeout`` is the timeout in milliseconds to wait for the send.
Return value: ``None``.
.. method:: CAN.rxcallback(fifo, fun)
Register a function to be called when a message is accepted into a empty fifo:
- *fifo* is the receiving fifo.
- *fun* is the function to be called when the fifo becomes non empty.
The callback function takes two arguments the first is the can object it self the second is
a integer that indicates the reason for the callback.
+--------+------------------------------------------------+
| Reason | |
+========+================================================+
| 0 | A message has been accepted into a empty FIFO. |
+--------+------------------------------------------------+
| 1 | The FIFO is full |
+--------+------------------------------------------------+
| 2 | A message has been lost due to a full FIFO |
+--------+------------------------------------------------+
Example use of rxcallback::
def cb0(bus, reason):
print('cb0')
if reason == 0:
print('pending')
if reason == 1:
print('full')
if reason == 2:
print('overflow')
can = CAN(1, CAN.LOOPBACK)
can.rxcallback(0, cb0)
Constants
---------
.. data:: CAN.NORMAL
CAN.LOOPBACK
CAN.SILENT
CAN.SILENT_LOOPBACK
.. data:: CAN.LOOPBACK
.. data:: CAN.SILENT
.. data:: CAN.SILENT_LOOPBACK
The mode of the CAN bus used in :meth:`~CAN.init()`.
.. data:: CAN.STOPPED
CAN.ERROR_ACTIVE
CAN.ERROR_WARNING
CAN.ERROR_PASSIVE
CAN.BUS_OFF
Possible states of the CAN controller returned from :meth:`~CAN.state()`.
the mode of the CAN bus
.. data:: CAN.LIST16
CAN.MASK16
CAN.LIST32
CAN.MASK32
.. data:: CAN.MASK16
.. data:: CAN.LIST32
.. data:: CAN.MASK32
The operation mode of a filter used in :meth:`~CAN.setfilter()`.
the operation mode of a filter

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.DAC:
class DAC -- digital to analog conversion
@ -16,9 +15,6 @@ Example usage::
dac = DAC(1) # create DAC 1 on pin X5
dac.write(128) # write a value to the DAC (makes X5 1.65V)
dac = DAC(1, bits=12) # use 12 bit resolution
dac.write(4095) # output maximum value, 3.3V
To output a continuous sine-wave::
import math
@ -27,98 +23,47 @@ To output a continuous sine-wave::
# create a buffer containing a sine-wave
buf = bytearray(100)
for i in range(len(buf)):
buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf)))
buf[i] = 128 + int(127 \* math.sin(2 \* math.pi \* i / len(buf)))
# output the sine-wave at 400Hz
dac = DAC(1)
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
dac.write_timed(buf, 400 \* len(buf), mode=DAC.CIRCULAR)
To output a continuous sine-wave at 12-bit resolution::
import math
from array import array
from pyb import DAC
# create a buffer containing a sine-wave, using half-word samples
buf = array('H', 2048 + int(2047 * math.sin(2 * math.pi * i / 128)) for i in range(128))
# output the sine-wave at 400Hz
dac = DAC(1, bits=12)
dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
Constructors
------------
.. class:: pyb.DAC(port, bits=8, \*, buffering=None)
.. class:: pyb.DAC(port)
Construct a new DAC object.
``port`` can be a pin object, or an integer (1 or 2).
DAC(1) is on pin X5 and DAC(2) is on pin X6.
``bits`` is an integer specifying the resolution, and can be 8 or 12.
The maximum value for the write and write_timed methods will be
2\*\*``bits``-1.
The *buffering* parameter selects the behaviour of the DAC op-amp output
buffer, whose purpose is to reduce the output impedance. It can be
``None`` to select the default (buffering enabled for :meth:`DAC.noise`,
:meth:`DAC.triangle` and :meth:`DAC.write_timed`, and disabled for
:meth:`DAC.write`), ``False`` to disable buffering completely, or ``True``
to enable output buffering.
When buffering is enabled the DAC pin can drive loads down to 5KΩ.
Otherwise it has an output impedance of 15KΩ maximum: consequently
to achieve a 1% accuracy without buffering requires the applied load
to be less than 1.5MΩ. Using the buffer incurs a penalty in accuracy,
especially near the extremes of range.
Methods
-------
.. method:: DAC.init(bits=8, \*, buffering=None)
Reinitialise the DAC. *bits* can be 8 or 12. *buffering* can be
``None``, ``False`` or ``True``; see above constructor for the meaning
of this parameter.
.. method:: DAC.deinit()
De-initialise the DAC making its pin available for other uses.
.. method:: DAC.noise(freq)
.. method:: dac.noise(freq)
Generate a pseudo-random noise signal. A new random sample is written
to the DAC output at the given frequency.
.. method:: DAC.triangle(freq)
.. method:: dac.triangle(freq)
Generate a triangle wave. The value on the DAC output changes at the given
frequency and ramps through the full 12-bit range (up and down). Therefore
the frequency of the repeating triangle wave itself is 8192 times smaller.
Generate a triangle wave. The value on the DAC output changes at
the given frequency, and the frequence of the repeating triangle wave
itself is 256 (or 1024, need to check) times smaller.
.. method:: DAC.write(value)
.. method:: dac.write(value)
Direct access to the DAC output. The minimum value is 0. The maximum
value is 2\*\*``bits``-1, where ``bits`` is set when creating the DAC
object or by using the ``init`` method.
Direct access to the DAC output (8 bit only at the moment).
.. method:: DAC.write_timed(data, freq, \*, mode=DAC.NORMAL)
.. method:: dac.write_timed(data, freq, \*, mode=DAC.NORMAL)
Initiates a burst of RAM to DAC using a DMA transfer.
The input data is treated as an array of bytes in 8-bit mode, and
an array of unsigned half-words (array typecode 'H') in 12-bit mode.
``freq`` can be an integer specifying the frequency to write the DAC
samples at, using Timer(6). Or it can be an already-initialised
Timer object which is used to trigger the DAC sample. Valid timers
are 2, 4, 5, 6, 7 and 8.
The input data is treated as an array of bytes (8 bit data).
``mode`` can be ``DAC.NORMAL`` or ``DAC.CIRCULAR``.
Example using both DACs at the same time::
dac1 = DAC(1)
dac2 = DAC(2)
dac1.write_timed(buf1, pyb.Timer(6, freq=100), mode=DAC.CIRCULAR)
dac2.write_timed(buf2, pyb.Timer(7, freq=200), mode=DAC.CIRCULAR)
TIM6 is used to control the frequency of the transfer.

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.ExtInt:
class ExtInt -- configure I/O pins to interrupt on external events
@ -7,7 +6,7 @@ class ExtInt -- configure I/O pins to interrupt on external events
There are a total of 22 interrupt lines. 16 of these can come from GPIO pins
and the remaining 6 are from internal sources.
For lines 0 through 15, a given line can map to the corresponding line from an
For lines 0 thru 15, a given line can map to the corresponding line from an
arbitrary port. So line 0 can map to Px0 where x is A, B, C, ... and
line 1 can map to Px1 where x is A, B, C, ... ::
@ -27,7 +26,7 @@ explanation, along with various techniques for debouncing.
Trying to register 2 callbacks onto the same pin will throw an exception.
If pin is passed as an integer, then it is assumed to map to one of the
internal interrupt sources, and must be in the range 16 through 22.
internal interrupt sources, and must be in the range 16 thru 22.
All other pin objects go through the pin mapper to come up with one of the
gpio pins. ::
@ -54,7 +53,7 @@ Constructors
.. class:: pyb.ExtInt(pin, mode, pull, callback)
Create an ExtInt object:
- ``pin`` is the pin on which to enable the interrupt (can be a pin object or any valid pin name).
- ``mode`` can be one of:
- ``ExtInt.IRQ_RISING`` - trigger on a rising edge;
@ -72,7 +71,7 @@ Constructors
Class methods
-------------
.. classmethod:: ExtInt.regs()
.. method:: ExtInt.regs()
Dump the values of the EXTI registers.
@ -80,20 +79,20 @@ Class methods
Methods
-------
.. method:: ExtInt.disable()
.. method:: extint.disable()
Disable the interrupt associated with the ExtInt object.
This could be useful for debouncing.
.. method:: ExtInt.enable()
.. method:: extint.enable()
Enable a disabled interrupt.
.. method:: ExtInt.line()
.. method:: extint.line()
Return the line number that the pin is mapped to.
.. method:: ExtInt.swint()
.. method:: extint.swint()
Trigger the callback from software.

View File

@ -1,52 +0,0 @@
.. currentmodule:: pyb
.. _pyb.Flash:
class Flash -- access to built-in flash storage
===============================================
The Flash class allows direct access to the primary flash device on the pyboard.
In most cases, to store persistent data on the device, you'll want to use a
higher-level abstraction, for example the filesystem via Python's standard file
API, but this interface is useful to :ref:`customise the filesystem
configuration <filesystem>` or implement a low-level storage system for your
application.
Constructors
------------
.. class:: pyb.Flash()
Create and return a block device that represents the flash device presented
to the USB mass storage interface.
It includes a virtual partition table at the start, and the actual flash
starts at block ``0x100``.
This constructor is deprecated and will be removed in a future version of MicroPython.
.. class:: pyb.Flash(\*, start=-1, len=-1)
Create and return a block device that accesses the flash at the specified offset. The length defaults to the remaining size of the device.
The *start* and *len* offsets are in bytes, and must be a multiple of the block size (typically 512 for internal flash).
Methods
-------
.. method:: Flash.readblocks(block_num, buf)
.. method:: Flash.readblocks(block_num, buf, offset)
.. method:: Flash.writeblocks(block_num, buf)
.. method:: Flash.writeblocks(block_num, buf, offset)
.. method:: Flash.ioctl(cmd, arg)
These methods implement the simple and :ref:`extended
<block-device-interface>` block protocol defined by
:class:`uos.AbstractBlockDev`.
Hardware Note
-------------
On boards with external spiflash (e.g. Pyboard D), the MicroPython firmware will
be configured to use that as the primary flash storage. On all other boards, the
internal flash inside the :term:`MCU` will be used.

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.I2C:
class I2C -- a two-wire serial protocol
@ -8,9 +7,7 @@ I2C is a two-wire protocol for communicating between devices. At the physical
level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
I2C objects are created attached to a specific bus. They can be initialised
when created, or initialised later on.
Example::
when created, or initialised later on::
from pyb import I2C
@ -22,7 +19,7 @@ Example::
Printing the i2c object gives you information about its configuration.
The basic methods are send and recv::
Basic methods for slave are send and recv::
i2c.send('abc') # send 3 bytes
i2c.send(0x42) # send a single byte, given by the number
@ -35,7 +32,7 @@ To receive inplace, first create a bytearray::
You can specify a timeout (in ms)::
i2c.send(b'123', timeout=2000) # timeout after 2 seconds
i2c.send(b'123', timeout=2000) # timout after 2 seconds
A master must specify the recipient's address::
@ -50,109 +47,100 @@ Master also has other methods::
# a list of valid addresses
i2c.mem_read(3, 0x42, 2) # read 3 bytes from memory of slave 0x42,
# starting at address 2 in the slave
i2c.mem_write('abc', 0x42, 2, timeout=1000) # write 'abc' (3 bytes) to memory of slave 0x42
# starting at address 2 in the slave, timeout after 1 second
i2c.mem_write('abc', 0x42, 2, timeout=1000)
Constructors
------------
.. class:: pyb.I2C(bus, ...)
Construct an I2C object on the given bus. ``bus`` can be 1 or 2, 'X' or
'Y'. With no additional parameters, the I2C object is created but not
Construct an I2C object on the given bus. ``bus`` can be 1 or 2.
With no additional parameters, the I2C object is created but not
initialised (it has the settings from the last initialisation of
the bus, if any). If extra arguments are given, the bus is initialised.
See ``init`` for parameters of initialisation.
The physical pins of the I2C busses on Pyboards V1.0 and V1.1 are:
The physical pins of the I2C busses are:
- ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)``
- ``I2C(2)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PB10, PB11)``
On the Pyboard Lite:
- ``I2C(1)`` is on the X position: ``(SCL, SDA) = (X9, X10) = (PB6, PB7)``
- ``I2C(3)`` is on the Y position: ``(SCL, SDA) = (Y9, Y10) = (PA8, PB8)``
Calling the constructor with 'X' or 'Y' enables portability between Pyboard
types.
Methods
-------
.. method:: I2C.deinit()
.. method:: i2c.deinit()
Turn off the I2C bus.
.. method:: I2C.init(mode, \*, addr=0x12, baudrate=400000, gencall=False, dma=False)
Initialise the I2C bus with the given parameters:
.. method:: i2c.init(mode, \*, addr=0x12, baudrate=400000, gencall=False)
Initialise the I2C bus with the given parameters:
- ``mode`` must be either ``I2C.MASTER`` or ``I2C.SLAVE``
- ``addr`` is the 7-bit address (only sensible for a slave)
- ``baudrate`` is the SCL clock rate (only sensible for a master)
- ``gencall`` is whether to support general call mode
- ``dma`` is whether to allow the use of DMA for the I2C transfers (note
that DMA transfers have more precise timing but currently do not handle bus
errors properly)
.. method:: I2C.is_ready(addr)
.. method:: i2c.is_ready(addr)
Check if an I2C device responds to the given address. Only valid when in master mode.
.. method:: I2C.mem_read(data, addr, memaddr, \*, timeout=5000, addr_size=8)
.. method:: i2c.mem_read(data, addr, memaddr, timeout=5000, addr_size=8)
Read from the memory of an I2C device:
- ``data`` can be an integer (number of bytes to read) or a buffer to read into
- ``addr`` is the I2C device address
- ``memaddr`` is the memory location within the I2C device
- ``timeout`` is the timeout in milliseconds to wait for the read
- ``addr_size`` selects width of memaddr: 8 or 16 bits
Returns the read data.
This is only valid in master mode.
.. method:: I2C.mem_write(data, addr, memaddr, \*, timeout=5000, addr_size=8)
.. method:: i2c.mem_write(data, addr, memaddr, timeout=5000, addr_size=8)
Write to the memory of an I2C device:
- ``data`` can be an integer or a buffer to write from
- ``addr`` is the I2C device address
- ``memaddr`` is the memory location within the I2C device
- ``timeout`` is the timeout in milliseconds to wait for the write
- ``addr_size`` selects width of memaddr: 8 or 16 bits
Returns ``None``.
This is only valid in master mode.
.. method:: I2C.recv(recv, addr=0x00, \*, timeout=5000)
.. method:: i2c.recv(recv, addr=0x00, timeout=5000)
Receive data on the bus:
- ``recv`` can be an integer, which is the number of bytes to receive,
or a mutable buffer, which will be filled with received bytes
- ``addr`` is the address to receive from (only required in master mode)
- ``timeout`` is the timeout in milliseconds to wait for the receive
Return value: if ``recv`` is an integer then a new buffer of the bytes received,
otherwise the same buffer that was passed in to ``recv``.
.. method:: I2C.send(send, addr=0x00, \*, timeout=5000)
Send data on the bus:
- ``send`` is the data to send (an integer to send, or a buffer object)
- ``addr`` is the address to send to (only required in master mode)
- ``timeout`` is the timeout in milliseconds to wait for the send
Return value: ``None``.
.. method:: I2C.scan()
.. method:: i2c.scan()
Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
Only valid when in master mode.
.. method:: i2c.send(send, addr=0x00, timeout=5000)
Send data on the bus:
- ``send`` is the data to send (an integer to send, or a buffer object)
- ``addr`` is the address to send to (only required in master mode)
- ``timeout`` is the timeout in milliseconds to wait for the send
Return value: ``None``.
Constants
---------

View File

@ -1,6 +1,3 @@
.. currentmodule:: pyb
.. _pyb.LCD:
class LCD -- LCD control for the LCD touch-sensor pyskin
========================================================
@ -50,48 +47,48 @@ Constructors
Methods
-------
.. method:: LCD.command(instr_data, buf)
.. method:: lcd.command(instr_data, buf)
Send an arbitrary command to the LCD. Pass 0 for ``instr_data`` to send an
instruction, otherwise pass 1 to send data. ``buf`` is a buffer with the
instructions/data to send.
.. method:: LCD.contrast(value)
.. method:: lcd.contrast(value)
Set the contrast of the LCD. Valid values are between 0 and 47.
.. method:: LCD.fill(colour)
.. method:: lcd.fill(colour)
Fill the screen with the given colour (0 or 1 for white or black).
This method writes to the hidden buffer. Use ``show()`` to show the buffer.
.. method:: LCD.get(x, y)
.. method:: lcd.get(x, y)
Get the pixel at the position ``(x, y)``. Returns 0 or 1.
This method reads from the visible buffer.
.. method:: LCD.light(value)
.. method:: lcd.light(value)
Turn the backlight on/off. True or 1 turns it on, False or 0 turns it off.
.. method:: LCD.pixel(x, y, colour)
.. method:: lcd.pixel(x, y, colour)
Set the pixel at ``(x, y)`` to the given colour (0 or 1).
This method writes to the hidden buffer. Use ``show()`` to show the buffer.
.. method:: LCD.show()
.. method:: lcd.show()
Show the hidden buffer on the screen.
.. method:: LCD.text(str, x, y, colour)
.. method:: lcd.text(str, x, y, colour)
Draw the given text to the position ``(x, y)`` using the given colour (0 or 1).
This method writes to the hidden buffer. Use ``show()`` to show the buffer.
.. method:: LCD.write(str)
.. method:: lcd.write(str)
Write the string ``str`` to the screen. It will appear immediately.

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.LED:
class LED -- LED object
@ -13,34 +12,28 @@ Constructors
.. class:: pyb.LED(id)
Create an LED object associated with the given LED:
- ``id`` is the LED number, 1-4.
Methods
-------
.. method:: LED.intensity([value])
.. method:: led.intensity([value])
Get or set the LED intensity. Intensity ranges between 0 (off) and 255 (full on).
If no argument is given, return the LED intensity.
If an argument is given, set the LED intensity and return ``None``.
*Note:* Only LED(3) and LED(4) can have a smoothly varying intensity, and
they use timer PWM to implement it. LED(3) uses Timer(2) and LED(4) uses
Timer(3). These timers are only configured for PWM if the intensity of the
relevant LED is set to a value between 1 and 254. Otherwise the timers are
free for general purpose use.
.. method:: LED.off()
.. method:: led.off()
Turn the LED off.
.. method:: LED.on()
.. method:: led.on()
Turn the LED on, to maximum intensity.
.. method:: LED.toggle()
.. method:: led.toggle()
Toggle the LED between on (maximum intensity) and off. If the LED is at
non-zero intensity then it is considered "on" and toggle will turn it off.

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.Pin:
class Pin -- control I/O pins
@ -6,20 +5,20 @@ class Pin -- control I/O pins
A pin is the basic object to control I/O pins. It has methods to set
the mode of the pin (input, output, etc) and methods to get and set the
digital logic level. For analog control of a pin, see the ADC class.
digital logic level. For analog control of a pin, see the ADC class.
Usage Model:
All Board Pins are predefined as pyb.Pin.board.Name::
All Board Pins are predefined as pyb.Pin.board.Name ::
x1_pin = pyb.Pin.board.X1
g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN)
CPU pins which correspond to the board pins are available
as ``pyb.Pin.cpu.Name``. For the CPU pins, the names are the port letter
as ``pyb.cpu.Name``. For the CPU pins, the names are the port letter
followed by the pin number. On the PYBv1.0, ``pyb.Pin.board.X1`` and
``pyb.Pin.cpu.A0`` are the same pin.
``pyb.Pin.cpu.B6`` are the same pin.
You can also use strings::
@ -31,7 +30,7 @@ Users can add their own names::
pyb.Pin.dict(MyMapperDict)
g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)
and can query mappings::
and can query mappings ::
pin = pyb.Pin("LeftMotorDir")
@ -62,15 +61,6 @@ When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled,
that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND
respectively (except pin Y5 which has 11k Ohm resistors).
Now every time a falling edge is seen on the gpio pin, the callback will be
executed. Caution: mechanical push buttons have "bounce" and pushing or
releasing a switch will often generate multiple edges.
See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
explanation, along with various techniques for debouncing.
All pin objects go through the pin mapper to come up with one of the
gpio pins.
Constructors
------------
@ -79,18 +69,23 @@ Constructors
Create a new Pin object associated with the id. If additional arguments are given,
they are used to initialise the pin. See :meth:`pin.init`.
Class methods
-------------
.. classmethod:: Pin.debug([state])
.. method:: Pin.af_list()
Returns an array of alternate functions available for this pin.
.. method:: Pin.debug([state])
Get or set the debugging state (``True`` or ``False`` for on or off).
.. classmethod:: Pin.dict([dict])
.. method:: Pin.dict([dict])
Get or set the pin mapper dictionary.
.. classmethod:: Pin.mapper([fun])
.. method:: Pin.mapper([fun])
Get or set the pin mapper function.
@ -98,31 +93,35 @@ Class methods
Methods
-------
.. method:: Pin.init(mode, pull=Pin.PULL_NONE, af=-1)
.. method:: pin.init(mode, pull=Pin.PULL_NONE, af=-1)
Initialise the pin:
- ``mode`` can be one of:
- ``Pin.IN`` - configure the pin for input;
- ``Pin.OUT_PP`` - configure the pin for output, with push-pull control;
- ``Pin.OUT_OD`` - configure the pin for output, with open-drain control;
- ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull;
- ``Pin.AF_OD`` - configure the pin for alternate function, open-drain;
- ``Pin.ANALOG`` - configure the pin for analog.
- ``Pin.IN`` - configure the pin for input;
- ``Pin.OUT_PP`` - configure the pin for output, with push-pull control;
- ``Pin.OUT_OD`` - configure the pin for output, with open-drain control;
- ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull;
- ``Pin.AF_OD`` - configure the pin for alternate function, open-drain;
- ``Pin.ANALOG`` - configure the pin for analog.
- ``pull`` can be one of:
- ``Pin.PULL_NONE`` - no pull up or down resistors;
- ``Pin.PULL_UP`` - enable the pull-up resistor;
- ``Pin.PULL_DOWN`` - enable the pull-down resistor.
- when mode is ``Pin.AF_PP`` or ``Pin.AF_OD``, then af can be the index or name
- ``Pin.PULL_NONE`` - no pull up or down resistors;
- ``Pin.PULL_UP`` - enable the pull-up resistor;
- ``Pin.PULL_DOWN`` - enable the pull-down resistor.
- when mode is Pin.AF_PP or Pin.AF_OD, then af can be the index or name
of one of the alternate functions associated with a pin.
Returns: ``None``.
.. method:: Pin.value([value])
.. method:: pin.high()
Set the pin to a high logic level.
.. method:: pin.low()
Set the pin to a low logic level.
.. method:: pin.value([value])
Get or set the digital logic level of the pin:
@ -131,51 +130,48 @@ Methods
anything that converts to a boolean. If it converts to ``True``, the pin
is set high, otherwise it is set low.
.. method:: Pin.__str__()
.. method:: pin.__str__()
Return a string describing the pin object.
.. method:: Pin.af()
.. method:: pin.af()
Returns the currently configured alternate-function of the pin. The
integer returned will match one of the allowed constants for the af
argument to the init function.
.. method:: Pin.af_list()
Returns an array of alternate functions available for this pin.
.. method:: Pin.gpio()
.. method:: pin.gpio()
Returns the base address of the GPIO block associated with this pin.
.. method:: Pin.mode()
.. method:: pin.mode()
Returns the currently configured mode of the pin. The integer returned
will match one of the allowed constants for the mode argument to the init
function.
.. method:: Pin.name()
.. method:: pin.name()
Get the pin name.
.. method:: Pin.names()
.. method:: pin.names()
Returns the cpu and board names for this pin.
.. method:: Pin.pin()
.. method:: pin.pin()
Get the pin number.
.. method:: Pin.port()
.. method:: pin.port()
Get the pin port.
.. method:: Pin.pull()
.. method:: pin.pull()
Returns the currently configured pull of the pin. The integer returned
will match one of the allowed constants for the pull argument to the init
function.
Returns the currently configured pull of the pin. The integer returned
will match one of the allowed constants for the pull argument to the init
function.
Constants
---------
@ -216,10 +212,11 @@ Constants
enable the pull-up resistor on the pin
class PinAF -- Pin Alternate Functions
======================================
A Pin represents a physical pin on the microprocessor. Each pin
A Pin represents a physical pin on the microcprocessor. Each pin
can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF
object represents a particular function for a pin.
@ -228,7 +225,7 @@ Usage Model::
x3 = pyb.Pin.board.X3
x3_af = x3.af_list()
x3_af will now contain an array of PinAF objects which are available on
x3_af will now contain an array of PinAF objects which are availble on
pin X3.
For the pyboard, x3_af would contain:
@ -246,6 +243,7 @@ or::
pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=1)
Methods
-------

View File

@ -1,6 +1,3 @@
.. currentmodule:: pyb
.. _pyb.RTC:
class RTC -- real time clock
============================
@ -25,54 +22,27 @@ Constructors
Methods
-------
.. method:: RTC.datetime([datetimetuple])
.. method:: rtc.datetime([datetimetuple])
Get or set the date and time of the RTC.
With no arguments, this method returns an 8-tuple with the current
date and time. With 1 argument (being an 8-tuple) it sets the date
and time (and ``subseconds`` is reset to 255).
and time.
The 8-tuple has the following format:
(year, month, day, weekday, hours, minutes, seconds, subseconds)
``weekday`` is 1-7 for Monday through Sunday.
``subseconds`` counts down from 255 to 0
.. method:: RTC.wakeup(timeout, callback=None)
Set the RTC wakeup timer to trigger repeatedly at every ``timeout``
milliseconds. This trigger can wake the pyboard from both the sleep
states: :meth:`pyb.stop` and :meth:`pyb.standby`.
If ``timeout`` is ``None`` then the wakeup timer is disabled.
If ``callback`` is given then it is executed at every trigger of the
wakeup timer. ``callback`` must take exactly one argument.
.. method:: RTC.info()
.. method:: rtc.info()
Get information about the startup time and reset source.
- The lower 0xffff are the number of milliseconds the RTC took to
start up.
- Bit 0x10000 is set if a power-on reset occurred.
- Bit 0x20000 is set if an external reset occurred
.. method:: RTC.calibration(cal)
Get or set RTC calibration.
With no arguments, ``calibration()`` returns the current calibration
value, which is an integer in the range [-511 : 512]. With one
argument it sets the RTC calibration.
The RTC Smooth Calibration mechanism adjusts the RTC clock rate by
adding or subtracting the given number of ticks from the 32768 Hz
clock over a 32 second period (corresponding to 2^20 clock ticks.)
Each tick added will speed up the clock by 1 part in 2^20, or 0.954
ppm; likewise the RTC clock it slowed by negative values. The
usable calibration range is:
(-511 * 0.954) ~= -487.5 ppm up to (512 * 0.954) ~= 488.5 ppm

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.SPI:
class SPI -- a master-driven serial protocol
@ -18,43 +17,45 @@ Only required parameter is mode, SPI.MASTER or SPI.SLAVE. Polarity can be
to sample data on the first or second clock edge respectively. Crc can be
None for no CRC, or a polynomial specifier.
Additional methods for SPI::
Additional method for SPI::
data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes
buf = bytearray(4)
spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf
spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf
Constructors
------------
.. class:: pyb.SPI(bus, ...)
Construct an SPI object on the given bus. ``bus`` can be 1 or 2, or
'X' or 'Y'. With no additional parameters, the SPI object is created but
not initialised (it has the settings from the last initialisation of
Construct an SPI object on the given bus. ``bus`` can be 1 or 2.
With no additional parameters, the SPI object is created but not
initialised (it has the settings from the last initialisation of
the bus, if any). If extra arguments are given, the bus is initialised.
See ``init`` for parameters of initialisation.
The physical pins of the SPI busses are:
- ``SPI(1)`` is on the X position: ``(NSS, SCK, MISO, MOSI) = (X5, X6, X7, X8) = (PA4, PA5, PA6, PA7)``
- ``SPI(2)`` is on the Y position: ``(NSS, SCK, MISO, MOSI) = (Y5, Y6, Y7, Y8) = (PB12, PB13, PB14, PB15)``
At the moment, the NSS pin is not used by the SPI driver and is free
for other use.
Methods
-------
.. method:: SPI.deinit()
.. method:: spi.deinit()
Turn off the SPI bus.
.. method:: SPI.init(mode, baudrate=328125, \*, prescaler, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
.. method:: spi.init(mode, baudrate=328125, \*, prescaler, polarity=1, phase=0, bits=8, firstbit=SPI.MSB, ti=False, crc=None)
Initialise the SPI bus with the given parameters:
- ``mode`` must be either ``SPI.MASTER`` or ``SPI.SLAVE``.
- ``baudrate`` is the SCK clock rate (only sensible for a master).
- ``prescaler`` is the prescaler to use to derive SCK from the APB bus frequency;
@ -62,7 +63,6 @@ Methods
- ``polarity`` can be 0 or 1, and is the level the idle clock line sits at.
- ``phase`` can be 0 or 1 to sample data on the first or second clock edge
respectively.
- ``bits`` can be 8 or 16, and is the number of bits in each transferred word.
- ``firstbit`` can be ``SPI.MSB`` or ``SPI.LSB``.
- ``crc`` can be None for no CRC, or a polynomial specifier.
@ -76,38 +76,39 @@ Methods
Printing the SPI object will show you the computed baudrate and the chosen
prescaler.
.. method:: SPI.recv(recv, \*, timeout=5000)
.. method:: spi.recv(recv, \*, timeout=5000)
Receive data on the bus:
- ``recv`` can be an integer, which is the number of bytes to receive,
or a mutable buffer, which will be filled with received bytes.
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: if ``recv`` is an integer then a new buffer of the bytes received,
otherwise the same buffer that was passed in to ``recv``.
.. method:: SPI.send(send, \*, timeout=5000)
.. method:: spi.send(send, \*, timeout=5000)
Send data on the bus:
- ``send`` is the data to send (an integer to send, or a buffer object).
- ``timeout`` is the timeout in milliseconds to wait for the send.
Return value: ``None``.
.. method:: SPI.send_recv(send, recv=None, \*, timeout=5000)
.. method:: spi.send_recv(send, recv=None, \*, timeout=5000)
Send and receive data on the bus at the same time:
- ``send`` is the data to send (an integer to send, or a buffer object).
- ``recv`` is a mutable buffer which will be filled with received bytes.
It can be the same as ``send``, or omitted. If omitted, a new buffer will
be created.
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: the buffer with the received bytes.
Constants
---------

View File

@ -1,80 +1,38 @@
.. currentmodule:: pyb
.. _pyb.Servo:
class Servo -- 3-wire hobby servo driver
========================================
Servo objects control standard hobby servo motors with 3-wires (ground, power,
signal). There are 4 positions on the pyboard where these motors can be plugged
in: pins X1 through X4 are the signal pins, and next to them are 4 sets of power
and ground pins.
Servo controls standard hobby servos with 3-wires (ground, power, signal).
Example usage::
import pyb
s1 = pyb.Servo(1) # create a servo object on position X1
s2 = pyb.Servo(2) # create a servo object on position X2
s1.angle(45) # move servo 1 to 45 degrees
s2.angle(0) # move servo 2 to 0 degrees
# move servo1 and servo2 synchronously, taking 1500ms
s1.angle(-60, 1500)
s2.angle(30, 1500)
.. note:: The Servo objects use Timer(5) to produce the PWM output. You can
use Timer(5) for Servo control, or your own purposes, but not both at the
same time.
Constructors
------------
.. class:: pyb.Servo(id)
Create a servo object. ``id`` is 1-4, and corresponds to pins X1 through X4.
Create a servo object. ``id`` is 1-4.
Methods
-------
.. method:: Servo.angle([angle, time=0])
If no arguments are given, this function returns the current angle.
If arguments are given, this function sets the angle of the servo:
.. method:: servo.angle([angle, time=0])
Get or set the angle of the servo.
- ``angle`` is the angle to move to in degrees.
- ``time`` is the number of milliseconds to take to get to the specified
angle. If omitted, then the servo moves as quickly as possible to its
new position.
- ``time`` is the number of milliseconds to take to get to the specified angle.
.. method:: Servo.speed([speed, time=0])
.. method:: servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]])
If no arguments are given, this function returns the current speed.
Get or set the calibration of the servo timing.
If arguments are given, this function sets the speed of the servo:
.. method:: servo.pulse_width([value])
- ``speed`` is the speed to change to, between -100 and 100.
- ``time`` is the number of milliseconds to take to get to the specified
speed. If omitted, then the servo accelerates as quickly as possible.
Get or set the pulse width in milliseconds.
.. method:: Servo.pulse_width([value])
.. method:: servo.speed([speed, time=0])
If no arguments are given, this function returns the current raw pulse-width
value.
If an argument is given, this function sets the raw pulse-width value.
.. method:: Servo.calibration([pulse_min, pulse_max, pulse_centre, [pulse_angle_90, pulse_speed_100]])
If no arguments are given, this function returns the current calibration
data, as a 5-tuple.
If arguments are given, this function sets the timing calibration:
- ``pulse_min`` is the minimum allowed pulse width.
- ``pulse_max`` is the maximum allowed pulse width.
- ``pulse_centre`` is the pulse width corresponding to the centre/zero position.
- ``pulse_angle_90`` is the pulse width corresponding to 90 degrees.
- ``pulse_speed_100`` is the pulse width corresponding to a speed of 100.
Get or set the speed of a continuous rotation servo.
- ``speed`` is the speed to move to change to, between -100 and 100.
- ``time`` is the number of milliseconds to take to get to the specified speed.

View File

@ -1,6 +1,3 @@
.. currentmodule:: pyb
.. _pyb.Switch:
class Switch -- switch object
=============================
@ -9,8 +6,7 @@ A Switch object is used to control a push-button switch.
Usage::
sw = pyb.Switch() # create a switch object
sw.value() # get state (True if pressed, False otherwise)
sw() # shorthand notation to get the switch state
sw() # get state (True if pressed, False otherwise)
sw.callback(f) # register a callback to be called when the
# switch is pressed down
sw.callback(None) # remove the callback
@ -31,16 +27,11 @@ Constructors
Methods
-------
.. method:: Switch.__call__()
.. method:: switch()
Call switch object directly to get its state: ``True`` if pressed down,
``False`` otherwise.
Return the switch state: ``True`` if pressed down, ``False`` otherwise.
.. method:: Switch.value()
Get the switch state. Returns ``True`` if pressed down, otherwise ``False``.
.. method:: Switch.callback(fun)
.. method:: switch.callback(fun)
Register the given function to be called when the switch is pressed down.
If ``fun`` is ``None``, then it disables the callback.

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.Timer:
class Timer -- control internal timers
@ -19,13 +18,6 @@ Example usage to toggle an LED at a fixed frequency::
tim.init(freq=2) # trigger at 2Hz
tim.callback(lambda t:pyb.LED(1).toggle())
Example using named function for the callback::
def tick(timer): # we will receive the timer object when being called
print(timer.counter()) # show current timer's counter value
tim = pyb.Timer(4, freq=1) # create a timer object using timer 4 - trigger at 1Hz
tim.callback(tick) # set the callback to our tick function
Further examples::
tim = pyb.Timer(4, freq=100) # freq in Hz
@ -36,18 +28,9 @@ Further examples::
tim.callback(lambda t: ...) # set callback for update interrupt (t=tim instance)
tim.callback(None) # clear callback
*Note:* Timer(2) and Timer(3) are used for PWM to set the intensity of LED(3)
and LED(4) respectively. But these timers are only configured for PWM if
the intensity of the relevant LED is set to a value between 1 and 254. If
the intensity feature of the LEDs is not used then these timers are free for
general purpose use. Similarly, Timer(5) controls the servo driver, and
Timer(6) is used for timed ADC/DAC reading/writing. It is recommended to
use the other timers in your programs.
*Note:* Memory can't be allocated during a callback (an interrupt) and so
exceptions raised within a callback don't give much information. See
:func:`micropython.alloc_emergency_exception_buf` for how to get around this
limitation.
*Note:* Timer 3 is reserved for internal use. Timer 5 controls
the servo driver, and Timer 6 is used for timed ADC/DAC reading/writing.
It is recommended to use the other timers in your programs.
Constructors
@ -57,86 +40,31 @@ Constructors
Construct a new timer object of the given id. If additional
arguments are given, then the timer is initialised by ``init(...)``.
``id`` can be 1 to 14.
``id`` can be 1 to 14, excluding 3.
Methods
-------
.. method:: Timer.init(\*, freq, prescaler, period)
Initialise the timer. Initialisation must be either by frequency (in Hz)
or by prescaler and period::
tim.init(freq=100) # set the timer to trigger at 100Hz
tim.init(prescaler=83, period=999) # set the prescaler and period directly
Keyword arguments:
- ``freq`` --- specifies the periodic frequency of the timer. You might also
view this as the frequency with which the timer goes through one complete cycle.
- ``prescaler`` [0-0xffff] - specifies the value to be loaded into the
timer's Prescaler Register (PSC). The timer clock source is divided by
(``prescaler + 1``) to arrive at the timer clock. Timers 2-7 and 12-14
have a clock source of 84 MHz (pyb.freq()[2] \* 2), and Timers 1, and 8-11
have a clock source of 168 MHz (pyb.freq()[3] \* 2).
- ``period`` [0-0xffff] for timers 1, 3, 4, and 6-15. [0-0x3fffffff] for timers 2 & 5.
Specifies the value to be loaded into the timer's AutoReload
Register (ARR). This determines the period of the timer (i.e. when the
counter cycles). The timer counter will roll-over after ``period + 1``
timer clock cycles.
- ``mode`` can be one of:
- ``Timer.UP`` - configures the timer to count from 0 to ARR (default)
- ``Timer.DOWN`` - configures the timer to count from ARR down to 0.
- ``Timer.CENTER`` - configures the timer to count from 0 to ARR and
then back down to 0.
- ``div`` can be one of 1, 2, or 4. Divides the timer clock to determine
the sampling clock used by the digital filters.
- ``callback`` - as per Timer.callback()
- ``deadtime`` - specifies the amount of "dead" or inactive time between
transitions on complimentary channels (both channels will be inactive)
for this time). ``deadtime`` may be an integer between 0 and 1008, with
the following restrictions: 0-128 in steps of 1. 128-256 in steps of
2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadtime``
measures ticks of ``source_freq`` divided by ``div`` clock ticks.
``deadtime`` is only available on timers 1 and 8.
You must either specify freq or both of period and prescaler.
.. method:: Timer.deinit()
Deinitialises the timer.
Disables the callback (and the associated irq).
Disables any channel callbacks (and the associated irq).
Stops the timer, and disables the timer peripheral.
.. method:: Timer.callback(fun)
.. method:: timer.callback(fun)
Set the function to be called when the timer triggers.
``fun`` is passed 1 argument, the timer object.
If ``fun`` is ``None`` then the callback will be disabled.
.. method:: Timer.channel(channel, mode, ...)
.. method:: timer.channel(channel, mode, ...)
If only a channel number is passed, then a previously initialized channel
object is returned (or ``None`` if there is no previous channel).
Otherwise, a TimerChannel object is initialized and returned.
Othwerwise, a TimerChannel object is initialized and returned.
Each channel can be configured to perform pwm, output compare, or
input capture. All channels share the same underlying timer, which means
that they share the same timer clock.
Keyword arguments:
- ``mode`` can be one of:
- ``Timer.PWM`` --- configure the timer in PWM mode (active high).
@ -148,73 +76,115 @@ Methods
- ``Timer.OC_FORCED_ACTIVE`` --- the pin is forced active (compare match is ignored).
- ``Timer.OC_FORCED_INACTIVE`` --- the pin is forced inactive (compare match is ignored).
- ``Timer.IC`` --- configure the timer in Input Capture mode.
- ``Timer.ENC_A`` --- configure the timer in Encoder mode. The counter only changes when CH1 changes.
- ``Timer.ENC_B`` --- configure the timer in Encoder mode. The counter only changes when CH2 changes.
- ``Timer.ENC_AB`` --- configure the timer in Encoder mode. The counter changes when CH1 or CH2 changes.
- ``callback`` - as per TimerChannel.callback()
- ``pin`` None (the default) or a Pin object. If specified (and not None)
this will cause the alternate function of the the indicated pin
to be configured for this timer channel. An error will be raised if
the pin doesn't support any alternate functions for this timer channel.
Keyword arguments for Timer.PWM modes:
- ``pulse_width`` - determines the initial pulse width value to use.
- ``pulse_width_percent`` - determines the initial pulse width percentage to use.
Keyword arguments for Timer.OC modes:
- ``compare`` - determines the initial value of the compare register.
- ``polarity`` can be one of:
- ``Timer.HIGH`` - output is active high
- ``Timer.LOW`` - output is active low
- ``Timer.LOW`` - output is acive low
Optional keyword arguments for Timer.IC modes:
- ``polarity`` can be one of:
- ``Timer.RISING`` - captures on rising edge.
- ``Timer.FALLING`` - captures on falling edge.
- ``Timer.BOTH`` - captures on both edges.
Note that capture only works on the primary channel, and not on the
complimentary channels.
Notes for Timer.ENC modes:
- Requires 2 pins, so one or both pins will need to be configured to use
the appropriate timer AF using the Pin API.
- Read the encoder value using the timer.counter() method.
- Only works on CH1 and CH2 (and not on CH1N or CH2N)
- The channel number is ignored when setting the encoder mode.
PWM Example::
timer = pyb.Timer(2, freq=1000)
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=8000)
ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=16000)
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=210000)
ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=420000)
.. method:: Timer.counter([value])
.. method:: timer.counter([value])
Get or set the timer counter.
.. method:: Timer.freq([value])
.. method:: timer.deinit()
Deinitialises the timer.
Disables the callback (and the associated irq).
Disables any channel callbacks (and the associated irq).
Stops the timer, and disables the timer peripheral.
.. method:: timer.freq([value])
Get or set the frequency for the timer (changes prescaler and period if set).
.. method:: Timer.period([value])
.. method:: timer.init(\*, freq, prescaler, period)
Initialise the timer. Initialisation must be either by frequency (in Hz)
or by prescaler and period::
tim.init(freq=100) # set the timer to trigger at 100Hz
tim.init(prescaler=83, period=999) # set the prescaler and period directly
Keyword arguments:
- ``freq`` --- specifies the periodic frequency of the timer. You migh also
view this as the frequency with which the timer goes through one complete cycle.
- ``prescaler`` [0-0xffff] - specifies the value to be loaded into the
timer's Prescaler Register (PSC). The timer clock source is divided by
(``prescaler + 1``) to arrive at the timer clock. Timers 2-7 and 12-14
have a clock source of 84 MHz (pyb.freq()[2] \* 2), and Timers 1, and 8-11
have a clock source of 168 MHz (pyb.freq()[3] \* 2).
- ``period`` [0-0xffff] for timers 1, 3, 4, and 6-15. [0-0x3fffffff] for timers 2 & 5.
Specifies the value to be loaded into the timer's AutoReload
Register (ARR). This determines the period of the timer (i.e. when the
counter cycles). The timer counter will roll-over after ``period + 1``
timer clock cycles.
- ``mode`` can be one of:
- ``Timer.UP`` - configures the timer to count from 0 to ARR (default)
- ``Timer.DOWN`` - configures the timer to count from ARR down to 0.
- ``Timer.CENTER`` - confgures the timer to count from 0 to ARR and
then back down to 0.
- ``div`` can be one of 1, 2, or 4. Divides the timer clock to determine
the sampling clock used by the digital filters.
- ``callback`` - as per Timer.callback()
- ``deadtime`` - specifies the amount of "dead" or inactive time between
transitions on complimentary channels (both channels will be inactive)
for this time). ``deadtime`` may be an integer between 0 and 1008, with
the following restrictions: 0-128 in steps of 1. 128-256 in steps of
2, 256-512 in steps of 8, and 512-1008 in steps of 16. ``deadime``
measures ticks of ``source_freq`` divided by ``div`` clock ticks.
``deadtime`` is only available on timers 1 and 8.
You must either specify freq or both of period and prescaler.
.. method:: timer.period([value])
Get or set the period of the timer.
.. method:: Timer.prescaler([value])
.. method:: timer.prescaler([value])
Get or set the prescaler for the timer.
.. method:: Timer.source_freq()
.. method:: timer.source_freq()
Get the frequency of the source of the timer.
@ -251,7 +221,7 @@ Methods
Get or set the pulse width value associated with a channel.
capture, compare, and pulse_width are all aliases for the same function.
pulse_width is the logical name to use when the channel is in PWM mode.
In edge aligned mode, a pulse_width of ``period + 1`` corresponds to a duty cycle of 100%
In center aligned mode, a pulse width of ``period`` corresponds to a duty cycle of 100%

View File

@ -1,4 +1,3 @@
.. currentmodule:: pyb
.. _pyb.UART:
class UART -- duplex serial communication bus
@ -21,11 +20,11 @@ Bits can be 7, 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
only 7 and 8 bits are supported.
A UART object acts like a `stream` object and reading and writing is done
A UART object acts like a stream object and reading and writing is done
using the standard stream methods::
uart.read(10) # read 10 characters, returns a bytes object
uart.read() # read all available characters
uart.readall() # read all available characters
uart.readline() # read a line
uart.readinto(buf) # read and store into the given buffer
uart.write('abc') # write the 3 characters
@ -37,10 +36,9 @@ Individual characters can be read/written using::
To check if there is anything to be read, use::
uart.any() # returns the number of characters waiting
uart.any() # returns True if any characters waiting
*Note:* The stream functions ``read``, ``write``, etc. are new in MicroPython v1.3.4.
*Note:* The stream functions ``read``, ``write`` etc Are new in Micro Python since v1.3.4.
Earlier versions use ``uart.send`` and ``uart.recv``.
Constructors
@ -62,14 +60,10 @@ Constructors
- ``UART(3)`` is on ``YB``: ``(TX, RX) = (Y9, Y10) = (PB10, PB11)``
- ``UART(2)`` is on: ``(TX, RX) = (X3, X4) = (PA2, PA3)``
The Pyboard Lite supports UART(1), UART(2) and UART(6) only. Pins are as above except:
- ``UART(2)`` is on: ``(TX, RX) = (X1, X2) = (PA2, PA3)``
Methods
-------
.. method:: UART.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=0, flow=0, timeout_char=0, read_buf_len=64)
.. method:: uart.init(baudrate, bits=8, parity=None, stop=1, \*, timeout=1000, timeout_char=0, read_buf_len=64)
Initialise the UART bus with the given parameters:
@ -77,149 +71,66 @@ Methods
- ``bits`` is the number of bits per character, 7, 8 or 9.
- ``parity`` is the parity, ``None``, 0 (even) or 1 (odd).
- ``stop`` is the number of stop bits, 1 or 2.
- ``flow`` sets the flow control type. Can be 0, ``UART.RTS``, ``UART.CTS``
or ``UART.RTS | UART.CTS``.
- ``timeout`` is the timeout in milliseconds to wait for writing/reading the first character.
- ``timeout_char`` is the timeout in milliseconds to wait between characters while writing or reading.
- ``timeout`` is the timeout in milliseconds to wait for the first character.
- ``timeout_char`` is the timeout in milliseconds to wait between characters.
- ``read_buf_len`` is the character length of the read buffer (0 to disable).
This method will raise an exception if the baudrate could not be set within
5% of the desired value. The minimum baudrate is dictated by the frequency
of the bus that the UART is on; UART(1) and UART(6) are APB2, the rest are on
APB1. The default bus frequencies give a minimum baudrate of 1300 for
UART(1) and UART(6) and 650 for the others. Use :func:`pyb.freq <pyb.freq>`
to reduce the bus frequencies to get lower baudrates.
*Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled,
only 7 and 8 bits are supported.
.. method:: UART.deinit()
.. method:: uart.deinit()
Turn off the UART bus.
.. method:: UART.any()
.. method:: uart.any()
Returns the number of bytes waiting (may be 0).
Return ``True`` if any characters waiting, else ``False``.
.. method:: UART.read([nbytes])
.. method:: uart.read([nbytes])
Read characters. If ``nbytes`` is specified then read at most that many bytes.
If ``nbytes`` are available in the buffer, returns immediately, otherwise returns
when sufficient characters arrive or the timeout elapses.
If ``nbytes`` is not given then the method reads as much data as possible. It
returns after the timeout has elapsed.
*Note:* for 9 bit characters each character takes two bytes, ``nbytes`` must
be even, and the number of characters is ``nbytes/2``.
Return value: a bytes object containing the bytes read in. Returns ``None``
Return value: a bytes object containing the bytes read in. Returns ``b''``
on timeout.
.. method:: UART.readchar()
.. method:: uart.readall()
Read as much data as possible.
Return value: a bytes object.
.. method:: uart.readchar()
Receive a single character on the bus.
Return value: The character read, as an integer. Returns -1 on timeout.
.. method:: UART.readinto(buf[, nbytes])
.. method:: uart.readinto(buf[, nbytes])
Read bytes into the ``buf``. If ``nbytes`` is specified then read at most
that many bytes. Otherwise, read at most ``len(buf)`` bytes.
Return value: number of bytes read and stored into ``buf`` or ``None`` on
timeout.
Return value: number of bytes read and stored into ``buf``.
.. method:: UART.readline()
.. method:: uart.readline()
Read a line, ending in a newline character. If such a line exists, return is
immediate. If the timeout elapses, all available data is returned regardless
of whether a newline exists.
Read a line, ending in a newline character.
Return value: the line read or ``None`` on timeout if no data is available.
Return value: the line read.
.. method:: UART.write(buf)
.. method:: uart.write(buf)
Write the buffer of bytes to the bus. If characters are 7 or 8 bits wide
then each byte is one character. If characters are 9 bits wide then two
bytes are used for each character (little endian), and ``buf`` must contain
an even number of bytes.
Return value: number of bytes written. If a timeout occurs and no bytes
were written returns ``None``.
Return value: number of bytes written.
.. method:: UART.writechar(char)
.. method:: uart.writechar(char)
Write a single character on the bus. ``char`` is an integer to write.
Return value: ``None``. See note below if CTS flow control is used.
.. method:: UART.sendbreak()
Send a break condition on the bus. This drives the bus low for a duration
of 13 bits.
Return value: ``None``.
Constants
---------
.. data:: UART.RTS
UART.CTS
to select the flow control type.
Flow Control
------------
On Pyboards V1 and V1.1 ``UART(2)`` and ``UART(3)`` support RTS/CTS hardware flow control
using the following pins:
- ``UART(2)`` is on: ``(TX, RX, nRTS, nCTS) = (X3, X4, X2, X1) = (PA2, PA3, PA1, PA0)``
- ``UART(3)`` is on :``(TX, RX, nRTS, nCTS) = (Y9, Y10, Y7, Y6) = (PB10, PB11, PB14, PB13)``
On the Pyboard Lite only ``UART(2)`` supports flow control on these pins:
``(TX, RX, nRTS, nCTS) = (X1, X2, X4, X3) = (PA2, PA3, PA1, PA0)``
In the following paragraphs the term "target" refers to the device connected to
the UART.
When the UART's ``init()`` method is called with ``flow`` set to one or both of
``UART.RTS`` and ``UART.CTS`` the relevant flow control pins are configured.
``nRTS`` is an active low output, ``nCTS`` is an active low input with pullup
enabled. To achieve flow control the Pyboard's ``nCTS`` signal should be connected
to the target's ``nRTS`` and the Pyboard's ``nRTS`` to the target's ``nCTS``.
CTS: target controls Pyboard transmitter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If CTS flow control is enabled the write behaviour is as follows:
If the Pyboard's ``UART.write(buf)`` method is called, transmission will stall for
any periods when ``nCTS`` is ``False``. This will result in a timeout if the entire
buffer was not transmitted in the timeout period. The method returns the number of
bytes written, enabling the user to write the remainder of the data if required. In
the event of a timeout, a character will remain in the UART pending ``nCTS``. The
number of bytes composing this character will be included in the return value.
If ``UART.writechar()`` is called when ``nCTS`` is ``False`` the method will time
out unless the target asserts ``nCTS`` in time. If it times out ``OSError 116``
will be raised. The character will be transmitted as soon as the target asserts ``nCTS``.
RTS: Pyboard controls target's transmitter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If RTS flow control is enabled, behaviour is as follows:
If buffered input is used (``read_buf_len`` > 0), incoming characters are buffered.
If the buffer becomes full, the next character to arrive will cause ``nRTS`` to go
``False``: the target should cease transmission. ``nRTS`` will go ``True`` when
characters are read from the buffer.
Note that the ``any()`` method returns the number of bytes in the buffer. Assume a
buffer length of ``N`` bytes. If the buffer becomes full, and another character arrives,
``nRTS`` will be set False, and ``any()`` will return the count ``N``. When
characters are read the additional character will be placed in the buffer and will
be included in the result of a subsequent ``any()`` call.
If buffered input is not used (``read_buf_len`` == 0) the arrival of a character will
cause ``nRTS`` to go ``False`` until the character is read.

View File

@ -1,40 +0,0 @@
.. currentmodule:: pyb
.. _pyb.USB_HID:
class USB_HID -- USB Human Interface Device (HID)
=================================================
The USB_HID class allows creation of an object representing the USB
Human Interface Device (HID) interface. It can be used to emulate
a peripheral such as a mouse or keyboard.
Before you can use this class, you need to use :meth:`pyb.usb_mode()` to set the USB mode to include the HID interface.
Constructors
------------
.. class:: pyb.USB_HID()
Create a new USB_HID object.
Methods
-------
.. method:: USB_HID.recv(data, \*, timeout=5000)
Receive data on the bus:
- ``data`` can be an integer, which is the number of bytes to receive,
or a mutable buffer, which will be filled with received bytes.
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: if ``data`` is an integer then a new buffer of the bytes received,
otherwise the number of bytes read into ``data`` is returned.
.. method:: USB_HID.send(data)
Send data over the USB HID interface:
- ``data`` is the data to send (a tuple/list of integers, or a
bytearray).

View File

@ -1,10 +1,7 @@
.. currentmodule:: pyb
.. _pyb.USB_VCP:
class USB_VCP -- USB virtual comm port
======================================
The USB_VCP class allows creation of a `stream`-like object representing the USB
The USB_VCP class allows creation of an object representing the USB
virtual comm port. It can be used to read and write data over USB to
the connected host.
@ -12,22 +9,15 @@ the connected host.
Constructors
------------
.. class:: pyb.USB_VCP(id=0)
.. class:: pyb.USB_VCP()
Create a new USB_VCP object. The *id* argument specifies which USB VCP port to
use.
Create a new USB_VCP object.
Methods
-------
.. method:: USB_VCP.init(\*, flow=-1)
Configure the USB VCP port. If the *flow* argument is not -1 then the value sets
the flow control, which can be a bitwise-or of ``USB_VCP.RTS`` and ``USB_VCP.CTS``.
RTS is used to control read behaviour and CTS, to control write behaviour.
.. method:: USB_VCP.setinterrupt(chr)
.. method:: usb_vcp.setinterrupt(chr)
Set the character which interrupts running Python code. This is set
to 3 (CTRL-C) by default, and when a CTRL-C character is received over
@ -36,84 +26,41 @@ Methods
Set to -1 to disable this interrupt feature. This is useful when you
want to send raw bytes over the USB VCP port.
.. method:: USB_VCP.isconnected()
Return ``True`` if USB is connected as a serial device, else ``False``.
.. method:: USB_VCP.any()
.. method:: usb_vcp.any()
Return ``True`` if any characters waiting, else ``False``.
.. method:: USB_VCP.close()
.. method:: usb_vcp.close()
This method does nothing. It exists so the USB_VCP object can act as
a file.
.. method:: USB_VCP.read([nbytes])
.. method:: usb_vcp.read([nbytes])
Read at most ``nbytes`` from the serial device and return them as a
bytes object. If ``nbytes`` is not specified then the method reads
all available bytes from the serial device.
USB_VCP `stream` implicitly works in non-blocking mode,
so if no pending data available, this method will return immediately
with ``None`` value.
.. method:: USB_VCP.readinto(buf, [maxlen])
.. method:: usb_vcp.readall()
Read bytes from the serial device and store them into ``buf``, which
should be a buffer-like object. At most ``len(buf)`` bytes are read.
If ``maxlen`` is given and then at most ``min(maxlen, len(buf))`` bytes
are read.
Returns the number of bytes read and stored into ``buf`` or ``None``
if no pending data available.
.. method:: usb_vcp.readline()
.. method:: USB_VCP.readline()
Read a whole line from the serial device.
Returns a bytes object containing the data, including the trailing
newline character or ``None`` if no pending data available.
.. method:: USB_VCP.readlines()
Read as much data as possible from the serial device, breaking it into
lines.
Returns a list of bytes objects, each object being one of the lines.
Each line will include the newline character.
.. method:: USB_VCP.write(buf)
Write the bytes from ``buf`` to the serial device.
Returns the number of bytes written.
.. method:: USB_VCP.recv(data, \*, timeout=5000)
.. method:: usb_vcp.recv(data, \*, timeout=5000)
Receive data on the bus:
- ``data`` can be an integer, which is the number of bytes to receive,
or a mutable buffer, which will be filled with received bytes.
- ``timeout`` is the timeout in milliseconds to wait for the receive.
Return value: if ``data`` is an integer then a new buffer of the bytes received,
otherwise the number of bytes read into ``data`` is returned.
.. method:: USB_VCP.send(data, \*, timeout=5000)
.. method:: usb_vcp.send(data, \*, timeout=5000)
Send data over the USB VCP:
- ``data`` is the data to send (an integer to send, or a buffer object).
- ``timeout`` is the timeout in milliseconds to wait for the send.
Return value: number of bytes sent.
.. method:: usb_vcp.write(buf)
Constants
---------
.. data:: USB_VCP.RTS
USB_VCP.CTS
to select the flow control type.

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