From 5fe90ec204ad037f2dadd892e6f073cd404f540d Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 9 Aug 2022 12:54:58 -0700 Subject: [PATCH 1/4] 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 fdb8f9b019857..61ba0ed5b3a86 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 f9d724c09e5190c1bbfb6b39b6ff4aa8a649a421 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 10 Aug 2022 15:24:08 -0700 Subject: [PATCH 2/4] 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 545af1d6cbc6f..8616501ba258d 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 bb5f5b43d015a..79f1a63d7e018 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 3/4] 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 03aa362632a42..90cf04cea63d6 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 4/4] 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 61ba0ed5b3a86..6da73b2fdb8d6 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