shared-bindings: Update docs to remove with statements from examples but add more detail to the design guide about their use.

This commit is contained in:
Scott Shawcroft 2017-06-07 14:39:12 -07:00
parent c5e515b8fe
commit 714521a4c7
28 changed files with 354 additions and 275 deletions

View File

@ -319,6 +319,6 @@ texinfo_documents = [
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/3/': None,
'https://circuitpython.readthedocs.io/projects/bus_device/en/latest/': None,
'https://circuitpython.readthedocs.io/projects/register/en/latest/': None}
intersphinx_mapping = {"cpython": ('https://docs.python.org/3/', None),
"bus_device": ('https://circuitpython.readthedocs.io/projects/bus_device/en/latest/', None),
"register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None)}

View File

@ -33,6 +33,8 @@ not have the ``adafruit_`` module or package prefix.
Both should have the CircuitPython repository topic on GitHub.
.. _lifetime-and-contextmanagers:
Lifetime and ContextManagers
--------------------------------------------------------------------------------
@ -41,6 +43,49 @@ device requires deinitialization, then provide it through ``deinit()`` and also
provide ``__enter__`` and ``__exit__`` to create a context manager usable with
``with``.
For example, a user can then use ``deinit()```::
import digitalio
import board
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.DigitalInOut.Direction.OUT
for i in range(10):
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
led.deinit()
This will deinit the underlying hardware at the end of the program as long as no
exceptions occur.
Alternatively, using a ``with`` statement ensures that the hardware is deinitialized::
import digitalio
import board
with digitalio.DigitalInOut(board.D13) as led:
led.direction = digitalio.DigitalInOut.Direction.OUT
for i in range(10):
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
Python's ``with`` statement ensures that the deinit code is run regardless of
whether the code within the with statement executes without exceptions.
For small programs like the examples this isn't a major concern because all
user usable hardware is reset after programs are run or the REPL is run. However,
for more complex programs that may use hardware intermittently and may also
handle exceptions on their own, deinitializing the hardware using a with
statement will ensure hardware isn't enabled longer than needed.
Verify your device
--------------------------------------------------------------------------------

View File

@ -45,7 +45,7 @@
//| import analogio
//| from board import *
//|
//| with analogio.AnalogIn(A1) as adc:
//| adc = analogio.AnalogIn(A1)
//| val = adc.value
//|
@ -93,7 +93,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_deinit_obj, analogio_analogin_deinit
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -45,7 +45,7 @@
//| import analogio
//| from microcontroller import pin
//|
//| with analogio.AnalogOut(pin.PA02) as dac: # output on pin PA02
//| dac = analogio.AnalogOut(pin.PA02) # output on pin PA02
//| dac.value = 32768 # makes PA02 1.65V
//|
@ -91,7 +91,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogout_deinit_obj, analogio_analogo
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -53,21 +53,24 @@
//| AnalogIn
//| AnalogOut
//|
//| All libraries change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
//| For example::
//|
//| import analogio
//| from board import *
//|
//| with analogio.AnalogIn(A0) as pin:
//| pin = analogio.AnalogIn(A0)
//| print(pin.value)
//| pin.deinit()
//|
//| This example will initialize the the device, read
//| :py:data:`~analogio.AnalogIn.value` and then
//| :py:meth:`~analogio.AnalogIn.deinit` the hardware.
//| :py:meth:`~analogio.AnalogIn.deinit` the hardware. The last step is optional
//| because CircuitPython will do it automatically after the program finishes.
//|
STATIC const mp_rom_map_elem_t analogio_module_globals_table[] = {

View File

@ -66,7 +66,7 @@
//| for i in range(length):
//| b[i] = int(math.sin(math.pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
//|
//| with audioio.AudioOut(board.SPEAKER, sin_wave) as sample:
//| sample = audioio.AudioOut(board.SPEAKER, sin_wave)
//| sample.play(loop=True)
//| time.sleep(1)
//| sample.stop()
@ -136,7 +136,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_deinit_obj, audioio_audioout_d
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -49,9 +49,10 @@
//|
//| AudioOut
//|
//| All libraries change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = {

View File

@ -90,7 +90,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_deinit_obj, bitbangio_i2c_obj_deinit);
//| .. method:: I2C.__exit__()
//|
//| Automatically deinitializes the hardware on context exit.
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t bitbangio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -55,7 +55,7 @@
//| import bitbangio
//| import board
//|
//| with bitbangio.OneWire(board.D7) as onewire:
//| onewire = bitbangio.OneWire(board.D7)
//| onewire.reset()
//| onewire.write_bit(True)
//| onewire.write_bit(False)
@ -101,7 +101,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_deinit_obj, bitbangio_onewire
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t bitbangio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -102,7 +102,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_deinit_obj, bitbangio_spi_obj_deinit);
//| .. method:: SPI.__exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t bitbangio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -64,21 +64,24 @@
//| OneWire
//| SPI
//|
//| All libraries change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
//| For example::
//|
//| import bitbangio
//| from board import *
//|
//| with bitbangio.I2C(SCL, SDA) as i2c:
//| i2c.scan()
//| i2c = bitbangio.I2C(SCL, SDA)
//| print(i2c.scan())
//| i2c.deinit()
//|
//| This example will initialize the the device, run
//| :py:meth:`~bitbangio.I2C.scan` and then :py:meth:`~bitbangio.I2C.deinit` the
//| hardware.
//| hardware. The last step is optional because CircuitPython automatically
//| resets hardware after a program finishes.
//|
STATIC const mp_rom_map_elem_t bitbangio_module_globals_table[] = {

View File

@ -99,7 +99,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_deinit_obj, busio_i2c_obj_deinit);
//| .. method:: I2C.__exit__()
//|
//| Automatically deinitializes the hardware on context exit.
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -55,7 +55,7 @@
//| import busio
//| import board
//|
//| with busio.OneWire(board.D7) as onewire:
//| onewire = busio.OneWire(board.D7)
//| onewire.reset()
//| onewire.write_bit(True)
//| onewire.write_bit(False)
@ -101,7 +101,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit)
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t busio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -115,7 +115,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit);
//| .. method:: SPI.__exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -132,7 +132,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_deinit_obj, busio_uart_obj_deinit);
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t busio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -65,21 +65,24 @@
//| SPI
//| UART
//|
//| All libraries change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
//| For example::
//|
//| import busio
//| from board import *
//|
//| with busio.I2C(SCL, SDA) as i2c:
//| i2c.scan()
//| i2c = busio.I2C(SCL, SDA)
//| print(i2c.scan())
//| i2c.deinit()
//|
//| This example will initialize the the device, run
//| :py:meth:`~busio.I2C.scan` and then :py:meth:`~busio.I2C.deinit` the
//| hardware.
//| hardware. The last step is optional because CircuitPython automatically
//| resets hardware after a program finishes.
//|
STATIC const mp_rom_map_elem_t busio_module_globals_table[] = {

View File

@ -90,7 +90,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_deinit_obj, digitalio_digitalin
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;
@ -145,7 +146,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_output_obj, 1, digit
//| import digitalio
//| import board
//|
//| with digitalio.DigitalInOut(board.SLIDE_SWITCH) as switch:
//| switch = digitalio.DigitalInOut(board.SLIDE_SWITCH)
//| switch.switch_to_input(pull=digitalio.DigitalInOut.Pull.UP)
//| # Or, after switch_to_input
//| switch.pull = digitalio.DigitalInOut.Pull.UP

View File

@ -52,15 +52,16 @@
//| DigitalInOut
//|
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
//| For example::
//|
//| import digitalio
//| from board import *
//|
//| with digitalio.DigitalInOut(D13) as pin:
//| pin = digitalio.DigitalInOut(D13)
//| print(pin.value)
//|
//| This example will initialize the the device, read
@ -73,8 +74,8 @@
//| from board import *
//| import time
//|
//| with digitalio.DigitalInOut(D13) as led:
//| led.switch_to_output()
//| led = digitalio.DigitalInOut(D13)
//| led.direction = digitalio.DigitalInOut.Direction.OUT
//| while True:
//| led.value = True
//| time.sleep(0.1)

View File

@ -7,6 +7,8 @@ in a port if no underlying hardware support is present or if flash space is
limited. For example, a microcontroller without analog features will not have
`analogio`.
.. _module-support-matrix:
Support Matrix
---------------

View File

@ -60,7 +60,7 @@
//| import pulseio
//| import board
//|
//| with pulseio.PWMOut(board.D13) as pwm: # output on D13
//| pwm = pulseio.PWMOut(board.D13) # output on D13
//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at the default 500hz
//|
//| PWM at specific frequency (servos and motors)::
@ -68,7 +68,7 @@
//| import pulseio
//| import board
//|
//| with pulseio.PWMOut(board.D13, frequency=50) as pwm:
//| pwm = pulseio.PWMOut(board.D13, frequency=50)
//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at 50hz
//|
//| Variable frequency (usually tones)::
@ -77,7 +77,7 @@
//| import board
//| import time
//|
//| with pulseio.PWMOut(board.D13, duty_cycle=2 ** 15, frequency=440, variable_frequency=True) as pwm:
//| pwm = pulseio.PWMOut(board.D13, duty_cycle=2 ** 15, frequency=440, variable_frequency=True)
//| time.sleep(0.2)
//| pwm.frequency = 880
//| time.sleep(0.1)
@ -131,7 +131,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_deinit_obj, pulseio_pwmout_deini
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t pulseio_pwmout_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -61,7 +61,8 @@
//| import pulseio
//| import board
//|
//| with pulseio.PulseIn(board.D7) as pulses:
//| pulses = pulseio.PulseIn(board.D7)
//|
//| # Wait for an active pulse
//| while len(pulses) == 0:
//| pass
@ -122,7 +123,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_deinit_obj, pulseio_pulsein_dei
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t pulseio_pulsein_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -54,7 +54,7 @@
//| import pulseio
//| import board
//|
//| with pulseio.PWMOut(board.D13, duty_cycle=2 ** 15) as pwm:
//| pwm = pulseio.PWMOut(board.D13, duty_cycle=2 ** 15)
//| pulse = pulseio.PulseOut(pwm)
//| # on off on off on
//| pulses = array.array('H', [65000, 1000, 65000, 65000, 1000])
@ -100,7 +100,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulseout_deinit_obj, pulseio_pulseout_d
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t pulseio_pulseout_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -53,9 +53,15 @@
//| PulseOut
//| PWMOut
//|
//| All libraries change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| .. warning:: This module is not available in some SAMD21 builds. See the
//| :ref:`module-support-matrix` for more info.
//|
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
//| For example::
//|
@ -63,13 +69,15 @@
//| import time
//| from board import *
//|
//| with pulseio.PWMOut(D13) as pin:
//| pin.duty_cycle = 2 ** 15
//| pwm = pulseio.PWMOut(D13)
//| pwm.duty_cycle = 2 ** 15
//| time.sleep(0.1)
//|
//| This example will initialize the the device, set
//| :py:data:`~pulseio.PWMOut.duty_cycle`, sleep 0.1 seconds and then
//| :py:meth:`~pulseio.PWMOut.deinit` the hardware.
//| :py:data:`~pulseio.PWMOut.duty_cycle`, and then sleep 0.1 seconds.
//| CircuitPython will automatically turn off the PWM when it resets all
//| hardware after program completion. Use ``deinit()`` or a ``with`` statement
//| to do it yourself.
//|
STATIC const mp_rom_map_elem_t pulseio_module_globals_table[] = {

View File

@ -39,7 +39,7 @@
//| :synopsis: time and timing related functions
//| :platform: SAMD21
//|
//| The `time` module is a strict subset of the CPython `time` module. So, code
//| The `time` module is a strict subset of the CPython `cpython:time` module. So, code
//| written in MicroPython will work in CPython but not necessarily the other
//| way around.
//|

View File

@ -45,7 +45,8 @@
//| import touchio
//| from board import *
//|
//| with touchio.TouchIn(A1) as touch:
//| touch = touchio.TouchIn(A1)
//| while True:
//| if touch.value:
//| print("touched!")
//|
@ -92,7 +93,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_deinit_obj, touchio_touchin_dei
//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context.
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
STATIC mp_obj_t touchio_touchin_obj___exit__(size_t n_args, const mp_obj_t *args) {
(void)n_args;

View File

@ -52,21 +52,21 @@
//|
//| TouchIn
//|
//| All libraries change hardware state and should be deinitialized when they
//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a
//| context manager.
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
//| For example::
//|
//| import touchio
//| from board import *
//|
//| with touchio.TouchIn(D6) as touch_pin:
//| touch_pin = touchio.TouchIn(D6)
//| print(touch_pin.value)
//|
//| This example will initialize the the device, run
//| :py:data:`~touchio.TouchIn.value` and then :py:meth:`~touchio.TouchIn.deinit`
//| the hardware.
//| This example will initialize the the device, and print the
//| :py:data:`~touchio.TouchIn.value`.
//|
STATIC const mp_rom_map_elem_t touchio_module_globals_table[] = {

View File

@ -41,10 +41,6 @@
//| The `usb_hid` module allows you to output data as a HID device.
//|
//| .. warning:: This module may be dropped from builds without external flash
//| in the future. Please file an issue if this a problem and explain why.
//|
//| .. attribute:: usb_hid.devices
//|
//| Tuple of all active HID device interfaces.