From 5fe90ec204ad037f2dadd892e6f073cd404f540d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Aug 2022 12:54:58 -0700 Subject: [PATCH 1/7] Add register library topic to design guide --- docs/design_guide.rst | 63 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/docs/design_guide.rst b/docs/design_guide.rst index fdb8f9b019..61ba0ed5b3 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -494,6 +494,39 @@ backticks ``:class:`~adafruit_motor.servo.Servo```. You must also add the refer "adafruit_motor": ("https://circuitpython.readthedocs.io/projects/motor/en/latest/", None,), +Use ``adafruit_register`` when possible +-------------------------------------------------------------------------------- +`Register `_ is +a foundational library that manages packing and unpacking data from device +registers. When possible, use it for unpacking and packing registers. This +ensures the packing code is shared amongst all registers. Furthermore, it +simplifies device definitions by making them declarative (only data.) + +*Do not* add all registers from a datasheet upfront. Instead, only add the ones +necessary for the functionality the driver exposes. Adding them all will lead to +unnecessary file size and API clutter. See `this video about outside-in design +from @tannewt `_. + +I2C Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + from adafruit_register import i2c_bit + from adafruit_bus_device import i2c_device + + class HelloWorldDevice: + """Device with two bits to control when the words 'hello' and 'world' are lit.""" + + hello = i2c_bit.RWBit(0x0, 0x0) + """Bit to indicate if hello is lit.""" + + world = i2c_bit.RWBit(0x1, 0x0) + """Bit to indicate if world is lit.""" + + def __init__(self, i2c, device_address=0x0): + self.i2c_device = i2c_device.I2CDevice(i2c, device_address) + Use BusDevice -------------------------------------------------------------------------------- @@ -668,8 +701,24 @@ when using ``const()``, keep in mind these general guide lines: - Always use via an import, ex: ``from micropython import const`` - Limit use to global (module level) variables only. -- If user will not need access to variable, prefix name with a leading - underscore, ex: ``_SOME_CONST``. +- Only used when the user will not need access to variable and prefix name with + a leading underscore, ex: ``_SOME_CONST``. + +Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: python + + from adafruit_bus_device import i2c_device + from micropython import const + + _DEFAULT_I2C_ADDR = const(0x42) + + class Widget: + """A generic widget.""" + + def __init__(self, i2c, address=_DEFAULT_I2C_ADDR): + self.i2c_device = i2c_device.I2CDevice(i2c, address) Libraries Examples ------------------ @@ -751,6 +800,16 @@ properties. | ``sound_level`` | float | non-unit-specific sound level (monotonic but not actual decibels) | +-----------------------+-----------------------+-------------------------------------------------------------------------+ +Driver constant naming +-------------------------------------------------------------------------------- + +When adding variables for constant values for a driver. Do not include the +device's name in the variable name. For example, in ``adafruit_fancy123.py``, +variables should not start with ``FANCY123_``. Adding this prefix increases RAM +usage and .mpy file size because variable names are preserved. User code should +refer to these constants as ``adafruit_fancy123.HELLO_WORLD`` for clarity. +``adafruit_fancy123.FANCY123_HELLO_WORLD`` would be overly verbose. + Adding native modules -------------------------------------------------------------------------------- From 35f3773e94b476d5f6c1e98284809846cd721708 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Aug 2022 14:55:13 -0700 Subject: [PATCH 2/7] Remove PWMOut parameter to PulseOut Fixes #3264 --- shared-bindings/onewireio/OneWire.c | 3 --- shared-bindings/pulseio/PulseOut.c | 11 ----------- 2 files changed, 14 deletions(-) diff --git a/shared-bindings/onewireio/OneWire.c b/shared-bindings/onewireio/OneWire.c index a167c86cc8..6ce5b659e7 100644 --- a/shared-bindings/onewireio/OneWire.c +++ b/shared-bindings/onewireio/OneWire.c @@ -42,9 +42,6 @@ //| //| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus //| -//| .. note:: The OneWire class is available on `busio` and `bitbangio` in CircuitPython -//| 7.x for backwards compatibility but will be removed in CircuitPython 8.0.0. -//| //| Read a short series of pulses:: //| //| import onewireio diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 3de2176ffc..f812043e13 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -48,9 +48,6 @@ //| :param int frequency: Carrier signal frequency in Hertz //| :param int duty_cycle: 16-bit duty cycle of carrier frequency (0 - 65536) //| -//| For backwards compatibility, ``pin`` may be a PWMOut object used as the carrier. This -//| compatibility will be removed in CircuitPython 8.0.0. -//| //| Send a short series of pulses:: //| //| import array @@ -82,14 +79,6 @@ STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar const mcu_pin_obj_t *pin = args[ARG_pin].u_obj; mp_int_t frequency = args[ARG_frequency].u_int; mp_int_t duty_cycle = args[ARG_duty_cycle].u_int; - if (mp_obj_is_type(args[ARG_pin].u_obj, &pwmio_pwmout_type)) { - pwmio_pwmout_obj_t *pwmout = args[ARG_pin].u_obj; - duty_cycle = common_hal_pwmio_pwmout_get_duty_cycle(pwmout); - frequency = common_hal_pwmio_pwmout_get_frequency(pwmout); - pin = common_hal_pwmio_pwmout_get_pin(pwmout); - // Deinit the pin so we can use it. - common_hal_pwmio_pwmout_deinit(pwmout); - } validate_obj_is_free_pin(MP_OBJ_FROM_PTR(pin)); pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t); self->base.type = &pulseio_pulseout_type; From 412d6fee566f2401cd6affc04fa6bb5de611a5c0 Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Wed, 10 Aug 2022 19:55:00 +0200 Subject: [PATCH 3/7] Bump circuitpython-stage to 1.3.5 --- frozen/circuitpython-stage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index f993d5fac6..9a8338b3bd 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit f993d5fac69f3a0cfa33988268666c462b72c0ec +Subproject commit 9a8338b3bdaeac9eeb5b74d147107c67db33fdac From 92231e88ca95ed92c98f62ee3cd301e57519ec90 Mon Sep 17 00:00:00 2001 From: Hanns Holger Rutz Date: Wed, 10 Aug 2022 21:49:18 +0200 Subject: [PATCH 4/7] Touchin.c - fix clean up in constructor before exception is thrown When the constructor value reading times out, an exception is thrown, but the digital pin is not de-initialised. Make sure to run the clean up, so user could catch the exception and retry using the same pin. --- shared-module/touchio/TouchIn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-module/touchio/TouchIn.c b/shared-module/touchio/TouchIn.c index 840c14571d..35dd56a6e4 100644 --- a/shared-module/touchio/TouchIn.c +++ b/shared-module/touchio/TouchIn.c @@ -78,6 +78,7 @@ void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu uint16_t raw_reading = get_raw_reading(self); if (raw_reading == TIMEOUT_TICKS) { + common_hal_touchio_touchin_deinit(self); mp_raise_ValueError(translate("No pulldown on pin; 1Mohm recommended")); } self->threshold = raw_reading * 1.05 + 100; From f9d724c09e5190c1bbfb6b39b6ff4aa8a649a421 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 10 Aug 2022 15:24:08 -0700 Subject: [PATCH 5/7] Fix retries after successful connection. We may have set retries to 0 to enforce a timeout but the connect succeeded. When it succeeds, we want to allow retries later in case we lose signal briefly. (The callback will do this too but the connect function will override it after.) Also, remove extra code from websocket that is leftover from debugging. --- ports/espressif/common-hal/wifi/Radio.c | 3 +++ supervisor/shared/web_workflow/websocket.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c index 545af1d6cb..8616501ba2 100644 --- a/ports/espressif/common-hal/wifi/Radio.c +++ b/ports/espressif/common-hal/wifi/Radio.c @@ -336,6 +336,9 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t return WIFI_RADIO_ERROR_NO_AP_FOUND; } return self->last_disconnect_reason; + } else { + // We're connected, allow us to retry if we get disconnected. + self->retries_left = self->starting_retries; } return WIFI_RADIO_ERROR_NONE; } diff --git a/supervisor/shared/web_workflow/websocket.c b/supervisor/shared/web_workflow/websocket.c index bb5f5b43d0..79f1a63d7e 100644 --- a/supervisor/shared/web_workflow/websocket.c +++ b/supervisor/shared/web_workflow/websocket.c @@ -248,9 +248,6 @@ static void _websocket_send(_websocket *ws, const char *text, size_t len) { _send_raw(&ws->socket, extended_len, 4); } _send_raw(&ws->socket, (const uint8_t *)text, len); - char copy[len]; - memcpy(copy, text, len); - copy[len] = '\0'; } void websocket_write(const char *text, size_t len) { From 9c6c8b5d628fce2cfec9588ef2e6f06722ff0468 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 10 Aug 2022 16:31:50 -0700 Subject: [PATCH 6/7] Don't build boards for docs changes --- tools/ci_set_matrix.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci_set_matrix.py b/tools/ci_set_matrix.py index 03aa362632..90cf04cea6 100644 --- a/tools/ci_set_matrix.py +++ b/tools/ci_set_matrix.py @@ -96,8 +96,8 @@ def set_boards_to_build(build_all): if p in IGNORE: continue - # Boards don't run tests so ignore those as well. - if p.startswith("tests"): + # Boards don't run tests or docs so ignore those as well. + if p.startswith("tests") or p.startswith("docs"): continue # As a (nearly) last resort, for some certain files, we compute the settings from the From 553367105f24d159fd8070e8ce053cf6cfc70c44 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 11 Aug 2022 11:01:16 -0700 Subject: [PATCH 7/7] Add examples of non-applicable cases and SPI link --- docs/design_guide.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/design_guide.rst b/docs/design_guide.rst index 61ba0ed5b3..6da73b2fdb 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -497,10 +497,16 @@ backticks ``:class:`~adafruit_motor.servo.Servo```. You must also add the refer Use ``adafruit_register`` when possible -------------------------------------------------------------------------------- `Register `_ is -a foundational library that manages packing and unpacking data from device -registers. When possible, use it for unpacking and packing registers. This -ensures the packing code is shared amongst all registers. Furthermore, it -simplifies device definitions by making them declarative (only data.) +a foundational library that manages packing and unpacking data from I2C device +registers. There is also `Register SPI `_ +for SPI devices. When possible, use one of these libraries for unpacking and +packing registers. This ensures the packing code is shared amongst all +registers (even across drivers). Furthermore, it simplifies device definitions +by making them declarative (only data.) + +Values with non-consecutive bits in a register or that represent FIFO endpoints +may not map well to existing register classes. In unique cases like these, it is +ok to read and write the register directly. *Do not* add all registers from a datasheet upfront. Instead, only add the ones necessary for the functionality the driver exposes. Adding them all will lead to