summaryrefslogtreecommitdiff
path: root/docs/library
diff options
context:
space:
mode:
Diffstat (limited to 'docs/library')
-rw-r--r--docs/library/btree.rst144
-rw-r--r--docs/library/builtins.rst10
-rw-r--r--docs/library/framebuf.rst152
-rw-r--r--docs/library/index.rst14
-rw-r--r--docs/library/lcd160cr.rst394
-rw-r--r--docs/library/machine.ADC.rst1
-rw-r--r--docs/library/machine.I2C.rst113
-rw-r--r--docs/library/machine.Pin.rst90
-rw-r--r--docs/library/machine.RTC.rst1
-rw-r--r--docs/library/machine.SD.rst1
-rw-r--r--docs/library/machine.SPI.rst19
-rw-r--r--docs/library/machine.Signal.rst96
-rw-r--r--docs/library/machine.Timer.rst97
-rw-r--r--docs/library/machine.UART.rst75
-rw-r--r--docs/library/machine.WDT.rst1
-rw-r--r--docs/library/machine.rst90
-rw-r--r--docs/library/micropython.rst115
-rw-r--r--docs/library/pyb.Pin.rst2
-rw-r--r--docs/library/pyb.rst13
-rw-r--r--docs/library/uhashlib.rst84
-rw-r--r--docs/library/uio.rst65
-rw-r--r--docs/library/uos.rst60
-rw-r--r--docs/library/usocket.rst252
-rw-r--r--docs/library/ussl.rst100
-rw-r--r--docs/library/utime.rst141
25 files changed, 1431 insertions, 699 deletions
diff --git a/docs/library/btree.rst b/docs/library/btree.rst
new file mode 100644
index 000000000..aebcbc160
--- /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 d53c4d377..46f762660 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 000000000..61f0635f3
--- /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 3621f9d88..770920a1f 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 000000000..bd4741298
--- /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 2752878ff..4c7a04d74 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 cdeb246eb..a1b417890 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 952131f09..2efd84688 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 6dc8b3e9a..2a53b9146 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 21c28aa20..0eb024602 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 dda6314fa..080f6fdfb 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 000000000..486908627
--- /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 12db58d5c..ef46f9dd7 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 0b6b24e89..f9c8efef7 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 1d79b4c4e..5ca6dce45 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 7870da2ff..c2c6b83fd 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 14e4c917e..7f4002856 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 4f589fff8..b766c5280 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 910b2f45b..9c4933808 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 223c72dfe..cd0216dae 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 9b4c87df8..1239c6394 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 242e8c3d0..d1f83d2cc 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 c46e8f4c5..71deaebc4 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 5371ed129..36f6d65a4 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 109c3560c..871f6c678 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