diff options
author | Damien George <damien.p.george@gmail.com> | 2017-08-14 16:39:40 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-08-14 16:39:40 +1000 |
commit | 9624f10825851f5419cc0b21517580c4cb3838f0 (patch) | |
tree | feb035f907b56c0b933dbfbefe86ba7922814547 /docs | |
parent | 545354cb2a428bd844878a7c8cfd6e67a415e699 (diff) | |
parent | 825460a093a6bcd8fb79119b5f6ee8408f63603b (diff) | |
download | micropython-9624f10825851f5419cc0b21517580c4cb3838f0.tar.gz micropython-9624f10825851f5419cc0b21517580c4cb3838f0.zip |
Merge tag 'v1.9' into parse-bytecode
New VFS subsystem and scheduling framework, and less need for the heap
This release adds some fundamental new components, allows for more Python
operations without using the heap and has reduced code size and stack
usage.
Changes in the way iterators are handled allows to iterate without
allocating on the heap for the types: tuple, list, str, bytes, bytearray,
array, dict, set, frozenset. It also allows to call the builtins all, any,
min max and sum without allocating heap memory for the iterator argument.
And improvements to the handling of super() means that super().foo() method
calls are now heap-less.
A new generic VFS subsystem has been added which allows to mount arbitrary
filesystems (even written in Python) at the root or at a mount-point within
the root. The FatFS driver has been replaced with an object-oriented
version (oofatfs) which allows a fully customisable filesystem layout.
A scheduling framework has been implemented in the core which gives the
ability to schedule callbacks to be called "as soon as possible". This
allows ports to implement "soft IRQs" which allow the programmer to
allocate memory during an interrupt handler, at the cost of some
performance related to response time of the handler. The new
micropython.schedule() function gives access to the scheduler.
Other improvements to the core include: consts can now be big-nums, for
example "X = const(1 << 100)"; addition of "help('modules')" to list
available modules; stack usage reduced for a Python call by 8 bytes on ARM
Cortex-M architectures; micropython.kbd_intr() function added to disable
Ctrl-C capture; addition of uio.resource_stream(); mpy-cross is built
automatically if needed; a helper tool mpy_cross_all.py is added to run
mpy-cross on an entire project.
The bytecode has changed in this version so existing .mpy files will need
recompiling. There have also been some changes to the C API, most notably
with mp_uint_t changed to size_t in many places.
In the extended modules the following main changes have been made: addition
of machine.Signal class to allow inversion on a Pin; framebuf has new
formats of the form MONO_xxx; addition of uselect.ipoll() for allocation-
free polling; addition of uos.ilistdir() for efficient iteration of a
directory listing; machine.Pin high/low methods are renamed to on/off in
esp8266 and zephyr (this is a backwards-incompatible change);
machine.time_pulse_us() function no longer throws exceptions, but returns
negative values instead.
For stmhal the pyb.fault_debug() function is added, and default behaviour
for a hard-fault is now an immediate reset. There is better support for F7
MCUs, in particular DMA and SD card support. A bug has been fixed with the
USB VCP (USB serial) where it would in rare cases (usually when the host PC
was under load) would lose characters. Pyboard now automatically mounts
all available partitions on the SD card. Multithreading has been
implemented and is available via the _thread module, but this feature is
disabled by default and must be enabled at compile time using the
MICROPY_THREAD and MICROPY_THREAD_GIL options. The ability to skip booting
from SD card is now available by creating an empty file on the flash called
"SKIPSD".
The cc3200 port has had some backwards incompatible changes, in particular
with I2C, Pin, UART and uos. Please see the documentation for the new
behaviour.
The esp8266 port has had a change in the size of the firmware in order to
accommodate additional features. As such the filesystem for this version
is incompatible with v1.8.7 and a device requires backup and erasure before
flashing this version. Soft IRQs are now implemented for Pin and Timer
callbacks, along with the general improvements described above.
In the documentation there is now a section describing the differences
between MicroPython and CPython. And code coverage is up to 98% across py/
and extmod/.
Changes in code size (in bytes) between v1.8.7 and this version are:
bare-arm: -1104
minimal: -1324
unix x64: -1115
unix nanbox: -11106
stmhal: +18116
cc3200: +1032
esp8266: +3060
Note that stmhal has increased significantly due to the addition of frozen
bytecode and the LCD160CR driver.
A detailed list of changes follows.
py core:
- builtinimport: raise ValueError for bad relative import, per CPython
- builtinimport: remove unreachable code and change obj-import comment
- runtime: refactor assert(0) to improve coverage
- runtime: fix handling of throw() when resuming generator
- objgenerator: when throwing an object, don't make an exc instance
- objgenerator: don't raise RuntimeError if GeneratorExit ignored
- parse: refactor code to remove assert(0)'s
- emitnative: remove assert(0)'s or replace with mp_not_implemented
- objexcept: replace if-cond and assert(0) with simple assert
- runtime: refactor default case of switch to remove assert(0)
- binary: mp_binary_get_size: Raise error on unsupported typecodes
- formatfloat: remove unreachable code
- objint_mpz: refactor switch-statement to remove unreachable default
- mpz: implement mpz_set_from_bytes() as a foundation for int.from_bytes()
- objint: from_bytes(): implement "byteorder" param and arbitrary precision
- objint_longlong: add stub for mp_obj_int_from_bytes_impl()
- add builtin help function to core, with default help msg
- move weak-link map to objmodule.c, and expose module maps as public
- builtinhelp: implement help('modules') to list available modules
- objint: fix left-shift overflow in checking for large int
- objmodule: move module init/deinit code into runtime functions
- objstr: optimize string concatenation with empty string
- showbc: make sure to set the const_table before printing bytecode
- py.mk: add CFLAGS_MOD flag to set config file for FatFs
- objstringio: allow to specify initial capacity by passing numeric argument
- objset: make inplace binary operators actually modify the set
- objfloat: raise ZeroDivisionError for 0 to negative power
- objcomplex: correctly handle case of 0j to power of something
- objset: fix inplace binary ops so frozensets are not modified
- added optimised support for 3-argument calls to builtin.pow()
- objstr: give correct behaviour when passing a dict to %-formatting
- mpconfig.h: move PY_BUILTINS_POW3 config option to diff part of file
- objstr: convert some instances of mp_uint_t to size_t
- objcomplex: fix typo in ternary expression
- asmxtensa.h: explicitly cast args to 32-bits so left-shift is legal
- map: change mp_uint_t to size_t where appropriate
- nlr: fix execstack builds for ARM
- objtype: add __delattr__/__setattr__ configured by MICROPY_PY_DELATTR_SETATTR
- emitbc: produce correct line number info for large bytecode chunks
- objtype: replace non-ASCII single-quote char with ASCII version
- modthread: use system-provided mutexs for _thread locks
- vm: add MICROPY_PY_THREAD_GIL_VM_DIVISOR option
- runtime: convert mp_uint_t to size_t where appropriate
- mpz: convert mp_uint_t to size_t where appropriate
- mpz: remove obsolete declaration of mpz_as_str_size
- mpz: change type of "base" args from mp_uint_t to unsigned int
- persistentcode: replace mp_uint_t with size_t where appropriate
- objtuple: convert mp_uint_t to size_t where appropriate
- objlist: convert mp_uint_t to size_t where appropriate
- objdict: convert mp_uint_t to size_t where appropriate
- objset: convert mp_uint_t to size_t where appropriate
- objstr: convert mp_uint_t to size_t (and use int) where appropriate
- objarray: convert mp_uint_t to size_t where appropriate
- objfun: convert mp_uint_t to size_t where appropriate
- objclosure: convert mp_uint_t to size_t where appropriate
- objexcept: convert mp_uint_t to size_t where appropriate
- objint: convert mp_uint_t to size_t where appropriate
- vm: convert mp_uint_t to size_t where appropriate
- add iter_buf to getiter type method
- allow bytecode/native to put iter_buf on stack for simple for loops
- make FOR_ITER opcode pop 1+4 slots from the stack when finished
- optimise storage of iterator so it takes only 4 slots on Py stack
- remove unused "use_stack" argument from for_iter_end emit function
- runtime: optimise case of identity iterator so it doesn't alloc RAM
- compile: optimise list/dict/set comprehensions to use stack iter
- de-optimise some uses of mp_getiter, so they don't use the C stack
- grammar: group no-compile grammar rules together to shrink tables
- lexer: don't generate string representation for period or ellipsis
- persistentcode: bump .mpy version due to change in bytecode
- lexer: simplify handling of indenting of very first token
- lexer: move check for keyword to name-tokenising block
- lexer: use strcmp to make keyword searching more efficient
- lexer: simplify handling of line-continuation error
- do adjacent str/bytes literal concatenation in lexer, not compiler
- lexer: convert mp_uint_t to size_t where appropriate
- grammar: remove unused rule
- objlist: for list slice assignment, allow RHS to be a tuple or list
- moduerrno: make uerrno.errorcode dict configurable
- moduerrno: make list of errno codes configurable
- parse: allow parser/compiler consts to be bignums
- create str/bytes objects in the parser, not the compiler
- parse: simplify handling of errors by raising them directly
- runtime: mp_raise_msg(): Accept NULL argument for message
- objarray: disallow slice-assignment to read-only memoryview
- map: fix bugs with deletion of elements from OrderedDict
- move locals/globals dicts to the thread-specific state
- nlr.h: mark nlr_jump_fail as NORETURN
- nlrxtensa: convert from assembler to C file with inline asm
- nlrx64: convert from assembler to C file with inline asm
- nlrx86: convert from assembler to C file with inline asm
- py.mk: force nlr files to be compiled with -Os
- modsys: use MP_SMALL_INT_MAX for sys.maxsize in case of LONGINT_IMPL_NONE
- runtime.c: remove optimization of '*a,=b', it caused a bug
- use mp_obj_get_array where sequence may be a tuple or a list
- nlrx86: add workaround for Zephyr
- nlrx64: fixes to support Mac OS
- objint_longlong: implement mp_obj_int_from_bytes_impl()
- allow lexer to raise exceptions during construction
- objint: allow to print long-long ints without using the heap
- emitnative: use assertions and mp_not_implemented correctly
- emitnative: remove obsolete commented out code
- mpprint: fix int formatting so "+" is printed for 0-valued integer
- mkrules.mk: remove special check for "-B" in qstr auto generation
- objstr: fix eager optimisation of str/bytes addition
- reduce size of mp_code_state_t structure
- provide mp_decode_uint_value to help optimise stack usage
- objstr: use better msg in bad implicit str/bytes conversion exception
- add micropython.schedule() function and associated runtime code
- vm: don't release the GIL if the scheduler is locked
- bc: provide better error message for an unexpected keyword argument
- use size_t as len argument and return type of mp_get_index
- sequence: convert mp_uint_t to size_t where appropriate
- define and use MP_OBJ_ITER_BUF_NSLOTS to get size of stack iter buf
- lexer: remove obsolete comment, since lexer can now raise exceptions
- modmath: allow trunc/ceil/floor to return a big int if necessary
- objint: handle special case of -0 when classifying fp as int
- modbuiltins: for round() builtin use nearbyint instead of round
- modbuiltins: allow round() to return a big int if necessary
- objtype: use size_t where appropriate, instead of mp_uint_t or uint
- objnamedtuple: use size_t where appropriate, instead of mp_uint_t
- use mp_locals/mp_globals accessor funcs instead of MP_STATE_CTX
- remove MP_STATE_CTX, use MP_STATE_THREAD instead (it's an alias)
- objarray: use mp_obj_str_get_str instead of mp_obj_str_get_data
- nlrx86: better check for Zephyr (requires 1.7)
- obj: change mp_uint_t to size_t for mp_obj_get_array_fixed_n len arg
- vm: fix VM opcode tracing to print correct stack pointer
- compile: when compiling super(), handle closed-over self variable
- objmap: convert mp_uint_t to size_t
- use mp_raise_TypeError/mp_raise_ValueError helpers where possible
- lexer: simplify and reduce code size for operator tokenising
- compile: simplify syntax-error messages for illegal assignments
- shorten a couple of error messages
- compile: provide terse error message for invalid dict/set literals
- convert mp_uint_t to size_t for tuple/list accessors
- change mp_uint_t to size_t for mp_obj_str_get_data len arg
- objzip: convert mp_uint_t to size_t
- obj.h: make sequence grow more efficient and support overlapping
- objstr: use MICROPY_FULL_CHECKS for range checking when constructing bytes
- add very simple but correct hashing for float and complex numbers
- objint: consolidate mp_obj_new_int_from_float to one implementation
- raise a ValueError if range() step is zero
- objtuple: add support for inplace add (same as normal add)
- make sure that static emg-exc-buffer is aligned to size of mp_obj_t
- runtime: when init'ing kbd intr exc, use tuple ptr instead of object
- objint: extract small int value directly because type is known
- objint: use unsigned arithmetic when formatting an integer
- obj: clean up and add comments describing mp_obj_type_t struct
- optimise types for common case where type has a single parent type
- objfloat: add implementation of high-quality float hashing
- nlrsetjmp: add check for failed NLR jump
- gc: execute finaliser code in a protected environment
- modmicropython: add micropython.kbd_intr() function
- reduce str/repr precision of float numbers when floats are 30-bit
- objtype: mp_obj_new_super doesn't need to be public, so inline it
- compile: don't do unnecessary check if parse node is a struct
- compile: extract parse-node kind at start of func for efficiency
- compile: add COMP_RETURN_IF_EXPR option to enable return-if-else opt
- compile: don't do unnecessary check if iter parse node is a struct
- compile: refactor handling of special super() call
- add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls
- mpz: strip trailing zeros from mpz value when set from bytes
- mpz: in mpn_sub, use existing function to remove trailing zeros
- cleanup use of global DEBUG preprocessor definition
- modio: implement uio.resource_stream(package, resource_path)
- objint: in int.from_bytes, only create big-int if really needed
- modio: resource_stream: Implement "package" param handling
- binary: handle storing big-ints to all arrays types
- lexer: simplify lexer startup by using dummy bytes and next_char()
- mkrules.mk: add dependency of .mpy files upon mpy-cross
- lexer: process CR earlier to allow newlines checks on chr1
- modsys: update conditionals for code referencing sys.stdout
- objstringio: fix StringIO reads at or beyond EOF
- sequence: fix boundary errors when slicing with a negative step
- objrange: fix slicing of range when step of slice is negative
- mkenv.mk: use $(TOP) instead of ".." to reference tools, mpy-cross
- vm: fix bug with stackless mode and unwinding of exceptions
- vm: fix bug with unwind jump popping the iterator from a for loop
- emitbc: fix bug with BC emitter computing Python stack size
- mkrules.mk: fix auto-qstr generation when "make -B" is used
- objstringio: catch mp_uint_t overflow of stream position in write()
- move BYTES_PER_WORD definition from ports to py/mpconfig.h
extmod:
- modframebuf: optimize fill_rect subroutine call
- modframebuf: clip pixels drawn by line method
- modframebuf: add GS4_HMSB format
- vfs_fat: rework so it can optionally use OO version of FatFS
- rename vfs_fat_file.h to vfs_fat.h
- add generic VFS sub-system
- vfs_fat: rework to support new generic VFS sub-system
- vfs: add ability for VFS sub-system to import using VfsFat
- modlwip: add socket.readinto() method
- vfs: expose mp_vfs_mount_t type
- vfs_fat: use SECSIZE macro to determine FatFs sector size
- machine_signal: implement "Signal" abstraction for machine module
- vfs_fat: update to use FF_DIR instead of DIR
- vfs: expose lookup_path_raw as mp_vfs_lookup_path
- vfs_fat: remove MICROPY_READER_FATFS component
- vfs_fat: remove MICROPY_FSUSERMOUNT_ADHOC config option
- remove MICROPY_FSUSERMOUNT and related files
- vfs_fat: remove MICROPY_FATFS_OO config option
- merge old fsusermount.h header into vfs.h and vfs_fat.h
- vfs_fat: remove unused fatfs_builtin_open function
- vfs_fat: remove unused function fat_vfs_listdir
- vfs_reader: fix use of NLR by popping context
- vfs_fat.c: use explicit include path for timeutils.h
- machine_pulse: make time_pulse_us() not throw exceptions
- machine_spi: remove EVENT_POLL_HOOK from soft-SPI transfer func
- machine_signal: implement Signal .on() and .off() methods
- vfs: allow to mount a block device, not just a VFS object
- vfs: raise OSError(EEXIST) on attempt to mkdir a mount point
- vfs: allow to stat the root directory
- modlwip: add my copyright
- modurandom: use mp_raise_ValueError()
- modutimeq: make scheduling fair (round-robin)
- modutimeq: add peektime() function (provisional)
- vfs_fat: remove obsolete and unused str/len members
- vfs_fat: allow to compile with MICROPY_VFS_FAT disabled
- vfs: rewrite path lookup algo to support relative paths from root
- modframebuf: add support for monochrome horizontal format
- utime_mphal: don't exit/enter the GIL in generic sleep functions
- modlwip: use mp_obj_str_get_str instead of mp_obj_str_get_data
- vfs_fat: fix calculation of total blocks in statvfs
- moduselect: update to use size_t for array accessor
- update for changes to mp_obj_str_get_data
- modframebuf: make monochrome bitmap formats start with MONO_
- machine_signal: support all Pin's arguments to the constructor
- machine_signal: rename "inverted" arg to "invert", it's shorter
- moductypes: fix bigint handling for 32-bit ports
- crypto-algorithms/sha256: remove non-standard memory.h header
- moduselect: convert to MP_ROM_QSTR and friends
- moduselect: refactor towards introduction of poll.ipoll()
- moduselect: implement ipoll() method for alloc-free polling
- modlwip: getaddrinfo: Allow to accept all 6 standard params
- modlwip: ioctl POLL: Fix handling of peer closed socket
- vfs: allow a VFS to be mounted at the root dir
- vfs: implement mp_vfs_ilistdir()
- vfs_fat: replace listdir() with implementation of ilistdir()
- vfs: use MP_S_IFDIR, MP_S_IFREG consts instead of magic numbers
- vfs_fat_misc: remove dot-dirs filter since FatFS already does it
lib:
- utils: remove old pyhelp helper, replaced with py/builtinhelp.c
- utils/pyexec: only print help prompt if HELP feature is enabled
- oofatfs: add OO version of FatFS library
- fatfs: remove old fatfs library component, it's replaced by oofatfs
- oofatfs/ffconf.h: allow to configure FS_EXFAT option
- oofatfs/ffconf.h: add MICROPY_FATFS_NORTC option
- utils/pyexec: allow to compile when the uPy compiler is disabled
- utils/pyexec: refactor to put lexer constructors all in one place
- memzip: make lexer constructor raise exception when file not found
- utils/pyexec: fix bug with pyexec_file not setting flag for source
- libm: add implementation of nearbyintf, from musl-1.1.16
- netutils: update for changes to mp_obj_str_get_data
- utils/pyexec: update event-driven REPL to match non-event REPL
drivers:
- fix some minor spelling mistakes
- display: add driver and test for uPy LCD160CR display
- memory: add SPI flash driver, written in C
- display/lcd160cr: use correct variable in set_power()
- display/lcd160cr: fix bugs with lcd.get_pixel()
- display/lcd160cr: fix bug with save_to_flash method
- display/lcd160cr: add check that JPEG size is less than 65536
- nrf24l01: update to work on newer ports, using machine, utime
- display/lcd160cr: fix get_line method and enhance screen_dump
- display/lcd160cr_test: allow test to take orientation parameter
- replace deprecated Pin.high()/low() methods with .__call__(1/0)
tools:
- tinytest-codegen.py: blacklist heapalloc_str.py test for qemu-arm
- upip: update to 1.1.5. Better and more user-friendly error handling
- add gen-cpydiff.py to generate docs differences
- gen-cpydiff.py: set the Python import path to find test modules
- gen-cpydiff.py: configurable CPython and micropython executables
- tinytest-codegen: update for recent test renaming ("intbig" suffix)
- pyboard: tighten up Pyboard object closure on errors
- pyboard: add "exec" and "execpty" pseudo-devices support
- pyboard: execpty: Use shell=False to workaround some curdir issues
- pyboard: processPtyToTerminal: Add workaround for PySerial bug
- pyboard: provide more details when expected reply not received
- mpy-tool: make work if run from another directory
- upip: upgrade to 1.1.6, supports commented lines in requirements.txt
- upip: upgrade to 1.2
- mpy-tool.py: use MP_ROM_xxx macros to support nanbox builds
- mpy_cross_all.py: helper tool to run mpy-cross on the entire project
- mpy-tool.py: fix regression with freezing floats in obj repr C
tests:
- add feature check for "const" keyword and skip related tests
- update test suite to be compatible with CPython 3.6
- improve stream.c test coverage
- import: improve builtinimport.c test coverage
- improve frozen import test coverage
- update tests, and add new ones, for recent generator tweaks
- io: improve test coverage of io.BufferedWriter
- basics: improve runtime.c test coverage
- extmod: improve test coverage of ure module
- float: add test for assigning to attribute of complex number
- extmod/framebuf1: add test for no-op fill_rect
- micropython/opt_level: add test for opt_level 3
- misc/non_compliant: add test for inability to assign func attrs
- basics: add test for assignment of attribute to bound method
- add test for int.from_bytes() for arbitrary-precision integer
- heapalloc_int_from_bytes: test that int.from_bytes() can work w/o alloc
- add test for builtin help function
- basics/builtin_help: add test for help('modules')
- make sure special tests can be skipped as well
- extmod/framebuf4: add tests for GS4_HMSB framebuf format
- extmod/framebuf1: fix test for framebuf invalid constructor
- extmod: add test for ure debug printing when compiling a regex
- heapalloc_str: test for alloc-free string operations
- extmod: update vfs_fat tests for new OO FatFs library
- extmod/vfs_fat: update tests to work with new VFS sub-system
- extmod/vfs_fat_ramdisk: make it work on pyboard
- run-tests: skip frozenset tests if set literal syntax is not available
- basics/zip: make skippable
- thread: make thread_exc2 runable on baremetal
- thread: fix stack size test so tests run reliably on baremetal
- heapalloc_bytesio: test for BytesIO with preallocates space
- basics/set_binop: add tests for inplace set operations
- float: add tests for zero to a negative power
- split tests for 2- and 3-arg pow()
- basics/string_format_modulo: add more tests for dict formatting
- pyb: adjust tests so they can run on PYB and PYBLITE
- misc: add test for line number printing with large bytecode chunk
- add option to not clear MICROPYPATH when running tests
- run-tests: allow to skip tests using async/await keywords
- comprehension1, containment: split set tests to separate files
- builtin_dir: the most expected thing in sys is exit, test for it
- basic/[a-f]*: make skippable
- dict_fromkeys: revert to use reversed() to run in native codegen mode
- extmod: make tests skippable
- thread: replace busy waiting loops with a loop that sleeps
- thread: add stress-test for creating many threads
- gen_yield_from_close: use range() instead of reversed()
- basic/: make various tests skippable
- cmdline: update tests to pass with latest changes to bytecode
- cmdline/cmd_showbc: update to work with recent changes
- micropython: add test for iterating with the heap locked
- micropython/heapalloc_iter: add tests for contains and unpack
- cmdline: update cmd_parsetree test for changes to grammar order
- cmdline/cmd_parsetree: update to work with changes to grammar
- basics/string_join: add more tests for string concatenation
- heapalloc_exc_raise.py: heap alloc test for raising/catching exc
- cpydiff: add initial set of tests for uPy-CPython differences
- cpydiff: add a test for storing iterable to a list slice
- micropython: add test for consts that are bignums
- extmod: add test for machine.Signal class
- basics: add further tests for OrderedDict
- run-tests: check for big int availability and skip related tests
- basic: split tests into working with small ints and not working
- float/complex1: split out intbig test
- float2int*: suffix with _intbig, don't run on any other int type
- string_format_modulo2: split off intbig test
- basics/string_join.py: add test case where argument is not iterable
- basics/unpack1.py: test if *a, = b copies b when b is a list
- micropython/: split off intbig tests
- uctypes_array_assign_native_le: split off intbig part
- basic: make various tests skippable
- float: make various tests skippable
- extmod: add very basic feature test for ussl module
- extmod: add websocket tests
- dict_fromkeys: split out skippable part
- micropython: make uio-using tests skippable
- micropython/heapalloc_traceback: fix backtrace line # after refactor
- micropython/opt_level: clarify the expected output for opt_level == 3
- feature_check/int_big: rework "big int" detection
- basics/fun_error: split out skippable test
- extmod: rename websocket test to websocket_basic
- misc/: make few tests skippable
- extmod: add a test for core VFS functionality, sans any filesystem
- extmod/vfs_basic: add more tests for basic VFS functionality
- extmod: improve re1.5/recursiveloop.c test coverage
- improve binary.c test coverage
- basics/struct_micropython: add test for 'S' typecode in ustruct
- run-tests: re-instate skipping of doubleprec test on pyboard
- extmod/vfs_basic: unmount all existing devices before doing test
- extmod: improve tinfgzip.c test coverage
- micropython/viper_error: add more tests to improve coverage
- basics/string_format2: adjust comment now that tests succeed
- basics: add test for string module formatting with int argument
- basics: move string-modulo-format int tests to dedicated file
- basics/bytes_add: add tests for optimised bytes addition
- micropython: add tests for micropython.schedule()
- heapalloc_str: test no-replacement case for str.replace()
- float: add tests for math funcs that return ints
- float: add tests for round() of inf, nan and large number
- basics: add test for super() when self is closed over
- basics: add tests for list and bytearray growing using themselves
- run-tests: be sure to close Pyboard object on completion
- vfs_fat_fileio.py is too big to be parsed in 16K heap, split in 2
- extmod/vfs_fat_fileio*: improve skippability
- float/byte*_construct: skip on missing array module
- micropython/heapalloc_iter: improve skippability
- run-tests: introduce generic "minimal" target
- float: add tests for hashing float and complex numbers
- run-tests: update names of tests that may need skipping
- basics: add tests for raising ValueError when range() gets 0 step
- basics: add test for tuple inplace add
- extmod/utimeq1: improve coverage of utimeq module
- run-tests: search feature checks wrt to main script location
- run-tests: don't post-process CRASH result in any way
- micropython: add test for micropython.kbd_intr()
- add tests for calling super and loading a method directly
- basics: add tests for int.from_bytes when src has trailing zeros
- cpydiff/core_arguments: fill in cause/workaround
- cpydiff/core_function_userattr: clarify, fill in cause and workaround
- cpydiff/core_import_prereg: fill in cause and workaround
- io/resource_stream: add test for uio.resource_stream()
- cpydiff/core_import_path: test showing difference in package.__path__
- cpydiff/core_import_split_ns_pkgs: test for split namespace packages
- cpydiff/core_function_unpacking: fill in workaround
- extmod: add more tests for VFS FAT
- extmod: add some more VFS tests
- micropython: add test for int.from_bytes with many zero bytes
- move super-as-local test from cpydiff to basic tests
- basics: update array test for big-int with lL typecodes
- basics: add memoryview test for big ints
- basics/lexer: add lexer tests for input starting with newlines
- extmod: make some vfs tests fully unmount FSs before running
- extmod/vfs: update tests to reflect new ilistdir() method
- basics/lexer: add line continuation tests for lexer
- extmod/vfs_fat: add test for ilistdir of a non-existent directory
- extmod/vfs_fat_more: make skippable is uos is not available
- io/bytesio_ext: test read() after seek() past end of BytesIO object
- basics/list_slice_3arg: add more tests for negative slicing
- basics/builtin_range: add tests for negative slicing of range
- basics: add more tests for unwind jumps from within a try-finally
mpy-cross:
- main: move lexer constructor to within NLR handler block
- fix compiler detection for including windows/fmode.c
- Makefile: override undefine any inherited variables
- Makefile: guard "override undefine" by test for make feature
bare-arm port:
- main: move lexer constructor to within NLR handler block
- Makefile: change C standard from gnu99 to c99
minimal port:
- update frozentest.mpy file for new .mpy version
- add ability and description to build without the compiler
- main: move lexer constructor to within NLR handler block
- Makefile: change C standard from gnu99 to c99
- main: make Cortex-M vector table constant
unix port:
- coverage: move coverage #if guard back to top of file
- enable builtin help function in coverage build
- enable MICROPY_PY_BUILTINS_HELP_MODULES in coverage build
- switch to OO version of FatFS library
- get minimal version compiling again
- change to use new generic VFS sub-system in coverage build
- fatfs_port: include new oofatfs header
- mpconfigport.h: remove obsolete MICROPY_FATFS_VOLUMES config
- modos: remove VfsFat from uos module, it's now in uos_vfs module
- make stack be non-executable
- fix freedos port build problems
- main: properly handle MICROPYPATH starting with ':'
- moduselect: implement ipoll() method with no-allocation policy
- modmachine: add Signal class to machine module
- remove remaining, obsolete traces of GNU readline support
- moduselect: properly implement ipoll object iteration
- main: refactor to put lexer constructors all in one place
- use mp_handle_pending() in time.sleep()
- coverage: enable scheduler and add tests for it
- use mp_obj_str_get_str instead of mp_obj_str_get_data
- convert mp_uint_t to size_t for use of mp_obj_list_get
- convert mp_uint_t to size_t in alloc.c
- enabled high-quality float hashing in coverage build
- remove obsolete MICROPY_FATFS macro
- main: ignore SIGPIPE signal, instead make EPIPE arrive
- main: don't allow to specify too small heap size
- main: implement -m option for packages
- Makefile: enable frozen bytecode modules dir
- move upip to frozen bytecode dir
- Makefile: don't add frozen bytecode to minimal build
- add ilistdir in uos module
- use core-provided KeyboardInterrupt exception object
windows port:
- .gitignore: ignore VC.db and VC.opendb files from VS2015
- make msvc project file support any version from VS2013 to VS2017
- bring mpconfigport.h up-to-date with unix port
- README: convert to Markdown
- README: fix some typos and grammar
- README: add a note about stack usage for msvc
- use core-provided KeyboardInterrupt exception object
- msvc: add machine/pin-related sources to build
- msvc: remove directory with generated files when cleaning
- msvc: do not define DEBUG for debug builds
- msvc: rebuild all qstrs when mpconfig headers are modified
- msvc: workaround parser bug in older MSBuild versions
qemu-arm port:
- don't compile tests in "REPL" mode
- mpconfigport.h: enable MICROPY_PY_BUILTINS_POW3 option
- enable machine module and associated tests
- add basic uos module with generic VFS capabilities
- move lexer constructors to within NLR handler block
stmhal port:
- support PortG on STM32L476 and STM32L486
- fix wrong usage of gcc -print-libgcc-file-name
- fix USB HID receive not receiving the first packet
- implement ioctl for USB HID read
- implement SNAK/CNAK mechanism for USB HID receive
- convert to use builtin help function
- enable help('modules') feature
- add default frozen-bytecode directory and link lcd160cr driver
- fix examples in openocd configs to include addresses
- add ability to have filesystem stored on external SPI flash
- boards/STM32L476DISC: use external SPI flash for filesystem
- mpconfigport.h: reorganise the config options into groups
- usbd_msc_storage: use storage functions instead of disk ones
- convert to use VFS sub-system and new ooFatFs component
- fix name of automatically created boot.py
- moduos: remove duplicated chdir
- use LED constants from PYBv4 onwards
- set the FatFs partition number when initialising VFS object
- fix stack pointer initialisation for F411 and F429 boards
- README: add paragraph about building mpy-cross
- on boot, mount all available partitions of the SD card
- main: put /sd directory before /flash in sys.path
- pin: add C-level pin ioctl method
- modmachine: add machine.Signal type
- main: guard init_sdcard_fs with MICROPY_HW_HAS_SDCARD
- pendsv: fill in comments about what the stack contains
- initial implementation of multithreading, currently disabled
- main: use _estack value to initialise stack extents
- fix build issue when MICROPY_PY_THREAD is disabled
- mpconfigport.h: enable MICROPY_PY_BUILTINS_POW3 option
- on HardFault, print stack pointer and do a stack dump
- add pyb.fault_debug() function, to control hard-fault behaviour
- use MICROPY_EVENT_POLL_HOOK instead of __WFI where appropriate
- add ability to skip booting from SD card via /flash/SKIPSD file
- Makefile: drop use of -mabi=aapcs-linux; link libgcc by default
- boards: for STM32F411DISC, change I2C pin according to datasheet
- implement a proper thread scheduler
- use generic interrupt char code
- main: remove unnecessary header includes
- use mp_hal_delay_ms instead of HAL_Delay
- rename sys_tick ticks/delay functions to corresp. mp_hal ones
- modpyb: use utime ticks ms/us functions instead of custom ones
- modnwcc3k: add include for mp_hal_delay_ms
- mphalport: get ticks_cpu() working on F7 MCUs
- main: allocate flash's VFS struct on the heap to trace root ptrs
- enable micropython.schedule()
- pendsv: disable interrupts during a thread switch
- irq: shift IRQ priorities of TIM and EXTINT to be above PENDSV
- pybthread: allow interrupts to work during lock/unlock of mutex
- systick: make mp_hal_delay_ms release the GIL when sleeping
- boards: fix alt-func config for PA5 of STM32F767
- board: fix existing and add more pin defs for NUCLEO_F767ZI
- spi: clean and/or invalidate D-cache before SPI DMA transfers
- hal: for F7 MCUs, expose DMA_CalcBaseAndBitshift function
- dma: fix reinitialisation of DMA on F7 MCUs, following F4
- update to use size_t for tuple/list accessors
- update for changes to mp_obj_str_get_data
- spi: increase SPI transfer timeout, proportional to num bytes
- support SDMMC alternate functions in pin generation
- sdcard: add support for SDMMC2 on F7 MCUs
- boards: update F76x alternate function table to add SDMMC2
- boards/STM32F769DISC: get SD card working by using SDMMC2
- boards/STM32F769DISC: fix user switch pin, and document stlink
- boards: remove F769 alt function table, it's same as for F767
- dma: don't include SDMMC2 struct if SDMMC2 is not available
- move L4/F7 I2C timing constants from mpconfigboard.h to i2c.c
- i2c: clean the cache so that I2C DMA works on F7 MCUs
- usbd_cdc_interface: increase in-endpoint timeout to 500ms
- usbd_cdc_interface: change CDC RX to use a circular buffer
- enable parsing of all Pin constructor args by machine.Signal
- timer: clear interrupt flag before setting callback
- convert all module and method tables to use MP_ROM macros
- modmachine: add machine.UART class, linking to pyb.UART
- modmachine: remove TODO comment that is now implemented
- add machine.Pin on/off methods
- add ilistdir in uos module
cc3200 port:
- convert to use builtin help function
- add implementations of mp_import_stat and builtin_open
- modusocket: remove deprecated socket.error
- convert to use new VFS sub-system and new ooFatFs library
- refactor "ticks" functions to use common extmod implementation
- move stoupper to ftp.c and define in terms of unichar_toupper
- use simplelink API instead of emulated BSD API
- remove util/std.h, can just use stdio.h instead
- mods/modwlan: remove unused header includes; simplify others
- mods/modwlan: make multi-threaded a proper compile-time option
- mods/modwlan: allow antenna diversity to be fully compiled out
- mods/modwlan: add int casts to silence compiler warnings
- remove remaining references to std.h
- move wlan socket glue functions from modwlan to modusocket
- convert to using uPy internal errno numbers
- when raising OSError's use MP_Exxx as arg instead of a string
- enable uerrno module with short, custom list of error codes
- mods/modusocket: init vars to 0 to silence compiler warnings
- remove socket.timeout class, use OSError(ETIMEDOUT) instead
- moduos: remove uos.sep, as it's strictly optional
- mptask: allocate flash VFS struct on the heap to trace root ptrs
- mods/modutime: use generic sleep_ms and sleep_us implementations
- update to use size_t for tuple/list accessors
- update for changes to mp_obj_str_get_data
- mods/pybi2c: raise OSError if readfrom_mem fails to write addr
- modmachine: return frequency value directly, like other ports
- pybuart: make parity specifications consistent with HW API
- mods/pybi2c: make machine.I2C constructor/init conform to HW API
- mods/pybi2c: make readfnom_mem_into/writeto_mem return None
- mods/pybpin: remove toggle() method
teensy port:
- convert to use builtin help function
- main: remove unnecessary header includes
- lexerfrozen: make mp_lexer_new_from_file raise an exception
esp8266 port:
- convert to use builtin help function
- factor out common linker code to esp8266_common.ld
- switch to use OO version of FatFs library
- change to use new generic VFS sub-system
- fatfs_port: include new oofatfs header
- machine_pin: implement pin ioctl protocol
- modmachine: add Signal class
- mpconfigport.h: remove obsolete MICROPY_FATFS_VOLUMES config
- uart: add support for polling uart device
- moduos: populate release field of uname in case it was GC'd
- mpconfigport.h: enable help('modules') feature
- update lexer constructors so they can raise exceptions
- only execute main.py if in friendly REPL mode
- enable micropython.schedule() with locking in pin callback
- change machine.Timer callback to soft callback
- machine_pin: add "hard" parameter to pin.irq, soft by default
- machine_pin: make pin.irq arguments positional
- machine_pin: fix memset size for zeroing of pin_irq_is_hard
- machine_pin: fix pin.irq() to work when all args are keywords
- modesp: use mp_obj_str_get_str instead of mp_obj_str_get_data
- modesp: remove long-obsolete and unused espconn bindings
- update to use size_t for tuple/list accessors
- update for changes to mp_obj_str_get_data
- remove unused entry in port root pointers
- README: replace reference of alpha status to beta status
- README: add notice about 512K version
- change default settings to mount flash at root dir
- esp8266.ld, esp8266_ota.ld: grow main firmware size by 32KB
- modesp: flash_user_start: Use value from linker script
- modules/flashbdev: reserve one sector for native code storage
- scripts: move drivers/modules to modules/ (frozen bytecode)
- scripts: move initsetup & port_diag tools to modules/
- ets_alt_task.c: prevent spurious large increment of ticks_ms()
- modnetwork: in connect, fix potential buffer overflows
- machine_uart: add uart.any() method
- modules: mount filesystem at root when creating for first time
- mpconfigport.h: remove duplicate link to lwip module
- rename machine.Pin high/low methods to on/off
- add ilistdir in uos module
zephyr port:
- help: update n_args param type to size_t
- remove deprecated .mdef file
- add separate Zephyr config for "minimal" build
- enable SLIP networking for the default build
- convert to use builtin help function
- make sure that correct Zephyr config is used for "minimal" build
- allow to have per-board Zephyr config fragments
- prj_frdm_k64f.conf: add, enable Ethernet support
- Makefile.zephyr: support and default to networked (SLIP) QEMU
- README: describe many gotchas of networked builds
- enable IPv6 networking in addition to IPv4
- add qemu_cortex_m3 config fragment
- main: don't unconditionally dump stats on each GC
- README: network startup issues with frdm_k64f resolved
- modzephyr: add a module for Zephyr-specific things
- modzephyr: fix typo in identifier
- make sure that generated prj.conf is updated only on content changes
- move "minimal" configuration building to a separate wrapper script
- main: nlr_jump_fail: Fix noreturn warning
- main: remove unused __fatal_error()
- main: move lexer constructor to within NLR handler block
- zephyr_getchar: use native k_sem instead of legacy nano_sem
- prj_base.conf: disable legacy kernel compatibility
- prj_base.conf: enable TCP (and UDP explicitly)
- Makefile: rework to use modern, official build integration
- Makefile: add workaround (fix?) for broken builds for DTS targets
- fix NLR segfault in minimal build
- modusocket: initial version of usocket module for Zephyr
- integrate modusocket into build
- modusocket: implement bind() and connect()
- modusocket: implement send()
- modusocket: implement recv() for UDP sockets
- modusocket: implement recv() for TCP sockets
- prj_base.conf: add config for net_buf logging
- modusocket: be sure to use MP_OBJ_FROM_PTR
- modusocket: factor out socket_new() function
- zephyr_getchar: explicitly yield to other threads on char availability
- Makefile: add "test" target, runs testsuite in QEMU
- modusocket: factor out "extended k_fifo API"
- modusocket: implement listen()
- modusocket: socket_bind: Don't set recv callback on STREAM sockets
- modusocket: implement accept()
- mpconfigport.h: fix build if usocket module is disabled
- modmachine: add Signal class
- machine_pin: implement pin protocol for machine.Signal support
- modusocket: call net_nbuf_print_frags() in recv callback if DEBUG > 1
- modusocket: strip packet header right in the receive callback
- modmachine: implement machine.reset()
- main: configure IPv4 netmask and gateway to allow Internet access
- add 96b_carbon configuration
- modusocket: refactor send() into stream write() method
- modusocket: enable stream write() method
- modusocket: refactor recv() into stream read() method
- modusocket: add read/readline/readinto stream methods
- modusocket: sock_read: Check socket status only at the start of packet
- modusocket: add dummy makefile() implementation
- Makefile: add debugserver Zephyr target
- mpconfigport.h: enable line number information for scripts
- main: remove superfluous include
- modusocket: add dummy setsockopt() implementation
- modusocket: add SOL_SOCKET and SO_REUSEADDR constants
- prj_qemu_x86.conf: bump RAM size to 320K
- README: update to require Zephyr 1.8
- modusocket: wrap pkt_get_info() call
- modusocket: update for net_pkt refactor
- modusocket: switch to net_pkt_append() returning length
- modusocket: if there're no packets in recv_q, cancel waiter
- modusocket: implement getaddrinfo()
- modusocket: first step to switch to alternative FIFO processing
- modusocket: get rid of cur_pkt object member
- main: check default netif before applying operations to it
- modusocket: getaddrinfo: Use RAISE_ERRNO for proper error decoding
- modusocket: getaddrinfo: Raise OSError on resolution timeout, etc
- modusocket: use DEBUG_PRINT macro name as other modules do
- rename machine.Pin high/low methods to on/off
- don't send more than MTU allows
- modusocket: handle a case when recv_q is empty when EOF is signaled
pic16bit port:
- main: make nlr_jump_fail never return
- main: make mp_lexer_new_from_file raise an exception
README:
- explicitly mention "await" support, and formatting for keywords
- add link to docs.micropython.org
- describe extmod/ dir
- change Travis & Coveralls badges to not use link references
travis:
- unconditionally run coveralls analysis, even if others failed
- change an stmhal rule to build PYBV11 instead of default PYBV10
gitattributes:
- add .mpy files to list of binary files
- remove obsolete lines
docs:
- fix some minor spelling mistakes
- add documentation for lcd160cr module
- pyboard/tutorial: add tutorial for LCD160CR
- library/lcd160cr: fix set_brightness range, should be 0..31
- machine.Timer: move WiPy adhoc parts to its documentation
- machine: add explicit note on machine module level and scope
- usocket: clarify exceptions used
- usocket: elaborate "Constants" section
- usocket: clarify description of various methods
- usocket: dedent Methods section
- uio: describe differences between uPy an CPy stream hierarchy
- conf.py: add myself as a copyright holder on the docs
- uio: typo fixes/lexical improvements
- pyboard/tutorial/lcd160cr_skin: fix typo, get_touched->get_touch
- for LCD160CR driver and tutorial, add link to positioning image
- esp8266/tutorial: specify the baudrate in picocom example command
- add M-logo as favicon
- library/pyb.Pin: minor typo fix, B6 should be A0
- library/machine: make separate TOC for WiPy vs non-WiPy
- uos: remove mention of uos.sep
- library/lcd160cr: mention the valid values for set_power() method
- modify Makefile and indexes to generate cPy-differences pages
- uhashlib: provide port-neutral description
- Makefile: define and use PYTHON as the interpreter for CPYDIFF
- machine: fix formatting of Constants section
- library/lcd160cr: add note about supported JPEG format/encodings
- library: add framebuf documentation
- library/lcd160cr: add link to framebuf page
- esp8266/tutorial: update since esptool 1.3 added Python 3 support
- library/framebuf: fix typo in bit-width for MVLSB description
- library/machine.I2C: fix scan() doc to match implementation
- library/btree: add btree module docs
- utime: de-conditionalize description of sleep_ms() and friends
- uos: de-conditionalize statvfs() description
- machine.SPI: remove outdated wipy chunk
- machine.Pin: move wipy-specific details to its own docs
- machine.Pin: move wipy-specific methods to its docs
- esp8266/general: start explicit "Known Issues", mentioned RTC inaccuracy
- library/builtins: int: Add notice on byteorder param for to/from_bytes
- library/machine.UART: remove some conditionals
- utime: deconditionalize description of sleep()
- usocket: deconditionalize
- uhashlib: deconditionalize
- esp8266/tutorial/intro: reword section on flash size requirement
- library/micropython: deconditionalize
- library/uos: urandom: Generalize description
- library/ussl: deconditionalize, wipy notes moved to its documentation
- machine.UART: deconditionalize normal methods
- machine: move machine.main() misnomer to wipy's known issues
- library/machine: typo fix in machine_callbacks section
- library/machine.UART: remove pyboard-specific section
- wipy/quickref: update reference for change to I2C API
- wipy/general: add section about specifics of I2C implementation
- library/machine.I2C: deconditionalise all methods
- library/machine.*: add cross-reference label to individual classes
- esp8266/quickref: add links from quickref page to machine classes
- library/machine.I2C: remove WiPy-specific return values
- library/machine.SPI: fix formatting of bullet list to stop warning
- library/uos: add description of uos.ilistdir() function
- machine.Pin: there's no toggle() method in MicroPython hardware API
- machine.Signal: add initial draft description of Signal class
- library/index: add important summary of the intro section as warning
- change single occurrence of "Micropython" to "MicroPython"
- library/micropython: document the newer micropython functions
- library/machine.UART: update and improve uart.any() docs
- library/machine.Pin: remove .id() method and .board class attr
examples:
- hwapi: use Signal for inverted LED on ESP-12
- hwapi: consistently use Signal class to define LEDs
- button_reaction: update for time_pulse_us() no longer raising exc
- hwapi: add hwconfig_pyboard.py for pyboard
- hwapi: be sure to import Signal when it's used
- hwapi/soft_pwm: use Signal on()/off() methods
- embedding/README: convert to markdown, grammar and clarity fixes
- embedding: place lexer constructor within NLR handler block
- hwapi: add config for Zephyr port of 96Boards Carbon
- hwapi/hwconfig*: use inline Signal() args where possible
- hwapi/soft_pwm2_uasyncio: update for call_later_ms()
Diffstat (limited to 'docs')
51 files changed, 1871 insertions, 734 deletions
diff --git a/docs/Makefile b/docs/Makefile index d81d11eeb2..e9c128e900 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -2,10 +2,14 @@ # # 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 @@ -48,11 +52,18 @@ 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)/* -html: +cpydiff: + @echo "Generating MicroPython Differences." + rm -f $(GENRSTDIR)/* + cd $(CPYDIFFDIR) && $(PYTHON) $(CPYDIFF) + +html: cpydiff $(SPHINXBUILD) $(FORCE) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." @@ -106,20 +117,20 @@ epub: @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." -latex: +latex: cpydiff $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." -latexpdf: +latexpdf: cpydiff $(SPHINXBUILD) $(FORCE) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." -latexpdfja: +latexpdfja: cpydiff $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja diff --git a/docs/conf.py b/docs/conf.py index 6026aee56a..e813f23836 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -90,16 +90,16 @@ source_suffix = '.rst' # General information about the project. project = 'MicroPython' -copyright = '2014-2016, Damien P. George and contributors' +copyright = '2014-2017, Damien P. George, Paul Sokolovsky, and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '1.8' +version = '1.9' # The full version, including alpha/beta/rc tags. -release = '1.8.7' +release = '1.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -178,7 +178,7 @@ else: # 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 = None +html_favicon = 'favicon.ico' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -253,7 +253,7 @@ latex_elements = { # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'MicroPython.tex', 'MicroPython Documentation', - 'Damien P. George and contributors', 'manual'), + 'Damien P. George, Paul Sokolovsky, and contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -283,7 +283,7 @@ latex_documents = [ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'micropython', 'MicroPython Documentation', - ['Damien P. George and contributors'], 1), + ['Damien P. George, Paul Sokolovsky, and contributors'], 1), ] # If true, show URL addresses after external links. @@ -297,7 +297,7 @@ man_pages = [ # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'MicroPython', 'MicroPython Documentation', - 'Damien P. George and contributors', 'MicroPython', 'One line description of project.', + 'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.', 'Miscellaneous'), ] diff --git a/docs/differences/index_template.txt b/docs/differences/index_template.txt new file mode 100644 index 0000000000..6ade2c2dab --- /dev/null +++ b/docs/differences/index_template.txt @@ -0,0 +1,8 @@ +MicroPython Differences from CPython +==================================== + +The operations listed in this section produce conflicting results in MicroPython when compared to standard Python. + +.. toctree:: + :maxdepth: 2 + diff --git a/docs/esp8266/general.rst b/docs/esp8266/general.rst index cd659f80a9..47df80d7ba 100644 --- a/docs/esp8266/general.rst +++ b/docs/esp8266/general.rst @@ -107,8 +107,16 @@ 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 ``ntpdate.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 diff --git a/docs/esp8266/quickref.rst b/docs/esp8266/quickref.rst index 845a94ba7b..5ff33e02bd 100644 --- a/docs/esp8266/quickref.rst +++ b/docs/esp8266/quickref.rst @@ -88,7 +88,7 @@ Use the :mod:`time <utime>` module:: Timers ------ -Virtual (RTOS-based) timers are supported. Use the ``machine.Timer`` class +Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class with timer ID of -1:: from machine import Timer @@ -102,7 +102,7 @@ The period is in milliseconds. Pins and GPIO ------------- -Use the ``machine.Pin`` class:: +Use the :ref:`machine.Pin <machine.Pin>` class:: from machine import Pin @@ -155,7 +155,7 @@ 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 ``machine.ADC`` class:: +Use the :ref:`machine.ADC <machine.ADC>` class:: from machine import ADC @@ -166,7 +166,8 @@ Software SPI bus ---------------- There are two SPI drivers. One is implemented in software (bit-banging) -and works on all pins:: +and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>` +class:: from machine import Pin, SPI @@ -208,7 +209,8 @@ constructor and init (as those are fixed):: I2C bus ------- -The I2C driver is implemented in software and works on all pins:: +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 diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst index fe824cffff..67ed0ba67c 100644 --- a/docs/esp8266/tutorial/intro.rst +++ b/docs/esp8266/tutorial/intro.rst @@ -20,9 +20,12 @@ 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 512k. A board with this amount of -flash will not have room for a filesystem, but otherwise is fully functional. -If your board has 1Mbyte or more of flash then it will support a filesystem. +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 @@ -72,15 +75,17 @@ 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/themadinventor/esptool/>`__, or install it -using pip (at least version 1.2.1 is required):: +this tool here: `<https://github.com/espressif/esptool/>`__, or install it +using pip:: pip install esptool -It requires Python 2.7, so you may need to use ``pip2`` instead of ``pip`` in -the command above. 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. +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:: @@ -88,7 +93,7 @@ Using esptool.py you can erase the flash with the command:: And then deploy the new firmware using:: - esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-2016-05-03-v1.8.bin + 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 @@ -99,7 +104,7 @@ 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-2016-05-03-v1.8.bin + 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! @@ -158,7 +163,9 @@ after it, here are troubleshooting recommendations: 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). + 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. @@ -179,7 +186,7 @@ after it, here are troubleshooting recommendations: 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/themadinventor/esptool + 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 diff --git a/docs/esp8266/tutorial/repl.rst b/docs/esp8266/tutorial/repl.rst index 1922da128d..21e889c9a8 100644 --- a/docs/esp8266/tutorial/repl.rst +++ b/docs/esp8266/tutorial/repl.rst @@ -24,7 +24,7 @@ terminal programs that will work, so pick your favourite! For example, on Linux you can try running:: - picocom /dev/ttyUSB0 + 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, diff --git a/docs/esp8266_contents.rst b/docs/esp8266_contents.rst index 30def3df2b..7c35460bd9 100644 --- a/docs/esp8266_contents.rst +++ b/docs/esp8266_contents.rst @@ -8,4 +8,5 @@ MicroPython documentation contents esp8266/tutorial/index.rst library/index.rst reference/index.rst + genrst/index.rst license.rst diff --git a/docs/esp8266_index.rst b/docs/esp8266_index.rst index 82de9d6dfd..8654c43aa0 100644 --- a/docs/esp8266_index.rst +++ b/docs/esp8266_index.rst @@ -5,6 +5,7 @@ MicroPython documentation and references esp8266/quickref.rst library/index.rst + genrst/index.rst license.rst esp8266_contents.rst diff --git a/docs/library/btree.rst b/docs/library/btree.rst new file mode 100644 index 0000000000..aebcbc1604 --- /dev/null +++ b/docs/library/btree.rst @@ -0,0 +1,144 @@ +: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 section, etc. + 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" + + # 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, cachesize=0, pagesize=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 + paramters of the database operation (most users will not need them): + + * `flags` - Currently unused. + * `cachesize` - Suggested maximum memory cache size in bytes. For a + board with enough memory using larger values may improve performance. + The value is only a recommendation, the module may use more memory if + values set too low. + * `pagesize` - Page size used for the nodes in BTree. Acceptable range + is 512-65536. If 0, underlying I/O block size will be used (the best + compromise between memory usage and performance). + * `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 streamw 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) +.. method:: btree.get(key, default=None) +.. method:: btree.__setitem__(key, val) +.. method:: btree.__detitem__(key) +.. method:: 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]]]) +.. method:: btree.values([start_key, [end_key, [flags]]]) +.. method:: 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. diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index d53c4d377b..46f762660a 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -67,6 +67,16 @@ All builtin functions are described here. They are also available via .. 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() diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst new file mode 100644 index 0000000000..61f0635f36 --- /dev/null +++ b/docs/library/framebuf.rst @@ -0,0 +1,152 @@ +: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 = 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; + valid values are ``framebuf.MVLSB``, ``framebuf.RGB565`` + and ``framebuf.GS4_HMSB``. MVLSB is monochrome 1-bit color, + RGB565 is RGB 16-bit color, and GS4_HMSB is grayscale 4-bit color. + 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's 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.GS4_HMSB + + Grayscale (4-bit) color format diff --git a/docs/library/index.rst b/docs/library/index.rst index 3621f9d880..770920a1ff 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -1,6 +1,17 @@ MicroPython libraries ===================== +.. warning:: + + Important summary of this section + + * MicroPython implements a subset of Python functionality for each module. + * To ease extensibility, MicroPython versions of standard Python modules + usually have ``u`` (micro) prefix. + * Any particular MicroPython variant or port may miss any feature/function + described in this general documentation, due to resource constraints. + + This chapter describes modules (function and class libraries) which are built into MicroPython. There are a few categories of modules: @@ -153,6 +164,8 @@ the following libraries. .. toctree:: :maxdepth: 1 + btree.rst + framebuf.rst machine.rst micropython.rst network.rst @@ -170,6 +183,7 @@ the following libraries. :maxdepth: 2 pyb.rst + lcd160cr.rst .. only:: port_wipy diff --git a/docs/library/lcd160cr.rst b/docs/library/lcd160cr.rst new file mode 100644 index 0000000000..bd47412986 --- /dev/null +++ b/docs/library/lcd160cr.rst @@ -0,0 +1,394 @@ +:mod:`lcd160cr` --- control of LCD160CR display +=============================================== + +.. module:: lcd160cr + :synopsis: control of LCD160CR display + +This module provides control of the MicroPython LCD160CR display. + +.. image:: http://micropython.org/resources/LCD160CRv10-persp.jpg + :alt: LCD160CRv1.0 picture + :width: 640px + +Further resources are available via the following links: + +* `LCD160CRv1.0 reference manual <http://micropython.org/resources/LCD160CRv10-refmanual.pdf>`_ (100KiB PDF) +* `LCD160CRv1.0 schematics <http://micropython.org/resources/LCD160CRv10-schematics.pdf>`_ (1.6MiB PDF) + +class LCD160CR +-------------- + +The LCD160CR class provides an interface to the display. Create an +instance of this class and use its methods to draw to the LCD and get +the status of the touch panel. + +For example:: + + import lcd160cr + + lcd = lcd160cr.LCD160CR('X') + lcd.set_orient(lcd160cr.PORTRAIT) + lcd.set_pos(0, 0) + lcd.set_text_color(lcd.rgb(255, 0, 0), lcd.rgb(0, 0, 0)) + lcd.set_font(1) + lcd.write('Hello MicroPython!') + print('touch:', lcd.get_touch()) + +Constructors +------------ + +.. class:: LCD160CR(connect=None, \*, pwr=None, i2c=None, spi=None, i2c_addr=98) + + Construct an LCD160CR object. The parameters are: + + - `connect` is a string specifying the physical connection of the LCD + display to the board; valid values are "X", "Y", "XY", "YX". + Use "X" when the display is connected to a pyboard in the X-skin + position, and "Y" when connected in the Y-skin position. "XY" + and "YX" are used when the display is connected to the right or + left side of the pyboard, respectively. + - `pwr` is a Pin object connected to the LCD's power/enabled pin. + - `i2c` is an I2C object connected to the LCD's I2C interface. + - `spi` is an SPI object connected to the LCD's SPI interface. + - `i2c_addr` is the I2C address of the display. + + One must specify either a valid `connect` or all of `pwr`, `i2c` and `spi`. + If a valid `connect` is given then any of `pwr`, `i2c` or `spi` which are + not passed as parameters (ie 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 +`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 +.. data:: lcd160cr.LANDSCAPE +.. data:: lcd160cr.PORTRAIT_UPSIDEDOWN +.. data:: lcd160cr.LANDSCAPE_UPSIDEDOWN + + orientation of the display, used by :meth:`LCD160CR.set_orient` + +.. data:: lcd160cr.STARTUP_DECO_NONE +.. data:: lcd160cr.STARTUP_DECO_MLOGO +.. data:: lcd160cr.STARTUP_DECO_INFO + + type of start-up decoration, can be or'd together, used by + :meth:`LCD160CR.set_startup_deco` diff --git a/docs/library/machine.ADC.rst b/docs/library/machine.ADC.rst index 2752878ff3..4c7a04d74f 100644 --- a/docs/library/machine.ADC.rst +++ b/docs/library/machine.ADC.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.ADC: class ADC -- analog to digital conversion ========================================= diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst index cdeb246ebb..a1b4178905 100644 --- a/docs/library/machine.I2C.rst +++ b/docs/library/machine.I2C.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.I2C: class I2C -- a two-wire serial protocol ======================================= @@ -9,86 +10,55 @@ 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. -.. only:: port_wipy +Printing the I2C object gives you information about its configuration. - Example:: +Example usage:: - from machine import I2C + from machine import I2C - i2c = I2C(0) # create on bus 0 - i2c = I2C(0, I2C.MASTER) # create and init as a master - i2c.init(I2C.MASTER, baudrate=20000) # init as a master - i2c.deinit() # turn off the peripheral + 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 -Printing the i2c object gives you information about its configuration. + i2c.scan() # scan for slaves, returning a list of 7-bit addresses -.. only:: port_wipy + 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 - A master must specify the recipient's address:: - - i2c.init(I2C.MASTER) - i2c.writeto(0x42, '123') # send 3 bytes to slave with address 0x42 - i2c.writeto(addr=0x42, b'456') # keyword for address - - Master also has other methods:: - - i2c.scan() # scan for slaves on the bus, returning - # a list of valid addresses - i2c.readfrom_mem(0x42, 2, 3) # read 3 bytes from memory of slave 0x42, - # starting at address 2 in the slave - i2c.writeto_mem(0x42, 2, 'abc') # write 'abc' (3 bytes) to memory of slave 0x42 - # starting at address 2 in the slave, timeout after 1 second + 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 ------------ -.. only:: port_wipy - - .. class:: I2C(bus, ...) - - Construct an I2C object on the given bus. `bus` can only be 0. - If the bus is not given, the default one will be selected (0). +.. class:: I2C(id=-1, \*, scl, sda, freq=400000) -.. only:: not port_wipy + Construct and return a new I2C object using the following parameters: - .. class:: I2C(id=-1, \*, scl, sda, freq=400000) - - Construct and return a new I2C object using the following parameters: - - - `id` identifies the 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. + - `id` identifies the 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 --------------- -.. only:: port_wipy - - .. method:: I2C.init(mode, \*, baudrate=100000, pins=(SDA, SCL)) - - Initialise the I2C bus with the given parameters: - - - ``mode`` must be ``I2C.MASTER`` - - ``baudrate`` is the SCL clock rate - - ``pins`` is an optional tuple with the pins to assign to the I2C bus. +.. method:: I2C.init(scl, sda, \*, freq=400000) -.. only:: port_esp8266 + Initialise the I2C bus with the given arguments: - .. 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 + - `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() @@ -100,9 +70,7 @@ General Methods 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 read bit) is sent on the bus. - - Note: on WiPy the I2C object must be in master mode for this method to be valid. + its address (including a write bit) is sent on the bus. Primitive I2C operations ------------------------ @@ -192,8 +160,7 @@ methods are convenience functions to communicate with such devices. The argument `addrsize` specifies the address size in bits (on ESP8266 this argument is not recognised and the address size is always 8 bits). - On WiPy the return value is the number of bytes read. Otherwise the - return value is `None`. + The method returns `None`. .. method:: I2C.writeto_mem(addr, memaddr, buf, \*, addrsize=8) @@ -202,14 +169,4 @@ methods are convenience functions to communicate with such devices. The argument `addrsize` specifies the address size in bits (on ESP8266 this argument is not recognised and the address size is always 8 bits). - On WiPy the return value is the number of bytes written. Otherwise the - return value is `None`. - -Constants ---------- - -.. data:: I2C.MASTER - - for initialising the bus to master mode - - Availability: WiPy. + The method returns `None`. diff --git a/docs/library/machine.Pin.rst b/docs/library/machine.Pin.rst index 952131f099..2efd84688a 100644 --- a/docs/library/machine.Pin.rst +++ b/docs/library/machine.Pin.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.Pin: class Pin -- control I/O pins ============================= @@ -38,58 +39,6 @@ Usage Model:: # configure an irq callback p0.irq(lambda p:print(p)) -.. only:: port_wipy - - On the WiPy board the pins are identified by their string id:: - - from machine import Pin - g = machine.Pin('GP9', mode=Pin.OUT, pull=None, drive=Pin.MED_POWER, alt=-1) - - You can also configure the Pin to generate interrupts. For instance:: - - from machine import Pin - - def pincb(pin): - print(pin.id()) - - pin_int = Pin('GP10', mode=Pin.IN, pull=Pin.PULL_DOWN) - pin_int.irq(trigger=Pin.IRQ_RISING, handler=pincb) - # the callback can be triggered manually - pin_int.irq()() - # to disable the callback - pin_int.irq().disable() - - 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. - - For the ``drive`` parameter the strengths are: - - - ``Pin.LOW_POWER`` - 2mA drive capability. - - ``Pin.MED_POWER`` - 4mA drive capability. - - ``Pin.HIGH_POWER`` - 6mA drive capability. - - For the ``alt`` parameter please refer to the pinout and alternate functions - table at <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ - for the specific alternate functions that each pin supports. - - For interrupts, the ``priority`` can take values in the range 1-7. And the - ``wake`` parameter has the following properties: - - - If ``wake_from=machine.Sleep.ACTIVE`` any pin can wake the board. - - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, - ``GP11``, GP17`` or ``GP24`` can wake the board. Note that only 1 - of this pins can be enabled as a wake source at the same time, so, only - the last enabled pin as a ``machine.Sleep.SUSPENDED`` wake source will have effect. - - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, - ``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the - 6 pins can be enabled as a ``machine.Sleep.HIBERNATE`` wake source at the same time. - Constructors ------------ @@ -209,20 +158,6 @@ Methods and get the value of the pin. It is equivalent to Pin.value([x]). See :meth:`Pin.value` for more details. -.. method:: Pin.toggle() - - Toggle the output value of the pin. Equivalent to ``pin.value(not pin.out_value())``. - Returns ``None``. - - Not all ports implement this method. - - Availability: WiPy. - -.. method:: Pin.id() - - Get the pin identifier. This may return the ``id`` as specified in the - constructor. Or it may return a canonical software-specific pin id. - .. method:: Pin.mode([mode]) Get or set the pin mode. @@ -277,29 +212,6 @@ Methods This method returns a callback object. -.. only:: port_wipy - - .. method:: Pin.alt_list() - - Returns a list of the alternate functions supported by the pin. List items are - a tuple of the form: ``('ALT_FUN_NAME', ALT_FUN_INDEX)`` - - Availability: WiPy. - - -Attributes ----------- - -.. class:: Pin.board - - Contains all ``Pin`` objects supported by the board. Examples:: - - Pin.board.GP25 - led = Pin(Pin.board.GP25, mode=Pin.OUT) - Pin.board.GP2.alt_list() - - Availability: WiPy. - Constants --------- diff --git a/docs/library/machine.RTC.rst b/docs/library/machine.RTC.rst index 6dc8b3e9ab..2a53b91469 100644 --- a/docs/library/machine.RTC.rst +++ b/docs/library/machine.RTC.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.RTC: class RTC -- real time clock ============================ diff --git a/docs/library/machine.SD.rst b/docs/library/machine.SD.rst index 21c28aa200..0eb024602f 100644 --- a/docs/library/machine.SD.rst +++ b/docs/library/machine.SD.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.SD: class SD -- secure digital memory card ====================================== diff --git a/docs/library/machine.SPI.rst b/docs/library/machine.SPI.rst index dda6314fa2..080f6fdfb2 100644 --- a/docs/library/machine.SPI.rst +++ b/docs/library/machine.SPI.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.SPI: class SPI -- a Serial Peripheral Interface bus protocol (master side) ===================================================================== @@ -6,22 +7,10 @@ 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 particualr device on a bus with which +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). -.. only:: port_wipy - - See usage model of I2C; SPI is very similar. Main difference is - parameters to init the SPI bus:: - - from machine import SPI - spi = SPI(0, mode=SPI.MASTER, baudrate=1000000, polarity=0, phase=0, firstbit=SPI.MSB) - - Only required parameter is mode, must be SPI.MASTER. 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. - Constructors ------------ @@ -51,12 +40,12 @@ Methods - ``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 constructore), pins are fixed + 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`` paramter. + specify them as a tuple of ``pins`` parameter. .. method:: SPI.deinit() diff --git a/docs/library/machine.Signal.rst b/docs/library/machine.Signal.rst new file mode 100644 index 0000000000..4869086274 --- /dev/null +++ b/docs/library/machine.Signal.rst @@ -0,0 +1,96 @@ +.. currentmodule:: machine +.. _machine.Signal: + +class Signal -- control and sense external I/O devices +====================================================== + +The Signal class is a simple extension of 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. Summing up, 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 +whether different users have an active-high or active-low LED, a normally +open or normally closed relay - you can develop single, nicely looking +application which works with each of them, and capture hardware +configuration differences in few lines on the config file of your app. + +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 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 developed 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. diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst index 12db58d5c4..ef46f9dd7c 100644 --- a/docs/library/machine.Timer.rst +++ b/docs/library/machine.Timer.rst @@ -1,53 +1,18 @@ .. currentmodule:: machine +.. _machine.Timer: -class Timer -- control internal timers +class Timer -- control hardware timers ====================================== -.. only:: port_wipy - - Timers can be used for a great variety of tasks, calling a function periodically, - counting events, and generating a PWM signal are among the most common use cases. - Each timer consists of two 16-bit channels and this channels can be tied together to - form one 32-bit timer. The operating mode needs to be configured per timer, but then - the period (or the frequency) can be independently configured on each channel. - By using the callback method, the timer event can call a Python function. - - Example usage to toggle an LED at a fixed frequency:: - - from machine import Timer - from machine import Pin - led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED - tim = Timer(3) # create a timer object using timer 3 - tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode - tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz - tim_ch.irq(handler=lambda t:led.toggle(), trigger=Timer.TIMEOUT) # toggle a LED on every cycle of the timer - - Example using named function for the callback:: - - from machine import Timer - from machine import Pin - tim = Timer(1, mode=Timer.PERIODIC, width=32) - tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer +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). - led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED - - def tick(timer): # we will receive the timer object when being called - global led - led.toggle() # toggle the LED - - tim_a.irq(handler=tick, trigger=Timer.TIMEOUT) # create the interrupt - - Further examples:: - - from machine import Timer - tim1 = Timer(1, mode=Timer.ONE_SHOT) # initialize it in one shot mode - tim2 = Timer(2, mode=Timer.PWM) # initialize it in PWM mode - tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges - tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=5000) # start the PWM on channel B with a 50% duty cycle - tim2_ch.freq(20) # set the frequency (can also get) - tim2_ch.duty_cycle(3010) # set the duty cycle to 30.1% (can also get) - tim2_ch.duty_cycle(3020, Timer.NEGATIVE) # set the duty cycle to 30.2% and change the polarity to negative - tim2_ch.period(2000000) # change the period to 2 seconds +See discussion of :ref:`important constraints <machine_callbacks>` on +Timer callbacks. .. note:: @@ -61,10 +26,8 @@ Constructors .. class:: Timer(id, ...) - .. only:: port_wipy - - Construct a new timer object of the given id. ``id`` can take values from 0 to 3. - + Construct a new timer object of the given id. Id of -1 constructs a + virtual timer (if supported by a board). Methods ------- @@ -94,8 +57,7 @@ Methods .. method:: Timer.deinit() - Deinitialises the timer. Disables all channels and associated IRQs. - Stops the timer, and disables the timer peripheral. + Deinitialises the timer. Stops the timer, and disables the timer peripheral. .. only:: port_wipy @@ -138,17 +100,17 @@ Methods - ``GP10`` on Timer 3 channel A. - ``GP11`` on Timer 3 channel B. -class TimerChannel --- setup a channel for a timer -================================================== +.. only:: port_wipy -Timer channels are used to generate/capture a signal using a timer. + class TimerChannel --- setup a channel for a timer + ================================================== -TimerChannel objects are created using the Timer.channel() method. + Timer channels are used to generate/capture a signal using a timer. -Methods -------- + TimerChannel objects are created using the Timer.channel() method. -.. only:: port_wipy + Methods + ------- .. method:: timerchannel.irq(\*, trigger, priority=1, handler=None) @@ -194,22 +156,5 @@ Constants .. data:: Timer.ONE_SHOT .. data:: Timer.PERIODIC -.. data:: Timer.PWM - - Selects the timer operating mode. - -.. data:: Timer.A -.. data:: Timer.B - - Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when - using a 32-bit timer. - -.. data:: Timer.POSITIVE -.. data:: Timer.NEGATIVE - - Timer channel polarity selection (only relevant in PWM mode). - -.. data:: Timer.TIMEOUT -.. data:: Timer.MATCH - Timer channel IRQ triggers. + Timer operating mode. diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst index 0b6b24e894..f9c8efef78 100644 --- a/docs/library/machine.UART.rst +++ b/docs/library/machine.UART.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.UART: class UART -- duplex serial communication bus ============================================= @@ -15,17 +16,13 @@ UART objects can be created and initialised using:: uart = UART(1, 9600) # init with given baudrate uart.init(9600, bits=8, parity=None, stop=1) # init with given parameters -.. only:: port_machineoard +Supported paramters differ on a board: - Bits can be 7, 8 or 9. Parity can be None, 0 (even) or 1 (odd). Stop can be 1 or 2. - - *Note:* with parity=None, only 8 and 9 bits are supported. With parity enabled, - only 7 and 8 bits are supported. - -.. only:: port_wipy - - Bits can be 5, 6, 7, 8. Parity can be ``None``, ``UART.EVEN`` or ``UART.ODD``. Stop can be 1 or 2. +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:: @@ -36,33 +33,12 @@ using the standard stream methods:: uart.readinto(buf) # read and store into the given buffer uart.write('abc') # write the 3 characters -.. only:: port_pyboard - - Individual characters can be read/written using:: - - uart.readchar() # read 1 character and returns it as an integer - uart.writechar(42) # write 1 character - - To check if there is anything to be read, use:: - - uart.any() # returns True if any characters waiting - -.. only:: port_wipy - - To check if there is anything to be read, use:: - - uart.any() # returns the number of characters available for reading - Constructors ------------ -.. only:: port_wipy +.. class:: UART(id, ...) - .. class:: UART(bus, ...) - - Construct a UART object on the given bus. ``bus`` can be 0 or 1. - If the bus is not given, the default one will be selected (0) or the selection - will be made based on the given pins. + Construct a UART object of the given id. Methods ------- @@ -75,7 +51,7 @@ Methods - ``baudrate`` is the clock rate. - ``bits`` is the number of bits per character, 7, 8 or 9. - - ``parity`` is the parity, ``None``, ``UART.EVEN`` or ``UART.ODD``. + - ``parity`` is the parity, ``None``, 0 (even) or 1 (odd). - ``stop`` is the number of stop bits, 1 or 2. - ``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. @@ -83,15 +59,22 @@ Methods 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=None, no pin assignment will be made. -.. only:: not port_esp8266 +.. method:: UART.deinit() - .. method:: UART.deinit() + Turn off the UART bus. - Turn off the UART bus. +.. method:: UART.any() - .. 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. - Return the number of characters 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]) @@ -121,13 +104,10 @@ Methods Return value: number of bytes written or ``None`` on timeout. -.. only:: not port_esp8266 - - .. method:: UART.sendbreak() +.. method:: UART.sendbreak() - Send a break condition on the bus. This drives the bus low for a duration - of 13 bits. - Return value: ``None``. + 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. .. only:: port_wipy @@ -154,16 +134,9 @@ Methods Returns an irq object. -.. only:: not port_esp8266 - Constants --------- - .. data:: UART.EVEN - .. data:: UART.ODD - - parity types (along with ``None``) - .. data:: UART.RX_ANY IRQ trigger sources diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst index 1d79b4c4ed..5ca6dce45d 100644 --- a/docs/library/machine.WDT.rst +++ b/docs/library/machine.WDT.rst @@ -1,4 +1,5 @@ .. currentmodule:: machine +.. _machine.WDT: class WDT -- watchdog timer =========================== diff --git a/docs/library/machine.rst b/docs/library/machine.rst index 7870da2ffc..c2c6b83fd6 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -1,10 +1,23 @@ -:mod:`machine` --- functions related to the board -================================================= +:mod:`machine` --- functions related to the hardware +==================================================== .. module:: machine - :synopsis: functions related to the board + :synopsis: functions related to the hardware -The ``machine`` module contains specific functions related to the board. +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 ``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 ----------------------- @@ -39,16 +52,7 @@ Power related functions .. function:: freq() - .. only:: not port_wipy - - Returns CPU frequency in hertz. - - .. only:: port_wipy - - Returns a tuple of clock frequencies: ``(sysclk,)`` - These correspond to: - - - sysclk: frequency of the CPU + Returns CPU frequency in hertz. .. function:: idle() @@ -81,13 +85,6 @@ Miscellaneous functions .. only:: port_wipy - .. function:: main(filename) - - Set the filename of the main script to run after boot.py is finished. If - this function is not called then the default file main.py will be executed. - - It only makes sense to call this function from within boot.py. - .. function:: rng() Return a 24-bit software generated random number. @@ -105,12 +102,15 @@ Miscellaneous functions microseconds. The `pulse_level` argument should be 0 to time a low pulse or 1 to time a high pulse. - The function first waits while the pin input is different to the `pulse_level` - parameter, then times the duration that the pin is equal to `pulse_level`. + 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 raise an OSError with ETIMEDOUT if either of the waits is - longer than the given timeout value (which is in microseconds). + 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). .. _machine_constants: @@ -118,29 +118,45 @@ Constants --------- .. data:: machine.IDLE -.. data:: machine.SLEEP -.. data:: machine.DEEPSLEEP + machine.SLEEP + machine.DEEPSLEEP - irq wake values + IRQ wake values. .. data:: machine.PWRON_RESET -.. data:: machine.HARD_RESET -.. data:: machine.WDT_RESET -.. data:: machine.DEEPSLEEP_RESET -.. data:: machine.SOFT_RESET + machine.HARD_RESET + machine.WDT_RESET + machine.DEEPSLEEP_RESET + machine.SOFT_RESET - reset causes + Reset causes. .. data:: machine.WLAN_WAKE -.. data:: machine.PIN_WAKE -.. data:: machine.RTC_WAKE + machine.PIN_WAKE + machine.RTC_WAKE - wake reasons + Wake-up reasons. Classes ------- -.. toctree:: +.. only:: not port_wipy + + .. toctree:: + :maxdepth: 1 + + machine.I2C.rst + machine.Pin.rst + machine.Signal.rst + machine.RTC.rst + machine.SPI.rst + machine.Timer.rst + machine.UART.rst + machine.WDT.rst + +.. only:: port_wipy + + .. toctree:: :maxdepth: 1 machine.ADC.rst diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst index 14e4c917e0..7f40028565 100644 --- a/docs/library/micropython.rst +++ b/docs/library/micropython.rst @@ -7,25 +7,31 @@ Functions --------- -.. only:: port_pyboard or port_unix - - .. 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:: 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 `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. .. function:: alloc_emergency_exception_buf(size) @@ -37,3 +43,74 @@ Functions 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. + +.. 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(fun, arg) + + Schedule the function `fun` 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. + + There is a finite stack to hold the scheduled functions and `schedule` + will raise a `RuntimeError` if the stack is full. diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index 4f589fff89..b766c5280c 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -21,7 +21,7 @@ Usage Model: CPU pins which correspond to the board pins are available 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.B6`` are the same pin. + ``pyb.Pin.cpu.A0`` are the same pin. You can also use strings:: diff --git a/docs/library/pyb.rst b/docs/library/pyb.rst index 910b2f45b4..9c4933808a 100644 --- a/docs/library/pyb.rst +++ b/docs/library/pyb.rst @@ -80,6 +80,19 @@ Reset related functions Activate the bootloader without BOOT\* pins. +.. function:: fault_debug(value) + + Enable or disable hard-fault debugging. A hard-fault is when there is a fatal + error in the underlying system, like an invalid memory access. + + If the `value` argument is `False` then the board will automatically reset if + there is a hard fault. + + If `value` is `True` then, when the board has a hard fault, it will print the + registers and the stack trace, and then cycle the LEDs indefinitely. + + The default value is disabled, i.e. to automatically reset. + Interrupt related functions --------------------------- diff --git a/docs/library/uhashlib.rst b/docs/library/uhashlib.rst index 223c72dfe7..cd0216dae9 100644 --- a/docs/library/uhashlib.rst +++ b/docs/library/uhashlib.rst @@ -1,63 +1,41 @@ -:mod:`uhashlib` -- hashing algorithm -==================================== +:mod:`uhashlib` -- hashing algorithms +===================================== .. module:: uhashlib - :synopsis: hashing algorithm + :synopsis: hashing algorithms -.. only:: port_pyboard +This module implements binary data hashing algorithms. The exact inventory +of available algorithms depends on a board. Among the algorithms which may +be implemented: - This module implements binary data hashing algorithms. Currently, it - implements SHA256 algorithm. Choosing SHA256 was a deliberate choice, - as a modern, cryptographically secure algorithm. This means that a - single algorithm can cover both use cases of "any hash algorithm" and - security-related usage, and thus save space omitting legacy algorithms - like MD5 or SHA1. +* SHA256 - The current generation, modern hashing algorithm (of SHA2 series). + It is suitable for cryptographically-secure purposes. Included in the + MicroPython core and any board is recommended to provide this, unless + it has particular code size constraints. -.. only:: port_wipy - - This module implements binary data hashing algorithms. Currently, it - implements SHA1 and SHA256 algorithms only. These two algorithms are - more than enough for today's web applications. +* SHA1 - A previous generation algorithm. Not recommended for new usages, + but SHA1 is a part of number of Internet standards and existing + applications, so boards targetting network connectivity and + interoperatiability will try to provide this. +* MD5 - A legacy algorithm, not considered cryptographically secure. Only + selected boards, targetting interoperatibility with legacy applications, + will offer this. Constructors ------------ -.. only:: port_pyboard - - .. class:: uhashlib.sha256([data]) - - Create a hasher object and optionally feed ``data`` into it. - -.. only:: port_wipy - - .. class:: uhashlib.sha1([data[, block_size]]) - - Create a sha1 hasher object and optionally feed ``data`` or ``data and block_size`` into it. - - .. class:: uhashlib.sha256([data[, block_size]]) - - Create a sha256 hasher object and optionally feed ``data`` or ``data and block_size`` into it. - - .. admonition:: CPython extension - :class: attention - - Due to hardware implementation details of the WiPy, data must be buffered before being - digested, which would make it impossible to calculate the hash of big blocks of data that - do not fit in RAM. In this case, since most likely the total size of the data is known - in advance, the size can be passed to the constructor and hence the HASH hardware engine - of the WiPy can be properly initialized without needing buffering. If ``block_size`` is - to be given, an initial chunk of ``data`` must be passed as well. **When using this extension, - care must be taken to make sure that the length of all intermediate chunks (including the - initial one) is a multiple of 4 bytes.** The last chunk may be of any length. - - Example:: - - hash = uhashlib.sha1('abcd1234', 1001) # length of the initial piece is multiple of 4 bytes - hash.update('1234') # also multiple of 4 bytes - ... - hash.update('12345') # last chunk may be of any length - hash.digest() +.. class:: uhashlib.sha256([data]) + + Create an SHA256 hasher object and optionally feed ``data`` into it. + +.. class:: uhashlib.sha1([data]) + + Create an SHA1 hasher object and optionally feed ``data`` into it. + +.. class:: uhashlib.md5([data]) + + Create an MD5 hasher object and optionally feed ``data`` into it. Methods ------- @@ -69,11 +47,7 @@ Methods .. method:: hash.digest() Return hash for all data passed through hash, as a bytes object. After this - method is called, more data cannot be fed into hash any longer. - - .. only:: port_wipy - - SHA1 hashes are 20-byte long. SHA256 hashes are 32-byte long. + method is called, more data cannot be fed into the hash any longer. .. method:: hash.hexdigest() diff --git a/docs/library/uio.rst b/docs/library/uio.rst index 9b4c87df88..1239c6394e 100644 --- a/docs/library/uio.rst +++ b/docs/library/uio.rst @@ -7,6 +7,71 @@ This module contains additional types of stream (file-like) objects and helper functions. +Conceptual hierarchy +-------------------- + +.. admonition:: Difference to CPython + :class: attention + + Conceptual hierarchy of stream base classes is simplified in MicroPython, + as described in this section. + +(Abstract) base stream classes, which serve as a foundation for behavior +of all the concrete classes, adhere to few dichotomies (pair-wise +classifications) in CPython. In MicroPython, they are somewhat simplified +and made implicit to achieve higher efficiencies and save resources. + +An important dichotomy in CPython is unbuffered vs buffered streams. In +MicroPython, all streams are currently unbuffered. This is because all +modern OSes, and even many RTOSes and filesystem drivers already perform +buffering on their side. Adding another layer of buffering is counter- +productive (an issue known as "bufferbloat") and takes precious memory. +Note that there still cases where buffering may be useful, so we may +introduce optional buffering support at a later time. + +But in CPython, another important dichotomy is tied with "bufferedness" - +it's whether a stream may incur short read/writes or not. A short read +is when a user asks e.g. 10 bytes from a stream, but gets less, similarly +for writes. In CPython, unbuffered streams are automatically short +operation susceptible, while buffered are guarantee against them. The +no short read/writes is an important trait, as it allows to develop +more concise and efficient programs - something which is highly desirable +for MicroPython. So, while MicroPython doesn't support buffered streams, +it still provides for no-short-operations streams. Whether there will +be short operations or not depends on each particular class' needs, but +developers are strongly advised to favor no-short-operations behavior +for the reasons stated above. For example, MicroPython sockets are +guaranteed to avoid short read/writes. Actually, at this time, there is +no example of a short-operations stream class in the core, and one would +be a port-specific class, where such a need is governed by hardware +peculiarities. + +The no-short-operations behavior gets tricky in case of non-blocking +streams, blocking vs non-blocking behavior being another CPython dichotomy, +fully supported by MicroPython. Non-blocking streams never wait for +data either to arrive or be written - they read/write whatever possible, +or signal lack of data (or ability to write data). Clearly, this conflicts +with "no-short-operations" policy, and indeed, a case of non-blocking +buffered (and this no-short-ops) streams is convoluted in CPython - in +some places, such combination is prohibited, in some it's undefined or +just not documented, in some cases it raises verbose exceptions. The +matter is much simpler in MicroPython: non-blocking stream are important +for efficient asynchronous operations, so this property prevails on +the "no-short-ops" one. So, while blocking streams will avoid short +reads/writes whenever possible (the only case to get a short read is +if end of file is reached, or in case of error (but errors don't +return short data, but raise exceptions)), non-blocking streams may +produce short data to avoid blocking the operation. + +The final dichotomy is binary vs text streams. MicroPython of course +supports these, but while in CPython text streams are inherently +buffered, they aren't in MicroPython. (Indeed, that's one of the cases +for which we may introduce buffering support.) + +Note that for efficiency, MicroPython doesn't provide abstract base +classes corresponding to the hierarchy above, and it's not possible +to implement, or subclass, a stream class in pure Python. + Functions --------- diff --git a/docs/library/uos.rst b/docs/library/uos.rst index 242e8c3d0b..d1f83d2cc3 100644 --- a/docs/library/uos.rst +++ b/docs/library/uos.rst @@ -37,6 +37,21 @@ Functions Get the current directory. +.. function:: ilistdir([dir]) + + This function returns an iterator which then yields 3-tuples corresponding to + the entries in the directory that it is listing. With no argument it lists the + current directory, otherwise it lists the directory given by `dir`. + + The 3-tuples have the form `(name, type, inode)`: + + - `name` is a string (or bytes if `dir` is a bytes object) and is the name of + the entry; + - `type` is an integer that specifies the type of the entry, with 0x4000 for + directories and 0x8000 for regular files; + - `inode` is an integer corresponding to the inode of the file, and may be 0 + for filesystems that don't have such a notion. + .. function:: listdir([dir]) With no argument, list the current directory. Otherwise list the given directory. @@ -61,28 +76,26 @@ Functions Get the status of a file or directory. -.. only:: port_unix or port_pyboard or port_esp8266 - - .. function:: statvfs(path) +.. function:: statvfs(path) - Get the status of a fileystem. + Get the status of a fileystem. - Returns a tuple with the filesystem information in the following order: + Returns a tuple with the filesystem information in the following order: - * ``f_bsize`` -- file system block size - * ``f_frsize`` -- fragment size - * ``f_blocks`` -- size of fs in f_frsize units - * ``f_bfree`` -- number of free blocks - * ``f_bavail`` -- number of free blocks for unpriviliged users - * ``f_files`` -- number of inodes - * ``f_ffree`` -- number of free inodes - * ``f_favail`` -- number of free inodes for unpriviliged users - * ``f_flag`` -- mount flags - * ``f_namemax`` -- maximum filename length + * ``f_bsize`` -- file system block size + * ``f_frsize`` -- fragment size + * ``f_blocks`` -- size of fs in f_frsize units + * ``f_bfree`` -- number of free blocks + * ``f_bavail`` -- number of free blocks for unpriviliged users + * ``f_files`` -- number of inodes + * ``f_ffree`` -- number of free inodes + * ``f_favail`` -- number of free inodes for unpriviliged users + * ``f_flag`` -- mount flags + * ``f_namemax`` -- maximum filename length - Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail`` - and the ``f_flags`` parameter may return ``0`` as they can be unavailable - in a port-specific implementation. + Parameters related to inodes: ``f_files``, ``f_ffree``, ``f_avail`` + and the ``f_flags`` parameter may return ``0`` as they can be unavailable + in a port-specific implementation. .. function:: sync() @@ -90,8 +103,8 @@ Functions .. function:: urandom(n) - Return a bytes object with n random bytes, generated by the hardware - random number generator. + Return a bytes object with n random bytes. Whenever possible, it is + generated by the hardware random number generator. .. only:: port_wipy @@ -116,10 +129,3 @@ Functions Duplicate the terminal (the REPL) on the passed stream-like object. The given object must at least implement the ``.read()`` and ``.write()`` methods. - -Constants ---------- - -.. data:: sep - - separation character used in paths diff --git a/docs/library/usocket.rst b/docs/library/usocket.rst index c46e8f4c53..71deaebc41 100644 --- a/docs/library/usocket.rst +++ b/docs/library/usocket.rst @@ -7,13 +7,28 @@ This module provides access to the BSD socket interface. -See corresponding `CPython module <https://docs.python.org/3/library/socket.html>`_ for -comparison. +See the corresponding `CPython module <https://docs.python.org/3/library/socket.html>`_ +for comparison. + +.. admonition:: Difference to CPython + :class: attention + + CPython used to have a ``socket.error`` exception which is now deprecated, + and is an alias of OSError. In MicroPython, use OSError directly. + +.. admonition:: Difference to CPython + :class: attention + + For efficiency and consistency, socket objects in MicroPython implement a stream + (file-like) interface directly. In CPython, you need to convert a socket to + a file-like object using ``makefile()`` method. This method is still supported + by MicroPython (but is a no-op), so where compatibility with CPython matters, + be sure to use it. Socket address format(s) ------------------------ -Functions below which expect a network address, accept it in the format of +The functions below which expect a network address, accept it in the format of `(ipv4_address, port)`, where `ipv4_address` is a string with dot-notation numeric IPv4 address, e.g. ``"8.8.8.8"``, and port is integer port number in the range 1-65535. Note the domain names are not accepted as `ipv4_address`, they should be @@ -26,18 +41,6 @@ Functions Create a new socket using the given address family, socket type and protocol number. - .. only:: port_wipy - - .. note:: - - SSL sockets need to be created the following way before wrapping them with - ``ssl.wrap_socket``:: - - import socket - import ssl - s = socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) - ss = ssl.wrap_socket(s) - .. function:: socket.getaddrinfo(host, port) Translate the host/port argument into a sequence of 5-tuples that contain all the @@ -51,33 +54,50 @@ Functions s = socket.socket() s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1]) -.. only:: port_wipy - - Exceptions - ---------- + .. admonition:: Difference to CPython + :class: attention - .. data:: socket.error - .. data:: socket.timeout + CPython raises a ``socket.gaierror`` exception (OSError subclass) in case + of error in this function. MicroPython doesn't have ``socket.gaierror`` + and raises OSError directly. Note that error numbers of ``getaddrinfo()`` + form a separate namespace and may not match error numbers from + ``uerrno`` module. To distinguish ``getaddrinfo()`` errors, they are + represented by negative numbers, whereas standard system errors are + positive numbers (error numbers are accessible using ``e.args[0]`` property + from an exception object). The use of negative values is a provisional + detail which may change in the future. Constants --------- .. data:: socket.AF_INET + socket.AF_INET6 - family types + Address family types. Availability depends on a particular board. .. data:: socket.SOCK_STREAM -.. data:: socket.SOCK_DGRAM + socket.SOCK_DGRAM - socket types + Socket types. .. data:: socket.IPPROTO_UDP -.. data:: socket.IPPROTO_TCP -.. only:: port_wipy + socket.IPPROTO_TCP - .. data:: socket.IPPROTO_SEC + IP protocol numbers. - protocol numbers +.. data:: socket.SOL_* + + Socket option levels (an argument to ``setsockopt()``). The exact inventory depends on a board. + +.. data:: socket.SO_* + + Socket options (an argument to ``setsockopt()``). The exact inventory depends on a board. + +Constants specific to WiPy: + +.. data:: socket.IPPROTO_SEC + + Special protocol value to create SSL-compatible socket. class socket ============ @@ -85,128 +105,146 @@ class socket Methods ------- - .. method:: socket.close +.. method:: socket.close + + Mark the socket closed. Once that happens, all future operations on the socket + object will fail. The remote end will receive no more data (after queued data is flushed). + + Sockets are automatically closed when they are garbage-collected, but it is recommended + to close() them explicitly, or to use a with statement around them. - Mark the socket closed. Once that happens, all future operations on the socket - object will fail. The remote end will receive no more data (after queued data is flushed). +.. method:: socket.bind(address) - Sockets are automatically closed when they are garbage-collected, but it is recommended - to close() them explicitly, or to use a with statement around them. + Bind the socket to address. The socket must not already be bound. - .. method:: socket.bind(address) +.. method:: socket.listen([backlog]) - Bind the socket to address. The socket must not already be bound. + Enable a server to accept connections. If backlog is specified, it must be at least 0 + (if it's lower, it will be set to 0); and specifies the number of unaccepted connections + that the system will allow before refusing new connections. If not specified, a default + reasonable value is chosen. - .. method:: socket.listen([backlog]) +.. method:: socket.accept() - Enable a server to accept connections. If backlog is specified, it must be at least 0 - (if it's lower, it will be set to 0); and specifies the number of unaccepted connections - that the system will allow before refusing new connections. If not specified, a default - reasonable value is chosen. + Accept a connection. The socket must be bound to an address and listening for connections. + The return value is a pair (conn, address) where conn is a new socket object usable to send + and receive data on the connection, and address is the address bound to the socket on the + other end of the connection. - .. method:: socket.accept() +.. method:: socket.connect(address) - Accept a connection. The socket must be bound to an address and listening for connections. - The return value is a pair (conn, address) where conn is a new socket object usable to send - and receive data on the connection, and address is the address bound to the socket on the - other end of the connection. + Connect to a remote socket at address. - .. method:: socket.connect(address) +.. method:: socket.send(bytes) - Connect to a remote socket at address. + Send data to the socket. The socket must be connected to a remote socket. + Returns number of bytes sent, which may be smaller than the length of data + ("short write"). - .. method:: socket.send(bytes) +.. method:: socket.sendall(bytes) - Send data to the socket. The socket must be connected to a remote socket. + Send all data to the socket. The socket must be connected to a remote socket. + Unlike ``send()``, this method will try to send all of data, by sending data + chunk by chunk consecutively. - .. method:: socket.sendall(bytes) + The behavior of this method on non-blocking sockets is undefined. Due to this, + on MicroPython, it's recommended to use ``write()`` method instead, which + has the same "no short writes" policy for blocking sockets, and will return + number of bytes sent on non-blocking sockets. - Send data to the socket. The socket must be connected to a remote socket. +.. method:: socket.recv(bufsize) - .. method:: socket.recv(bufsize) + Receive data from the socket. The return value is a bytes object representing the data + received. The maximum amount of data to be received at once is specified by bufsize. - Receive data from the socket. The return value is a bytes object representing the data - received. The maximum amount of data to be received at once is specified by bufsize. +.. method:: socket.sendto(bytes, address) - .. method:: socket.sendto(bytes, address) + Send data to the socket. The socket should not be connected to a remote socket, since the + destination socket is specified by `address`. - Send data to the socket. The socket should not be connected to a remote socket, since the - destination socket is specified by `address`. +.. method:: socket.recvfrom(bufsize) - .. method:: socket.recvfrom(bufsize) + Receive data from the socket. The return value is a pair (bytes, address) where bytes is a + bytes object representing the data received and address is the address of the socket sending + the data. - Receive data from the socket. The return value is a pair (bytes, address) where bytes is a - bytes object representing the data received and address is the address of the socket sending - the data. +.. method:: socket.setsockopt(level, optname, value) - .. method:: socket.setsockopt(level, optname, value) + Set the value of the given socket option. The needed symbolic constants are defined in the + socket module (SO_* etc.). The value can be an integer or a bytes-like object representing + a buffer. - Set the value of the given socket option. The needed symbolic constants are defined in the - socket module (SO_* etc.). The value can be an integer or a bytes-like object representing - a buffer. +.. method:: socket.settimeout(value) - .. method:: socket.settimeout(value) + Set a timeout on blocking socket operations. The value argument can be a nonnegative floating + point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations + will raise an ``OSError`` exception if the timeout period value has elapsed before the operation has + completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket + is put in blocking mode. - Set a timeout on blocking socket operations. The value argument can be a nonnegative floating - point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations - will raise an ``OSError`` exception if the timeout period value has elapsed before the operation has - completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket - is put in blocking mode. + .. admonition:: Difference to CPython + :class: attention - .. admonition:: Difference to CPython - :class: attention + CPython raises a ``socket.timeout`` exception in case of timeout, + which is an ``OSError`` subclass. MicroPython raises an OSError directly + instead. If you use ``except OSError:`` to catch the exception, + your code will work both in MicroPython and CPython. - CPython raises a ``socket.timeout`` exception in case of timeout, - which is an ``OSError`` subclass. MicroPython raises an OSError directly - instead. If you use ``except OSError:`` to catch the exception, - your code will work both in MicroPython and CPython. +.. method:: socket.setblocking(flag) - .. method:: socket.setblocking(flag) + Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking, + else to blocking mode. - Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking, - else to blocking mode. + This method is a shorthand for certain ``settimeout()`` calls: - This method is a shorthand for certain ``settimeout()`` calls:: + * ``sock.setblocking(True)`` is equivalent to ``sock.settimeout(None)`` + * ``sock.setblocking(False)`` is equivalent to ``sock.settimeout(0)`` - sock.setblocking(True) is equivalent to sock.settimeout(None) - sock.setblocking(False) is equivalent to sock.settimeout(0.0) +.. method:: socket.makefile(mode='rb', buffering=0) - .. method:: socket.makefile(mode='rb') + Return a file object associated with the socket. The exact returned type depends on the arguments + given to makefile(). The support is limited to binary modes only ('rb', 'wb', and 'rwb'). + CPython's arguments: ``encoding``, ``errors`` and ``newline`` are not supported. - Return a file object associated with the socket. The exact returned type depends on the arguments - given to makefile(). The support is limited to binary modes only ('rb' and 'wb'). - CPython's arguments: ``encoding``, ``errors`` and ``newline`` are not supported. + .. admonition:: Difference to CPython + :class: attention - The socket must be in blocking mode; it can have a timeout, but the file object’s internal buffer - may end up in a inconsistent state if a timeout occurs. + As MicroPython doesn't support buffered streams, values of ``buffering`` + parameter is ignored and treated as if it was 0 (unbuffered). - .. admonition:: Difference to CPython - :class: attention + .. admonition:: Difference to CPython + :class: attention - Closing the file object returned by makefile() WILL close the - original socket as well. + Closing the file object returned by makefile() WILL close the + original socket as well. - .. method:: socket.read([size]) +.. method:: socket.read([size]) - Read up to size bytes from the socket. Return a bytes object. If ``size`` is not given, it - reads all data available from the socket until ``EOF``; as such the method will not return until - the socket is closed. + Read up to size bytes from the socket. Return a bytes object. If ``size`` is not given, it + reads all data available from the socket until ``EOF``; as such the method will not return until + the socket is closed. This function tries to read as much data as + requested (no "short reads"). This may be not possible with + non-blocking socket though, and then less data will be returned. - .. method:: socket.readinto(buf[, nbytes]) +.. method:: socket.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. + Read bytes into the ``buf``. If ``nbytes`` is specified then read at most + that many bytes. Otherwise, read at most ``len(buf)`` bytes. Just as + ``read()``, this method follows "no short reads" policy. - Return value: number of bytes read and stored into ``buf``. + Return value: number of bytes read and stored into ``buf``. - .. method:: socket.readline() +.. method:: socket.readline() - Read a line, ending in a newline character. + Read a line, ending in a newline character. - Return value: the line read. + Return value: the line read. - .. method:: socket.write(buf) +.. method:: socket.write(buf) - Write the buffer of bytes to the socket. + Write the buffer of bytes to the socket. This function will try to + write all data to a socket (no "short writes"). This may be not possible + with a non-blocking socket though, and returned value will be less than + the length of ``buf``. - Return value: number of bytes written. + Return value: number of bytes written. diff --git a/docs/library/ussl.rst b/docs/library/ussl.rst index 5371ed1290..36f6d65a4a 100644 --- a/docs/library/ussl.rst +++ b/docs/library/ussl.rst @@ -1,86 +1,46 @@ -:mod:`ussl` -- ssl module -=============================== +:mod:`ussl` -- SSL/TLS module +============================= .. module:: ussl :synopsis: TLS/SSL wrapper for socket objects -This module provides access to Transport Layer Security (often known as -“Secure Sockets Layer”) encryption and peer authentication facilities for -network sockets, both client-side and server-side. +This module provides access to Transport Layer Security (previously and +widely known as “Secure Sockets Layer”) encryption and peer authentication +facilities for network sockets, both client-side and server-side. -.. only:: not port_wipy +Functions +--------- - Functions - --------- +.. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None) - .. function:: ssl.wrap_socket(sock, server_side=False) + Takes a stream `sock` (usually usocket.socket instance of ``SOCK_STREAM`` type), + and returns an instance of ssl.SSLSocket, which wraps the underlying stream in + an SSL context. Returned object has the usual stream interface methods like + `read()`, `write()`, etc. In MicroPython, the returned object does not expose + socket interface and methods like `recv()`, `send()`. In particular, a + server-side SSL socket should be created from a normal socket returned from + `accept()` on a non-SSL listening server socket. - Takes a stream `sock` (usually usocket.socket instance of ``SOCK_STREAM`` type), - and returns an instance of ssl.SSLSocket, which wraps the underlying stream in - an SSL context. Returned object has the usual stream interface methods like - `read()`, `write()`, etc. In MicroPython, the returned object does not expose - socket interface and methods like `recv()`, `send()`. In particular, a - server-side SSL socket should be created from a normal socket returned from - `accept()` on a non-SSL listening server socket. + Depending on the underlying module implementation for a particular board, + some or all keyword arguments above may be not supported. - .. warning:: +.. warning:: - Currently, this function does NOT validate server certificates, which makes - an SSL connection established prone to man-in-the-middle attacks. + Some implementations of ``ssl`` module do NOT validate server certificates, + which makes an SSL connection established prone to man-in-the-middle attacks. +Exceptions +---------- -.. only:: port_wipy +.. data:: ssl.SSLError - Functions - --------- + This exception does NOT exist. Instead its base class, OSError, is used. - .. function:: ssl.wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ca_certs=None) +Constants +--------- - Takes an instance sock of socket.socket, and returns an instance of ssl.SSLSocket, a subtype of - ``socket.socket``, which wraps the underlying socket in an SSL context. sock must be a ``SOCK_STREAM`` - socket and protocol number ``socket.IPPROTO_SEC``; other socket types are unsupported. Example:: +.. data:: ssl.CERT_NONE + ssl.CERT_OPTIONAL + ssl.CERT_REQUIRED - import socket - import ssl - s = socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) - ss = ssl.wrap_socket(s) - ss.connect(socket.getaddrinfo('www.google.com', 443)[0][-1]) - - Certificates must be used in order to validate the other side of the connection, and also to - authenticate ourselves with the other end. Such certificates must be stored as files using the - FTP server, and they must be placed in specific paths with specific names. - - - The certificate to validate the other side goes in: **'/flash/cert/ca.pem'** - - The certificate to authenticate ourselves goes in: **'/flash/cert/cert.pem'** - - The key for our own certificate goes in: **'/flash/cert/private.key'** - - .. note:: - - When these files are stored, they are placed inside the internal **hidden** file system - (just like firmware updates), and therefore they are never visible. - - For instance to connect to the Blynk servers using certificates, take the file ``ca.pem`` located - in the `blynk examples folder <https://github.com/wipy/wipy/tree/master/examples/blynk>`_ - and put it in '/flash/cert/'. Then do:: - - import socket - import ssl - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) - ss = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs='/flash/cert/ca.pem') - ss.connect(socket.getaddrinfo('cloud.blynk.cc', 8441)[0][-1]) - - SSL sockets inherit all methods and from the standard sockets, see the :mod:`usocket` module. - - Exceptions - ---------- - - .. data:: ssl.SSLError - - Constants - --------- - - .. data:: ssl.CERT_NONE - .. data:: ssl.CERT_OPTIONAL - .. data:: ssl.CERT_REQUIRED - - supported values in ``cert_reqs`` + Supported values for `cert_reqs` parameter. diff --git a/docs/library/utime.rst b/docs/library/utime.rst index 109c3560cc..871f6c678d 100644 --- a/docs/library/utime.rst +++ b/docs/library/utime.rst @@ -55,60 +55,50 @@ Functions which expresses a time as per localtime. It returns an integer which is the number of seconds since Jan 1, 2000. -.. only:: port_unix or port_pyboard or port_esp8266 +.. function:: sleep(seconds) - .. function:: sleep(seconds) - - Sleep for the given number of seconds. Seconds can be a floating-point number to - sleep for a fractional number of seconds. Note that other MicroPython ports may - not accept floating-point argument, for compatibility with them use ``sleep_ms()`` - and ``sleep_us()`` functions. + Sleep for the given number of seconds. Some boards may accept `seconds` as a + floating-point number to sleep for a fractional number of seconds. Note that + other boards may not accept a floating-point argument, for compatibility with + them use ``sleep_ms()`` and ``sleep_us()`` functions. -.. only:: port_wipy +.. function:: sleep_ms(ms) - .. function:: sleep(seconds) - - Sleep for the given number of seconds. + Delay for given number of milliseconds, should be positive or 0. -.. only:: port_unix or port_pyboard or port_wipy or port_esp8266 +.. function:: sleep_us(us) - .. function:: sleep_ms(ms) + Delay for given number of microseconds, should be positive or 0. - Delay for given number of milliseconds, should be positive or 0. +.. function:: ticks_ms() - .. function:: sleep_us(us) + Returns an increasing millisecond counter with an arbitrary reference point, that + wraps around after some value. This value is not explicitly exposed, but we will + refer to it as ``TICKS_MAX`` to simplify discussion. Period of the values is + ``TICKS_PERIOD = TICKS_MAX + 1``. ``TICKS_PERIOD`` is guaranteed to be a power of + two, but otherwise may differ from port to port. The same period value is used + for all of ``ticks_ms()``, ``ticks_us()``, ``ticks_cpu()`` functions (for + simplicity). Thus, these functions will return a value in range [``0`` .. + ``TICKS_MAX``], inclusive, total ``TICKS_PERIOD`` values. Note that only + non-negative values are used. For the most part, you should treat values returned + by these functions as opaque. The only operations available for them are + ``ticks_diff()`` and ``ticks_add()`` functions described below. - Delay for given number of microseconds, should be positive or 0 + Note: Performing standard mathematical operations (+, -) or relational + operators (<, <=, >, >=) directly on these value will lead to invalid + result. Performing mathematical operations and then passing their results + as arguments to ``ticks_diff()`` or ``ticks_add()`` will also lead to + invalid results from the latter functions. - .. function:: ticks_ms() +.. function:: ticks_us() - Returns an increasing millisecond counter with an arbitrary reference point, - that wraps around after some value. This value is not explicitly exposed, - but we will refer to it as `TICKS_MAX` to simplify discussion. Period of - the values is `TICKS_PERIOD = TICKS_MAX + 1`. `TICKS_PERIOD` is guaranteed - to be a power of two, but otherwise may differ from port to port. The same - period value is used for all of ticks_ms(), ticks_us(), ticks_cpu() functions - (for simplicity). Thus, these functions will return a value in range - [0 .. `TICKS_MAX`], inclusive, total `TICKS_PERIOD` values. Note that only - non-negative values are used. For the most part, you should treat values - returned by these functions as opaque. The only operations available for them - are ``ticks_diff()`` and ``ticks_add()`` functions described below. + Just like ``ticks_ms()`` above, but in microseconds. - Note: Performing standard mathematical operations (+, -) or relational - operators (<, <=, >, >=) directly on these value will lead to invalid - result. Performing mathematical operations and then passing their results - as arguments to ``ticks_diff()`` or ``ticks_add()`` will also lead to - invalid results from the latter functions. +.. function:: ticks_cpu() - .. function:: ticks_us() - - Just like ``ticks_ms`` above, but in microseconds. - -.. function:: ticks_cpu() - - Similar to ``ticks_ms`` and ``ticks_us``, but with the highest possible resolution + Similar to ``ticks_ms()`` and ``ticks_us()``, but with the highest possible resolution in the system. This is usually CPU clocks, and that's why the function is named that - way. But it doesn't have to a CPU clock, some other timing source available in a + way. But it doesn't have to be a CPU clock, some other timing source available in a system (e.g. high-resolution timer) can be used instead. The exact timing unit (resolution) of this function is not specified on ``utime`` module level, but documentation for a specific port may provide more specific information. This @@ -118,13 +108,13 @@ Functions Availability: Not every port implements this function. -.. function:: ticks_add(ticks, delta) +.. function:: ticks_add(ticks, delta) Offset ticks value by a given number, which can be either positive or negative. Given a ``ticks`` value, this function allows to calculate ticks value ``delta`` ticks before or after it, following modular-arithmetic definition of tick values (see ``ticks_ms()`` above). ``ticks`` parameter must be a direct result of call - to ``tick_ms()``, ``ticks_us()``, ``ticks_cpu()`` functions (or from previous + to ``ticks_ms()``, ``ticks_us()``, or ``ticks_cpu()`` functions (or from previous call to ``ticks_add()``). However, ``delta`` can be an arbitrary integer number or numeric expression. ``ticks_add()`` is useful for calculating deadlines for events/tasks. (Note: you must use ``ticks_diff()`` function to work with @@ -133,35 +123,37 @@ Functions Examples:: # Find out what ticks value there was 100ms ago - print(tick_add(time.ticks_ms(), -100)) + print(ticks_add(time.ticks_ms(), -100)) # Calculate deadline for operation and test for it - deadline = tick_add(time.ticks_ms(), 200) + deadline = ticks_add(time.ticks_ms(), 200) while ticks_diff(deadline, time.ticks_ms()) > 0: do_a_little_of_something() # Find out TICKS_MAX used by this port - print(tick_add(0, -1)) - - -.. function:: ticks_diff(ticks1, ticks2) - - Measure ticks difference between values returned from ticks_ms(), ticks_us(), or ticks_cpu() - functions. The argument order is the same as for subtraction operator, - ``tick_diff(ticks1, ticks2)`` has the same meaning as ``ticks1 - ticks2``. However, values returned by - ticks_ms(), etc. functions may wrap around, so directly using subtraction on them will - produce incorrect result. That is why ticks_diff() is needed, it implements modular - (or more specifically, ring) arithmetics to produce correct result even for wrap-around - values (as long as they not too distant inbetween, see below). The function returns - **signed** value in the range [`-TICKS_PERIOD/2` .. `TICKS_PERIOD/2-1`] (that's a typical - range definition for two's-complement signed binary integers). If the result is negative, - it means that `ticks1` occured earlier in time than `ticks2`. Otherwise, it means that - `ticks1` occured after `ticks2`. This holds `only` if `ticks1` and `ticks2` are apart from - each other for no more than `TICKS_PERIOD/2-1` ticks. If that does not hold, incorrect - result will be returned. Specifically, if 2 tick values are apart for `TICKS_PERIOD/2-1` - ticks, that value will be returned by the function. However, if `TICKS_PERIOD/2` of - real-time ticks has passed between them, the function will return `-TICKS_PERIOD/2` - instead, i.e. result value will wrap around to the negative range of possible values. + print(ticks_add(0, -1)) + + +.. function:: ticks_diff(ticks1, ticks2) + + Measure ticks difference between values returned from ``ticks_ms()``, ``ticks_us()``, + or ``ticks_cpu()`` functions. The argument order is the same as for subtraction + operator, ``ticks_diff(ticks1, ticks2)`` has the same meaning as ``ticks1 - ticks2``. + However, values returned by ``ticks_ms()``, etc. functions may wrap around, so + directly using subtraction on them will produce incorrect result. That is why + ``ticks_diff()`` is needed, it implements modular (or more specifically, ring) + arithmetics to produce correct result even for wrap-around values (as long as they not + too distant inbetween, see below). The function returns **signed** value in the range + [``-TICKS_PERIOD/2`` .. ``TICKS_PERIOD/2-1``] (that's a typical range definition for + two's-complement signed binary integers). If the result is negative, it means that + ``ticks1`` occured earlier in time than ``ticks2``. Otherwise, it means that + ``ticks1`` occured after ``ticks2``. This holds ``only`` if ``ticks1`` and ``ticks2`` + are apart from each other for no more than ``TICKS_PERIOD/2-1`` ticks. If that does + not hold, incorrect result will be returned. Specifically, if two tick values are + apart for ``TICKS_PERIOD/2-1`` ticks, that value will be returned by the function. + However, if ``TICKS_PERIOD/2`` of real-time ticks has passed between them, the + function will return ``-TICKS_PERIOD/2`` instead, i.e. result value will wrap around + to the negative range of possible values. Informal rationale of the constraints above: Suppose you are locked in a room with no means to monitor passing of time except a standard 12-notch clock. Then if you look at @@ -200,20 +192,21 @@ Functions print("Oops, running late, tell task to run faster!") task.run(run_faster=true) - Note: Do not pass ``time()`` values to ``ticks_diff()``, and should use + Note: Do not pass ``time()`` values to ``ticks_diff()``, you should use normal mathematical operations on them. But note that ``time()`` may (and will) also overflow. This is known as https://en.wikipedia.org/wiki/Year_2038_problem . .. function:: time() - Returns the number of seconds, as an integer, since the Epoch, assuming that underlying - RTC is set and maintained as described above. If an RTC is not set, this function returns - number of seconds since a port-specific reference point in time (for embedded boards without - a battery-backed RTC, usually since power up or reset). If you want to develop portable - MicroPython application, you should not rely on this function to provide higher than second - precision. If you need higher precision, use ``ticks_ms()`` and ``ticks_us()`` functions, - if you need calendar time, ``localtime()`` without an argument is a better choice. + Returns the number of seconds, as an integer, since the Epoch, assuming that + underlying RTC is set and maintained as described above. If an RTC is not set, this + function returns number of seconds since a port-specific reference point in time (for + embedded boards without a battery-backed RTC, usually since power up or reset). If you + want to develop portable MicroPython application, you should not rely on this function + to provide higher than second precision. If you need higher precision, use + ``ticks_ms()`` and ``ticks_us()`` functions, if you need calendar time, + ``localtime()`` without an argument is a better choice. .. admonition:: Difference to CPython :class: attention diff --git a/docs/pyboard/general.rst b/docs/pyboard/general.rst index 107bae69a7..48e0146442 100644 --- a/docs/pyboard/general.rst +++ b/docs/pyboard/general.rst @@ -11,6 +11,11 @@ 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``. +If needed, you can prevent the use of the SD card by creating an empty file +called ``/flash/SKIPSD``. If this file exists when the pyboard boots +up then the SD card will be skipped and the pyboard will always boot from the +internal filesystem (in this case the SD card won't be mounted but you can still +mount and use it later in your program using ``os.mount``). (Note that on older versions of the board, ``/flash`` is called ``0:/`` and ``/sd`` is called ``1:/``). diff --git a/docs/pyboard/hardware/index.rst b/docs/pyboard/hardware/index.rst index b64908c56d..bc4726ce2d 100644 --- a/docs/pyboard/hardware/index.rst +++ b/docs/pyboard/hardware/index.rst @@ -13,6 +13,7 @@ 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) +* LCD160CRv1.0: see :mod:`lcd160cr` Datasheets for the components on the pyboard ============================================ diff --git a/docs/pyboard/quickref.rst b/docs/pyboard/quickref.rst index 5f1a3a6e6b..5690dddb0c 100644 --- a/docs/pyboard/quickref.rst +++ b/docs/pyboard/quickref.rst @@ -152,7 +152,7 @@ See :ref:`pyb.SPI <pyb.SPI>`. :: spi = SPI(1, SPI.MASTER, baudrate=200000, polarity=1, phase=0) spi.send('hello') spi.recv(5) # receive 5 bytes on the bus - spi.send_recv('hello') # send a receive 5 bytes + spi.send_recv('hello') # send and receive 5 bytes I2C bus ------- diff --git a/docs/pyboard/tutorial/index.rst b/docs/pyboard/tutorial/index.rst index ae40f47b80..07f136c9b4 100644 --- a/docs/pyboard/tutorial/index.rst +++ b/docs/pyboard/tutorial/index.rst @@ -35,6 +35,7 @@ Tutorials requiring extra components fading_led.rst lcd_skin.rst amp_skin.rst + lcd160cr_skin.rst Tips, tricks and useful things to know -------------------------------------- diff --git a/docs/pyboard/tutorial/lcd160cr_skin.rst b/docs/pyboard/tutorial/lcd160cr_skin.rst new file mode 100644 index 0000000000..fc9d635382 --- /dev/null +++ b/docs/pyboard/tutorial/lcd160cr_skin.rst @@ -0,0 +1,134 @@ +The LCD160CR skin +================= + +This tutorial shows how to get started using the LCD160CR skin. + +.. image:: http://micropython.org/resources/LCD160CRv10-positions.jpg + :alt: LCD160CRv1.0 picture + :width: 800px + +For detailed documentation of the driver for the display see the +:mod:`lcd160cr` module. + +Plugging in the display +----------------------- + +The display can be plugged directly into a pyboard (all pyboard versions +are supported). You plug the display onto the top of the pyboard either +in the X or Y positions. The display should cover half of the pyboard. +See the picture above for how to achieve this; the left half of the picture +shows the X position, and the right half shows the Y position. + +Getting the driver +------------------ + +You can control the display directly using a power/enable pin and an I2C +bus, but it is much more convenient to use the driver provided by the +:mod:`lcd160cr` module. This driver is included in recent version of the +pyboard firmware (see `here <http://micropython.org/download>`__). You +can also find the driver in the GitHub repository +`here <https://github.com/micropython/micropython/blob/master/drivers/display/lcd160cr.py>`__, and to use this version you will need to copy the file to your +board, into a directory that is searched by import (usually the lib/ +directory). + +Once you have the driver installed you need to import it to use it:: + + import lcd160cr + +Testing the display +------------------- + +There is a test program which you can use to test the features of the display, +and which also serves as a basis to start creating your own code that uses the +LCD. This test program is included in recent versions of the pyboard firmware +and is also available on GitHub +`here <https://github.com/micropython/micropython/blob/master/drivers/display/lcd160cr_test.py>`__. + +To run the test from the MicroPython prompt do:: + + >>> import lcd160cr_test + +It will then print some brief instructions. You will need to know which +position your display is connected to (X or Y) and then you can run (assuming +you have the display on position X):: + + >>> test_all('X') + +Drawing some graphics +--------------------- + +You must first create an LCD160CR object which will control the display. Do this +using:: + + >>> import lcd160cr + >>> lcd = lcd160cr.LCD160CR('X') + +This assumes your display is connected in the X position. If it's in the Y +position then use ``lcd = lcd160cr.LCD160CR('Y')`` instead. + +To erase the screen and draw a line, try:: + + >>> lcd.set_pen(lcd.rgb(255, 0, 0), lcd.rgb(64, 64, 128)) + >>> lcd.erase() + >>> lcd.line(10, 10, 50, 80) + +The next example draws random rectangles on the screen. You can copy-and-paste it +into the MicroPython prompt by first pressing "Ctrl-E" at the prompt, then "Ctrl-D" +once you have pasted the text. :: + + from random import randint + for i in range(1000): + fg = lcd.rgb(randint(128, 255), randint(128, 255), randint(128, 255)) + bg = lcd.rgb(randint(0, 128), randint(0, 128), randint(0, 128)) + lcd.set_pen(fg, bg) + lcd.rect(randint(0, lcd.w), randint(0, lcd.h), randint(10, 40), randint(10, 40)) + +Using the touch sensor +---------------------- + +The display includes a resistive touch sensor that can report the position (in +pixels) of a single force-based touch on the screen. To see if there is a touch +on the screen use:: + + >>> lcd.is_touched() + +This will return either ``False`` or ``True``. Run the above command while touching +the screen to see the result. + +To get the location of the touch you can use the method:: + + >>> lcd.get_touch() + +This will return a 3-tuple, with the first entry being 0 or 1 depending on whether +there is currently anything touching the screen (1 if there is), and the second and +third entries in the tuple being the x and y coordinates of the current (or most +recent) touch. + +Directing the MicroPython output to the display +----------------------------------------------- + +The display supports input from a UART and implements basic VT100 commands, which +means it can be used as a simple, general purpose terminal. Let's set up the +pyboard to redirect its output to the display. + +First you need to create a UART object:: + + >>> import pyb + >>> uart = pyb.UART('XA', 115200) + +This assumes your display is connected to position X. If it's on position Y then +use ``uart = pyb.UART('YA', 115200)`` instead. + +Now, connect the REPL output to this UART:: + + >>> pyb.repl_uart(uart) + +From now on anything you type at the MicroPython prompt, and any output you +receive, will appear on the display. + +No set-up commands are required for this mode to work and you can use the display +to monitor the output of any UART, not just from the pyboard. All that is needed +is for the display to have power, ground and the power/enable pin driven high. +Then any characters on the display's UART input will be printed to the screen. +You can adjust the UART baudrate from the default of 115200 using the +`set_uart_baudrate` method. diff --git a/docs/pyboard_contents.rst b/docs/pyboard_contents.rst index 5ced479efc..658dd366f2 100644 --- a/docs/pyboard_contents.rst +++ b/docs/pyboard_contents.rst @@ -9,5 +9,6 @@ MicroPython documentation contents library/index.rst reference/index.rst pyboard/hardware/index.rst + genrst/index.rst license.rst diff --git a/docs/pyboard_index.rst b/docs/pyboard_index.rst index 38ccb1ac99..4caa4cc883 100644 --- a/docs/pyboard_index.rst +++ b/docs/pyboard_index.rst @@ -8,6 +8,7 @@ MicroPython documentation and references pyboard/tutorial/index.rst library/index.rst pyboard/hardware/index.rst + genrst/index.rst license.rst pyboard_contents.rst diff --git a/docs/static/favicon.ico b/docs/static/favicon.ico Binary files differnew file mode 100644 index 0000000000..49c6154140 --- /dev/null +++ b/docs/static/favicon.ico diff --git a/docs/topindex.html b/docs/topindex.html index 75039233ee..f32f3cea6b 100644 --- a/docs/topindex.html +++ b/docs/topindex.html @@ -47,6 +47,10 @@ <span class="linkdescr">MicroPython libraries, including the <a href="{{ pathto("library/machine") }}">machine module</a></span> {% endif %} </p> + <p class="biglink"> + <a class="biglink" href="{{ pathto("genrst/index") }}">MicroPython Differences</a><br/> + <span class="linkdescr">MicroPython operations which differ from CPython</span> + </p> </td> <td width="40%" style="padding-left:2em;"> <p class="biglink"> diff --git a/docs/unix_contents.rst b/docs/unix_contents.rst index ec0a6f0e86..8c5a586b29 100644 --- a/docs/unix_contents.rst +++ b/docs/unix_contents.rst @@ -5,4 +5,5 @@ MicroPython documentation contents library/index.rst reference/index.rst + genrst/index.rst license.rst diff --git a/docs/unix_index.rst b/docs/unix_index.rst index 027f24c2e3..7fa1753c23 100644 --- a/docs/unix_index.rst +++ b/docs/unix_index.rst @@ -4,6 +4,7 @@ MicroPython documentation and references .. toctree:: library/index.rst + genrst/index.rst license.rst unix_contents.rst diff --git a/docs/wipy/general.rst b/docs/wipy/general.rst index 0991dbaeaf..8b9b91c534 100644 --- a/docs/wipy/general.rst +++ b/docs/wipy/general.rst @@ -179,3 +179,147 @@ Details on sleep modes * ``machine.sleep()``: 950uA (in WLAN STA mode). Wake sources are ``Pin``, ``RTC`` and ``WLAN`` * ``machine.deepsleep()``: ~350uA. Wake sources are ``Pin`` and ``RTC``. + +Additional details for machine.Pin +---------------------------------- + +On the WiPy board the pins are identified by their string id:: + + from machine import Pin + g = machine.Pin('GP9', mode=Pin.OUT, pull=None, drive=Pin.MED_POWER, alt=-1) + +You can also configure the Pin to generate interrupts. For instance:: + + from machine import Pin + + def pincb(pin): + print(pin.id()) + + pin_int = Pin('GP10', mode=Pin.IN, pull=Pin.PULL_DOWN) + pin_int.irq(trigger=Pin.IRQ_RISING, handler=pincb) + # the callback can be triggered manually + pin_int.irq()() + # to disable the callback + pin_int.irq().disable() + +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. + +For the ``drive`` parameter the strengths are: + + - ``Pin.LOW_POWER`` - 2mA drive capability. + - ``Pin.MED_POWER`` - 4mA drive capability. + - ``Pin.HIGH_POWER`` - 6mA drive capability. + +For the ``alt`` parameter please refer to the pinout and alternate functions +table at <https://raw.githubusercontent.com/wipy/wipy/master/docs/PinOUT.png>`_ +for the specific alternate functions that each pin supports. + +For interrupts, the ``priority`` can take values in the range 1-7. And the +``wake`` parameter has the following properties: + + - If ``wake_from=machine.Sleep.ACTIVE`` any pin can wake the board. + - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, + ``GP11``, GP17`` or ``GP24`` can wake the board. Note that only 1 + of this pins can be enabled as a wake source at the same time, so, only + the last enabled pin as a ``machine.Sleep.SUSPENDED`` wake source will have effect. + - If ``wake_from=machine.Sleep.SUSPENDED`` pins ``GP2``, ``GP4``, ``GP10``, + ``GP11``, ``GP17`` and ``GP24`` can wake the board. In this case all of the + 6 pins can be enabled as a ``machine.Sleep.HIBERNATE`` wake source at the same time. + +Additional Pin methods: + +.. method:: machine.Pin.alt_list() + + Returns a list of the alternate functions supported by the pin. List items are + a tuple of the form: ``('ALT_FUN_NAME', ALT_FUN_INDEX)`` + +Additional details for machine.I2C +---------------------------------- + +On the WiPy there is a single hardware I2C peripheral, identified by "0". By +default this is the peripheral that is used when constructing an I2C instance. +The default pins are GP23 for SCL and GP13 for SDA, and one can create the +default I2C peripheral simply by doing:: + + i2c = machine.I2C() + +The pins and frequency can be specified as:: + + i2c = machine.I2C(freq=400000, scl='GP23', sda='GP13') + +Only certain pins can be used as SCL/SDA. Please refer to the pinout for further +information. + +Known issues +------------ + +Incompatible way to create SSL sockets +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +SSL sockets need to be created the following way before wrapping them with. +``ssl.wrap_socket``:: + + import socket + import ssl + s = socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) + ss = ssl.wrap_socket(s) + +Certificates must be used in order to validate the other side of the connection, and also to +authenticate ourselves with the other end. Such certificates must be stored as files using the +FTP server, and they must be placed in specific paths with specific names. + +- The certificate to validate the other side goes in: **'/flash/cert/ca.pem'** +- The certificate to authenticate ourselves goes in: **'/flash/cert/cert.pem'** +- The key for our own certificate goes in: **'/flash/cert/private.key'** + +.. note:: + + When these files are stored, they are placed inside the internal **hidden** file system + (just like firmware updates), and therefore they are never visible. + +For instance to connect to the Blynk servers using certificates, take the file ``ca.pem`` located +in the `blynk examples folder <https://github.com/wipy/wipy/tree/master/examples/blynk>`_. +and put it in '/flash/cert/'. Then do:: + + import socket + import ssl + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_SEC) + ss = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs='/flash/cert/ca.pem') + ss.connect(socket.getaddrinfo('cloud.blynk.cc', 8441)[0][-1]) + +Incompatibilities in uhashlib module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to hardware implementation details of the WiPy, data must be buffered before being +digested, which would make it impossible to calculate the hash of big blocks of data that +do not fit in RAM. In this case, since most likely the total size of the data is known +in advance, the size can be passed to the constructor and hence the HASH hardware engine +of the WiPy can be properly initialized without needing buffering. If ``block_size`` is +to be given, an initial chunk of ``data`` must be passed as well. **When using this extension, +care must be taken to make sure that the length of all intermediate chunks (including the +initial one) is a multiple of 4 bytes.** The last chunk may be of any length. + +Example:: + + hash = uhashlib.sha1('abcd1234', 1001) # length of the initial piece is multiple of 4 bytes + hash.update('1234') # also multiple of 4 bytes + ... + hash.update('12345') # last chunk may be of any length + hash.digest() + +Unrelated function in machine module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. function:: main(filename) + + Set the filename of the main script to run after boot.py is finished. If + this function is not called then the default file main.py will be executed. + + It only makes sense to call this function from within boot.py. diff --git a/docs/wipy/quickref.rst b/docs/wipy/quickref.rst index ac7eec1328..f60c81f5fe 100644 --- a/docs/wipy/quickref.rst +++ b/docs/wipy/quickref.rst @@ -44,7 +44,8 @@ See :ref:`machine.Pin <machine.Pin>`. :: Timers ------ -See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`. :: +See :ref:`machine.Timer <machine.Timer>` and :ref:`machine.Pin <machine.Pin>`. +Timer ``id``'s take values from 0 to 3.:: from machine import Timer from machine import Pin @@ -102,7 +103,7 @@ See :ref:`machine.SPI <machine.SPI>`. :: spi.write('hello') spi.read(5) # receive 5 bytes on the bus rbuf = bytearray(5) - spi.write_readinto('hello', rbuf) # send a receive 5 bytes + spi.write_readinto('hello', rbuf) # send and receive 5 bytes I2C bus ------- @@ -111,7 +112,7 @@ See :ref:`machine.I2C <machine.I2C>`. :: from machine import I2C # configure the I2C bus - i2c = I2C(0, I2C.MASTER, baudrate=100000) + i2c = I2C(baudrate=100000) i2c.scan() # returns list of slave addresses i2c.writeto(0x42, 'hello') # send 5 bytes to slave with address 0x42 i2c.readfrom(0x42, 5) # receive 5 bytes from slave diff --git a/docs/wipy/tutorial/index.rst b/docs/wipy/tutorial/index.rst index c3d51e2e5d..816de27b5a 100644 --- a/docs/wipy/tutorial/index.rst +++ b/docs/wipy/tutorial/index.rst @@ -14,4 +14,5 @@ for instructions see :ref:`OTA How-To <wipy_firmware_upgrade>`. repl.rst blynk.rst wlan.rst + timer.rst reset.rst diff --git a/docs/wipy/tutorial/timer.rst b/docs/wipy/tutorial/timer.rst new file mode 100644 index 0000000000..c87ac44959 --- /dev/null +++ b/docs/wipy/tutorial/timer.rst @@ -0,0 +1,70 @@ +Hardware timers +=============== + +Timers can be used for a great variety of tasks, calling a function periodically, +counting events, and generating a PWM signal are among the most common use cases. +Each timer consists of two 16-bit channels and this channels can be tied together to +form one 32-bit timer. The operating mode needs to be configured per timer, but then +the period (or the frequency) can be independently configured on each channel. +By using the callback method, the timer event can call a Python function. + +Example usage to toggle an LED at a fixed frequency:: + + from machine import Timer + from machine import Pin + led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED + tim = Timer(3) # create a timer object using timer 3 + tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode + tim_ch = tim.channel(Timer.A, freq=5) # configure channel A at a frequency of 5Hz + tim_ch.irq(handler=lambda t:led.toggle(), trigger=Timer.TIMEOUT) # toggle a LED on every cycle of the timer + +Example using named function for the callback:: + + from machine import Timer + from machine import Pin + tim = Timer(1, mode=Timer.PERIODIC, width=32) + tim_a = tim.channel(Timer.A | Timer.B, freq=1) # 1 Hz frequency requires a 32 bit timer + + led = Pin('GP16', mode=Pin.OUT) # enable GP16 as output to drive the LED + + def tick(timer): # we will receive the timer object when being called + global led + led.toggle() # toggle the LED + + tim_a.irq(handler=tick, trigger=Timer.TIMEOUT) # create the interrupt + +Further examples:: + + from machine import Timer + tim1 = Timer(1, mode=Timer.ONE_SHOT) # initialize it in one shot mode + tim2 = Timer(2, mode=Timer.PWM) # initialize it in PWM mode + tim1_ch = tim1.channel(Timer.A, freq=10, polarity=Timer.POSITIVE) # start the event counter with a frequency of 10Hz and triggered by positive edges + tim2_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=5000) # start the PWM on channel B with a 50% duty cycle + tim2_ch.freq(20) # set the frequency (can also get) + tim2_ch.duty_cycle(3010) # set the duty cycle to 30.1% (can also get) + tim2_ch.duty_cycle(3020, Timer.NEGATIVE) # set the duty cycle to 30.2% and change the polarity to negative + tim2_ch.period(2000000) # change the period to 2 seconds + + +Additional constants for Timer class +------------------------------------ + +.. data:: Timer.PWM + + PWM timer operating mode. + +.. data:: Timer.A +.. data:: Timer.B + + Selects the timer channel. Must be ORed (``Timer.A`` | ``Timer.B``) when + using a 32-bit timer. + +.. data:: Timer.POSITIVE +.. data:: Timer.NEGATIVE + + Timer channel polarity selection (only relevant in PWM mode). + +.. data:: Timer.TIMEOUT +.. data:: Timer.MATCH + + Timer channel IRQ triggers. diff --git a/docs/wipy_contents.rst b/docs/wipy_contents.rst index 2beffa236e..0e50a7c6ee 100644 --- a/docs/wipy_contents.rst +++ b/docs/wipy_contents.rst @@ -8,4 +8,5 @@ MicroPython documentation contents wipy/tutorial/index.rst library/index.rst reference/index.rst + genrst/index.rst license.rst diff --git a/docs/wipy_index.rst b/docs/wipy_index.rst index 9fe3dce896..a390aecb1e 100644 --- a/docs/wipy_index.rst +++ b/docs/wipy_index.rst @@ -7,6 +7,7 @@ MicroPython documentation and references wipy/general.rst wipy/tutorial/index.rst library/index.rst + genrst/index.rst license.rst wipy_contents.rst |