From ea0e2f80b7612d7d3119355a455667b3c4beb6d7 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Mon, 4 Jan 2021 23:11:25 -0600 Subject: Changing to duck-typing --- shared-bindings/adafruit_bus_device/I2CDevice.c | 81 ++++++++++++------------- shared-bindings/adafruit_bus_device/I2CDevice.h | 4 +- 2 files changed, 41 insertions(+), 44 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/adafruit_bus_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/I2CDevice.c index a4c04e198..d3b6fbec4 100644 --- a/shared-bindings/adafruit_bus_device/I2CDevice.c +++ b/shared-bindings/adafruit_bus_device/I2CDevice.c @@ -31,6 +31,7 @@ #include "shared-bindings/adafruit_bus_device/I2CDevice.h" #include "shared-bindings/util.h" #include "shared-module/adafruit_bus_device/I2CDevice.h" +#include "shared-bindings/busio/I2C.h" #include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" @@ -76,7 +77,7 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - busio_i2c_obj_t* i2c = args[ARG_i2c].u_obj; + mp_obj_t* i2c = args[ARG_i2c].u_obj; common_hal_adafruit_bus_device_i2cdevice_construct(MP_OBJ_TO_PTR(self), i2c, args[ARG_device_address].u_int); if (args[ARG_probe].u_bool == true) { @@ -107,7 +108,7 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_obj___exit__(size_t n_args, const } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit___obj, 4, 4, adafruit_bus_device_i2cdevice_obj___exit__); -//| def readinto(self, buf: WriteableBuffer, *, start: int = 0, end: int = 0) -> None: +//| def readinto(self, buf: WriteableBuffer, *, start: int = 0, end: Optional[int] = None) -> None: //| """Read into ``buf`` from the device. The number of bytes read will be the //| length of ``buf``. //| If ``start`` or ``end`` is provided, then the buffer will be sliced @@ -118,22 +119,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit_ //| :param int end: Index to write up to but not include; if None, use ``len(buf)``""" //| ... //| -STATIC void readinto(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, int32_t start, mp_int_t end) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_WRITE); - - size_t length = bufinfo.len; - normalize_buffer_bounds(&start, end, &length); - if (length == 0) { - mp_raise_ValueError(translate("Buffer must be at least length 1")); - } - - uint8_t status = common_hal_adafruit_bus_device_i2cdevice_readinto(MP_OBJ_TO_PTR(self), ((uint8_t*)bufinfo.buf) + start, length); - if (status != 0) { - mp_raise_OSError(status); - } -} - STATIC mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -147,12 +132,21 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_o mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - readinto(self, args[ARG_buffer].u_obj, args[ARG_start].u_int, args[ARG_end].u_int); + mp_obj_t dest[8]; + mp_load_method(self->i2c, MP_QSTR_readfrom_into, dest); + dest[2] = mp_obj_new_int_from_ull(self->device_address); + dest[3] = args[ARG_buffer].u_obj; + dest[4] = mp_obj_new_str("start", 5); + dest[5] = mp_obj_new_int(args[ARG_start].u_int); + dest[6] = mp_obj_new_str("end", 3); + dest[7] = mp_obj_new_int(args[ARG_end].u_int); + mp_call_method_n_kw(2, 2, dest); + return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 2, adafruit_bus_device_i2cdevice_readinto); -//| def write(self, buf: ReadableBuffer, *, start: int = 0, end: int = 0) -> None: +//| def write(self, buf: ReadableBuffer, *, start: int = 0, end: Optional[int] = None) -> None: //| """Write the bytes from ``buffer`` to the device, then transmit a stop bit. //| If ``start`` or ``end`` is provided, then the buffer will be sliced //| as if ``buffer[start:end]``. This will not cause an allocation like @@ -163,22 +157,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 2, //| """ //| ... //| -STATIC void write(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, int32_t start, mp_int_t end, bool transmit_stop_bit) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_READ); - - size_t length = bufinfo.len; - normalize_buffer_bounds(&start, end, &length); - if (length == 0) { - mp_raise_ValueError(translate("Buffer must be at least length 1")); - } - - uint8_t status = common_hal_adafruit_bus_device_i2cdevice_write(MP_OBJ_TO_PTR(self), ((uint8_t*)bufinfo.buf) + start, length, transmit_stop_bit); - if (status != 0) { - mp_raise_OSError(status); - } -} - STATIC mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -191,13 +169,22 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - write(self, args[ARG_buffer].u_obj, args[ARG_start].u_int, args[ARG_end].u_int, true); + mp_obj_t dest[8]; + mp_load_method(self->i2c, MP_QSTR_writeto, dest); + dest[2] = mp_obj_new_int_from_ull(self->device_address); + dest[3] = args[ARG_buffer].u_obj; + dest[4] = mp_obj_new_str("start", 5); + dest[5] = mp_obj_new_int(args[ARG_start].u_int); + dest[6] = mp_obj_new_str("end", 3); + dest[7] = mp_obj_new_int(args[ARG_end].u_int); + mp_call_method_n_kw(2, 2, dest); + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_write_obj, 2, adafruit_bus_device_i2cdevice_write); -//| def write_then_readinto(self, out_buffer: WriteableBuffer, in_buffer: ReadableBuffer, *, out_start: int = 0, out_end: int = 0, in_start: int = 0, in_end: int = 0) -> None: +//| def write_then_readinto(self, out_buffer: WriteableBuffer, in_buffer: ReadableBuffer, *, out_start: int = 0, out_end: Optional[int] = None, in_start: int = 0, in_end: Optional[int] = None) -> None: //| """Write the bytes from ``out_buffer`` to the device, then immediately //| reads into ``in_buffer`` from the device. The number of bytes read //| will be the length of ``in_buffer``. @@ -233,9 +220,21 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_write_then_readinto(size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - write(self, args[ARG_out_buffer].u_obj, args[ARG_out_start].u_int, args[ARG_out_end].u_int, false); - - readinto(self, args[ARG_in_buffer].u_obj, args[ARG_in_start].u_int, args[ARG_in_end].u_int); + mp_obj_t dest[13]; + mp_load_method(self->i2c, MP_QSTR_writeto_then_readfrom, dest); + dest[2] = mp_obj_new_int_from_ull(self->device_address); + dest[3] = args[ARG_out_buffer].u_obj; + dest[4] = args[ARG_in_buffer].u_obj; + dest[5] = mp_obj_new_str("out_start", 9); + dest[6] = mp_obj_new_int(args[ARG_out_start].u_int); + dest[7] = mp_obj_new_str("out_end", 7); + dest[8] = mp_obj_new_int(args[ARG_out_end].u_int); + dest[9] = mp_obj_new_str("in_start", 8); + dest[10] = mp_obj_new_int(args[ARG_in_start].u_int); + dest[11] = mp_obj_new_str("in_end", 6); + dest[12] = mp_obj_new_int(args[ARG_in_end].u_int); + + mp_call_method_n_kw(3, 4, dest); return mp_const_none; } diff --git a/shared-bindings/adafruit_bus_device/I2CDevice.h b/shared-bindings/adafruit_bus_device/I2CDevice.h index cf7b1321a..82ef1feb8 100644 --- a/shared-bindings/adafruit_bus_device/I2CDevice.h +++ b/shared-bindings/adafruit_bus_device/I2CDevice.h @@ -43,9 +43,7 @@ extern const mp_obj_type_t adafruit_bus_device_i2cdevice_type; // Initializes the hardware peripheral. -extern void common_hal_adafruit_bus_device_i2cdevice_construct(adafruit_bus_device_i2cdevice_obj_t *self, busio_i2c_obj_t *i2c, uint8_t device_address); -extern uint8_t common_hal_adafruit_bus_device_i2cdevice_readinto(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, size_t length); -extern uint8_t common_hal_adafruit_bus_device_i2cdevice_write(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t buffer, size_t length, bool transmit_stop_bit); +extern void common_hal_adafruit_bus_device_i2cdevice_construct(adafruit_bus_device_i2cdevice_obj_t *self, mp_obj_t *i2c, uint8_t device_address); extern void common_hal_adafruit_bus_device_i2cdevice_lock(adafruit_bus_device_i2cdevice_obj_t *self); extern void common_hal_adafruit_bus_device_i2cdevice_unlock(adafruit_bus_device_i2cdevice_obj_t *self); extern void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_device_i2cdevice_obj_t *self); -- cgit v1.2.3 From b609bc012434e1a8753196b2d020a3d05faf7948 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Tue, 5 Jan 2021 16:29:37 -0600 Subject: Removed unused include --- shared-bindings/adafruit_bus_device/I2CDevice.c | 1 - 1 file changed, 1 deletion(-) (limited to 'shared-bindings') diff --git a/shared-bindings/adafruit_bus_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/I2CDevice.c index d3b6fbec4..f76cfb0e1 100644 --- a/shared-bindings/adafruit_bus_device/I2CDevice.c +++ b/shared-bindings/adafruit_bus_device/I2CDevice.c @@ -31,7 +31,6 @@ #include "shared-bindings/adafruit_bus_device/I2CDevice.h" #include "shared-bindings/util.h" #include "shared-module/adafruit_bus_device/I2CDevice.h" -#include "shared-bindings/busio/I2C.h" #include "lib/utils/buffer_helper.h" #include "lib/utils/context_manager_helpers.h" -- cgit v1.2.3 From d3995eaf9748f641355a92c2929f3330a027b586 Mon Sep 17 00:00:00 2001 From: gamblor21 Date: Sat, 9 Jan 2021 10:07:08 -0600 Subject: Fixes from draft PR --- shared-bindings/adafruit_bus_device/I2CDevice.c | 17 +++++++------ shared-module/adafruit_bus_device/I2CDevice.c | 33 +++++++------------------ 2 files changed, 18 insertions(+), 32 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/adafruit_bus_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/I2CDevice.c index f76cfb0e1..15e8cc706 100644 --- a/shared-bindings/adafruit_bus_device/I2CDevice.c +++ b/shared-bindings/adafruit_bus_device/I2CDevice.c @@ -135,9 +135,10 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_o mp_load_method(self->i2c, MP_QSTR_readfrom_into, dest); dest[2] = mp_obj_new_int_from_ull(self->device_address); dest[3] = args[ARG_buffer].u_obj; - dest[4] = mp_obj_new_str("start", 5); + //dest[4] = mp_obj_new_str("start", 5); + dest[4] = MP_OBJ_NEW_QSTR(MP_QSTR_start); dest[5] = mp_obj_new_int(args[ARG_start].u_int); - dest[6] = mp_obj_new_str("end", 3); + dest[6] = MP_OBJ_NEW_QSTR(MP_QSTR_end); dest[7] = mp_obj_new_int(args[ARG_end].u_int); mp_call_method_n_kw(2, 2, dest); @@ -172,9 +173,9 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_ mp_load_method(self->i2c, MP_QSTR_writeto, dest); dest[2] = mp_obj_new_int_from_ull(self->device_address); dest[3] = args[ARG_buffer].u_obj; - dest[4] = mp_obj_new_str("start", 5); + dest[4] = MP_OBJ_NEW_QSTR(MP_QSTR_start); dest[5] = mp_obj_new_int(args[ARG_start].u_int); - dest[6] = mp_obj_new_str("end", 3); + dest[6] = MP_OBJ_NEW_QSTR(MP_QSTR_end); dest[7] = mp_obj_new_int(args[ARG_end].u_int); mp_call_method_n_kw(2, 2, dest); @@ -224,13 +225,13 @@ STATIC mp_obj_t adafruit_bus_device_i2cdevice_write_then_readinto(size_t n_args, dest[2] = mp_obj_new_int_from_ull(self->device_address); dest[3] = args[ARG_out_buffer].u_obj; dest[4] = args[ARG_in_buffer].u_obj; - dest[5] = mp_obj_new_str("out_start", 9); + dest[5] = MP_OBJ_NEW_QSTR(MP_QSTR_out_start); dest[6] = mp_obj_new_int(args[ARG_out_start].u_int); - dest[7] = mp_obj_new_str("out_end", 7); + dest[7] = MP_OBJ_NEW_QSTR(MP_QSTR_out_end); dest[8] = mp_obj_new_int(args[ARG_out_end].u_int); - dest[9] = mp_obj_new_str("in_start", 8); + dest[9] = MP_OBJ_NEW_QSTR(MP_QSTR_in_start); dest[10] = mp_obj_new_int(args[ARG_in_start].u_int); - dest[11] = mp_obj_new_str("in_end", 6); + dest[11] = MP_OBJ_NEW_QSTR(MP_QSTR_in_end); dest[12] = mp_obj_new_int(args[ARG_in_end].u_int); mp_call_method_n_kw(3, 4, dest); diff --git a/shared-module/adafruit_bus_device/I2CDevice.c b/shared-module/adafruit_bus_device/I2CDevice.c index 53811d491..792ab7183 100644 --- a/shared-module/adafruit_bus_device/I2CDevice.c +++ b/shared-module/adafruit_bus_device/I2CDevice.c @@ -68,37 +68,22 @@ void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_devi mp_obj_t dest[4]; /* catch exceptions that may be thrown while probing for the device */ - nlr_buf_t write_nlr; - if (nlr_push(&write_nlr) == 0) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { mp_load_method(self->i2c, MP_QSTR_writeto, dest); dest[2] = mp_obj_new_int_from_ull(self->device_address); dest[3] = write_buffer; mp_call_method_n_kw(2, 0, dest); nlr_pop(); } else { - /* some OS's don't like writing an empty bytestring... retry by reading a byte */ - mp_buffer_info_t read_bufinfo; - mp_obj_t read_buffer = mp_obj_new_bytearray_of_zeros(1); - mp_get_buffer_raise(read_buffer, &read_bufinfo, MP_BUFFER_WRITE); + common_hal_adafruit_bus_device_i2cdevice_unlock(self); - mp_load_method(self->i2c, MP_QSTR_readfrom_into, dest); - dest[2] = mp_obj_new_int_from_ull(self->device_address); - dest[3] = read_buffer; - - nlr_buf_t read_nlr; - if (nlr_push(&read_nlr) == 0) { - mp_call_method_n_kw(2, 0, dest); - nlr_pop(); - } else { - /* At this point we tried two methods and only got exceptions */ - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t*)read_nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { - common_hal_adafruit_bus_device_i2cdevice_unlock(self); - mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address); - } - else { - /* In case we receive an unrelated exception pass it up */ - nlr_raise(MP_OBJ_FROM_PTR(read_nlr.ret_val)); - } + if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t*)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { + mp_raise_ValueError_varg(translate("No I2C device at address: %x"), self->device_address); + } + else { + /* In case we receive an unrelated exception pass it up */ + nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val)); } } -- cgit v1.2.3 From dff3423c231c07751175ded39a18beef28aecd4f Mon Sep 17 00:00:00 2001 From: James Bowman Date: Fri, 22 Jan 2021 15:52:46 -0800 Subject: Change from fixed-point integer arguments to floating point in EVE API functions Changed calls: PointSize(), LineWidth(), VertexTranslateX() and VertexTranslateY() Units for all the above are now pixels, not fixed-point integers. This matches OpenGL. Docstrings updated accordingly --- shared-bindings/_eve/__init__.c | 150 ++++++++++++++++++++-------------------- shared-bindings/_eve/__init__.h | 8 +-- shared-module/_eve/__init__.c | 20 +++--- 3 files changed, 92 insertions(+), 86 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c index 0f628b6fb..c043aa5fa 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -604,22 +604,6 @@ STATIC mp_obj_t _jump(mp_obj_t self, mp_obj_t a0) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(jump_obj, _jump); -//| def LineWidth(self, width: int) -> None: -//| """Set the width of rasterized lines -//| -//| :param int width: line width in :math:`1/16` pixel. Range 0-4095. The initial value is 16 -//| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" -//| ... -//| - -STATIC mp_obj_t _linewidth(mp_obj_t self, mp_obj_t a0) { - uint32_t width = mp_obj_get_int_truncated(a0); - common_hal__eve_LineWidth(EVEHAL(self), width); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(linewidth_obj, _linewidth); - //| def Macro(self, m: int) -> None: //| """Execute a single command from a macro register //| @@ -662,22 +646,6 @@ STATIC mp_obj_t _palettesource(mp_obj_t self, mp_obj_t a0) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(palettesource_obj, _palettesource); -//| def PointSize(self, size: int) -> None: -//| """Set the radius of rasterized points -//| -//| :param int size: point radius in :math:`1/16` pixel. Range 0-8191. The initial value is 16 -//| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" -//| ... -//| - -STATIC mp_obj_t _pointsize(mp_obj_t self, mp_obj_t a0) { - uint32_t size = mp_obj_get_int_truncated(a0); - common_hal__eve_PointSize(EVEHAL(self), size); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize); - //| def RestoreContext(self) -> None: //| """Restore the current graphics context from the context stack""" //| ... @@ -836,48 +804,6 @@ STATIC mp_obj_t _tag(mp_obj_t self, mp_obj_t a0) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(tag_obj, _tag); -//| def VertexTranslateX(self, x: int) -> None: -//| """Set the vertex transformation's x translation component -//| -//| :param int x: signed x-coordinate in :math:`1/16` pixel. Range 0-131071. The initial value is 0 -//| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" -//| ... -//| - -STATIC mp_obj_t _vertextranslatex(mp_obj_t self, mp_obj_t a0) { - uint32_t x = mp_obj_get_int_truncated(a0); - common_hal__eve_VertexTranslateX(EVEHAL(self), x); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatex_obj, _vertextranslatex); - -//| def VertexTranslateY(self, y: int) -> None: -//| """Set the vertex transformation's y translation component -//| -//| :param int y: signed y-coordinate in :math:`1/16` pixel. Range 0-131071. The initial value is 0 -//| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" -//| ... -//| - - -STATIC mp_obj_t _vertextranslatey(mp_obj_t self, mp_obj_t a0) { - uint32_t y = mp_obj_get_int_truncated(a0); - common_hal__eve_VertexTranslateY(EVEHAL(self), y); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey); - -//| def VertexFormat(self, frac: int) -> None: -//| """Set the precision of vertex2f coordinates -//| -//| :param int frac: Number of fractional bits in X,Y coordinates, 0-4. Range 0-7. The initial value is 4 -//| -//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" -//| ... -//| - STATIC mp_obj_t _vertexformat(mp_obj_t self, mp_obj_t a0) { uint32_t frac = mp_obj_get_int_truncated(a0); common_hal__eve_VertexFormat(EVEHAL(self), frac); @@ -975,6 +901,82 @@ STATIC mp_obj_t _vertex2f(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { } STATIC MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f); +//| def LineWidth(self, width: float) -> None: +//| """Set the width of rasterized lines +//| +//| :param float width: line width in pixels. Range 0-511. The initial value is 1 +//| +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| ... +//| + +STATIC mp_obj_t _linewidth(mp_obj_t self, mp_obj_t a0) { + mp_float_t width = mp_obj_get_float(a0); + common_hal__eve_LineWidth(EVEHAL(self), width); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(linewidth_obj, _linewidth); + +//| def PointSize(self, size: float) -> None: +//| """Set the diameter of rasterized points +//| +//| :param float size: point diameter in pixels. Range 0-1023. The initial value is 1 +//| +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| ... +//| + +STATIC mp_obj_t _pointsize(mp_obj_t self, mp_obj_t a0) { + mp_float_t size = mp_obj_get_float(a0); + common_hal__eve_PointSize(EVEHAL(self), size); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize); + +//| def VertexTranslateX(self, x: float) -> None: +//| """Set the vertex transformation's x translation component +//| +//| :param float x: signed x-coordinate in pixels. Range ±4095. The initial value is 0 +//| +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| ... +//| + +STATIC mp_obj_t _vertextranslatex(mp_obj_t self, mp_obj_t a0) { + mp_float_t x = mp_obj_get_float(a0); + common_hal__eve_VertexTranslateX(EVEHAL(self), x); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatex_obj, _vertextranslatex); + +//| def VertexTranslateY(self, y: float) -> None: +//| """Set the vertex transformation's y translation component +//| +//| :param float y: signed y-coordinate in pixels. Range ±4095. The initial value is 0 +//| +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| ... +//| + + +STATIC mp_obj_t _vertextranslatey(mp_obj_t self, mp_obj_t a0) { + mp_float_t y = mp_obj_get_float(a0); + common_hal__eve_VertexTranslateY(EVEHAL(self), y); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey); + +//| def VertexFormat(self, frac: int) -> None: +//| """Set the precision of vertex2f coordinates +//| +//| :param int frac: Number of fractional bits in X,Y coordinates, 0-4. Range 0-7. The initial value is 4 +//| +//| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`.""" +//| ... +//| + +//} + // Append an object x to the FIFO #define ADD_X(self, x) \ common_hal__eve_add(EVEHAL(self), sizeof(x), &(x)); diff --git a/shared-bindings/_eve/__init__.h b/shared-bindings/_eve/__init__.h index 759a629bb..883b1a15b 100644 --- a/shared-bindings/_eve/__init__.h +++ b/shared-bindings/_eve/__init__.h @@ -61,11 +61,11 @@ void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t gre void common_hal__eve_Display(common_hal__eve_t *eve); void common_hal__eve_End(common_hal__eve_t *eve); void common_hal__eve_Jump(common_hal__eve_t *eve, uint32_t dest); -void common_hal__eve_LineWidth(common_hal__eve_t *eve, uint32_t width); +void common_hal__eve_LineWidth(common_hal__eve_t *eve, mp_float_t width); void common_hal__eve_Macro(common_hal__eve_t *eve, uint32_t m); void common_hal__eve_Nop(common_hal__eve_t *eve); void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr); -void common_hal__eve_PointSize(common_hal__eve_t *eve, uint32_t size); +void common_hal__eve_PointSize(common_hal__eve_t *eve, mp_float_t size); void common_hal__eve_RestoreContext(common_hal__eve_t *eve); void common_hal__eve_Return(common_hal__eve_t *eve); void common_hal__eve_SaveContext(common_hal__eve_t *eve); @@ -76,8 +76,8 @@ void common_hal__eve_StencilMask(common_hal__eve_t *eve, uint32_t mask); void common_hal__eve_StencilOp(common_hal__eve_t *eve, uint32_t sfail, uint32_t spass); void common_hal__eve_TagMask(common_hal__eve_t *eve, uint32_t mask); void common_hal__eve_Tag(common_hal__eve_t *eve, uint32_t s); -void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, uint32_t x); -void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, uint32_t y); +void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, mp_float_t x); +void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, mp_float_t y); void common_hal__eve_VertexFormat(common_hal__eve_t *eve, uint32_t frac); void common_hal__eve_Vertex2ii(common_hal__eve_t *eve, uint32_t x, uint32_t y, uint32_t handle, uint32_t cell); diff --git a/shared-module/_eve/__init__.c b/shared-module/_eve/__init__.c index d95c777dc..579729d42 100644 --- a/shared-module/_eve/__init__.c +++ b/shared-module/_eve/__init__.c @@ -226,8 +226,9 @@ void common_hal__eve_Jump(common_hal__eve_t *eve, uint32_t dest) { } -void common_hal__eve_LineWidth(common_hal__eve_t *eve, uint32_t width) { - C4(eve, ((14 << 24) | ((width & 4095)))); +void common_hal__eve_LineWidth(common_hal__eve_t *eve, mp_float_t width) { + int16_t iw = (int)(8 * width); + C4(eve, ((14 << 24) | ((iw & 4095)))); } @@ -246,8 +247,9 @@ void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr) { } -void common_hal__eve_PointSize(common_hal__eve_t *eve, uint32_t size) { - C4(eve, ((13 << 24) | ((size & 8191)))); +void common_hal__eve_PointSize(common_hal__eve_t *eve, mp_float_t size) { + int16_t is = (int)(8 * size); + C4(eve, ((13 << 24) | ((is & 8191)))); } @@ -301,13 +303,15 @@ void common_hal__eve_Tag(common_hal__eve_t *eve, uint32_t s) { } -void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, uint32_t x) { - C4(eve, ((43 << 24) | (((x) & 131071)))); +void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, mp_float_t x) { + int16_t ix = (int)(16 * x); + C4(eve, ((43 << 24) | (ix & 131071))); } -void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, uint32_t y) { - C4(eve, ((44 << 24) | (((y) & 131071)))); +void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, mp_float_t y) { + int16_t iy = (int)(16 * y); + C4(eve, ((44 << 24) | (iy & 131071))); } -- cgit v1.2.3 From 69869e1439a1ebad383b75b28e7e88f21ccab732 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Sun, 24 Jan 2021 22:49:28 -0500 Subject: CIRCUITPY_* switches for JSON, RE, etc. Doc cleanup --- docs/library/errno.rst | 32 ++++++ docs/library/index.rst | 51 +++------ docs/library/io.rst | 114 ++++++++++++++++++++ docs/library/json.rst | 35 +++++++ docs/library/re.rst | 101 ++++++++++++++++++ docs/library/uerrno.rst | 34 ------ docs/library/uio.rst | 116 --------------------- docs/library/ujson.rst | 37 ------- docs/library/ure.rst | 103 ------------------ docs/shared_bindings_matrix.py | 4 +- .../mpconfigboard.h | 3 +- ports/atmel-samd/mpconfigport.h | 7 -- ports/atmel-samd/mpconfigport.mk | 52 +++------ ports/esp32s2/mpconfigport.h | 1 - ports/litex/mpconfigport.h | 2 - ports/mimxrt10xx/mpconfigport.h | 2 - ports/nrf/mpconfigport.h | 3 - ports/raspberrypi/mpconfigport.h | 4 +- ports/stm/mpconfigport.h | 2 - py/circuitpy_mpconfig.h | 73 ++++++------- py/circuitpy_mpconfig.mk | 12 +++ shared-bindings/support_matrix.rst | 4 +- 22 files changed, 367 insertions(+), 425 deletions(-) create mode 100644 docs/library/errno.rst create mode 100644 docs/library/io.rst create mode 100644 docs/library/json.rst create mode 100644 docs/library/re.rst delete mode 100644 docs/library/uerrno.rst delete mode 100644 docs/library/uio.rst delete mode 100644 docs/library/ujson.rst delete mode 100644 docs/library/ure.rst (limited to 'shared-bindings') diff --git a/docs/library/errno.rst b/docs/library/errno.rst new file mode 100644 index 000000000..96777b205 --- /dev/null +++ b/docs/library/errno.rst @@ -0,0 +1,32 @@ +:mod:`errno` -- system error codes +=================================== + +.. module:: errno + :synopsis: system error codes + +|see_cpython_module| :mod:`cpython:errno`. + +This module provides access to symbolic error codes for `OSError` exception. + +Constants +--------- + +.. data:: EEXIST, EAGAIN, etc. + + Error codes, based on ANSI C/POSIX standard. All error codes start with + "E". Errors are usually accessible as ``exc.args[0]`` + where ``exc`` is an instance of `OSError`. Usage example:: + + try: + os.mkdir("my_dir") + except OSError as exc: + if exc.args[0] == errno.EEXIST: + print("Directory already exists") + +.. data:: errorcode + + Dictionary mapping numeric error codes to strings with symbolic error + code (see above):: + + >>> print(errno.errorcode[uerrno.EEXIST]) + EEXIST diff --git a/docs/library/index.rst b/docs/library/index.rst index e91387242..94bd8a656 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -7,34 +7,20 @@ Python standard libraries and micro-libraries --------------------------------------------- These libraries are inherited from MicroPython. -They are similar to the standard Python libraries with the same name -or with the "u" prefix dropped. +They are similar to the standard Python libraries with the same name. They implement a subset of or a variant of the corresponding standard Python library. -.. warning:: - - Though these MicroPython-based libraries are available in CircuitPython, - their functionality may change in the future, perhaps significantly. - As CircuitPython continues to develop, new versions of these libraries will - be created that are more compliant with the standard Python libraries. - You may need to change your code later if you rely - on any non-standard functionality they currently provide. - CircuitPython's long-term goal is that code written in CircuitPython using Python standard libraries will be runnable on CPython without changes. -Some libraries below are not enabled on CircuitPython builds with +These libraries are not enabled on CircuitPython builds with limited flash memory, usually on non-Express builds: -``uerrno``, ``ure``. - -Some libraries are not currently enabled in any CircuitPython build, but may be in the future: -``uio``, ``ujson``, ``uzlib``. +``binascii``, ``errno``, ``json``, ``re``. -Some libraries are only enabled only WiFi-capable ports (ESP8266, nRF) -because they are typically used for network software: -``binascii``, ``hashlib``, ``uheapq``, ``uselect``, ``ussl``. -Not all of these are enabled on all WiFi-capable ports. +These libraries are not currently enabled in any CircuitPython build, but may be in the future, +with the ``u`` prefix dropped: +``uctypes`, ``uhashlib``, ``uio``, ``uzlib``. .. toctree:: :maxdepth: 1 @@ -44,13 +30,14 @@ Not all of these are enabled on all WiFi-capable ports. array.rst binascii.rst collections.rst + errno.rst gc.rst hashlib.rst + io.rst + json.rst + re.rst sys.rst - uerrno.rst - uio.rst - ujson.rst - ure.rst + uctypes.rst uselect.rst usocket.rst ussl.rst @@ -59,8 +46,8 @@ Not all of these are enabled on all WiFi-capable ports. Omitted functions in the ``string`` library ------------------------------------------- -A few string operations are not enabled on CircuitPython -M0 non-Express builds, due to limited flash memory: +A few string operations are not enabled on small builds +(usually non-Express), due to limited flash memory: ``string.center()``, ``string.partition()``, ``string.splitlines()``, ``string.reversed()``. @@ -78,15 +65,3 @@ versions of CircuitPython. btree.rst framebuf.rst micropython.rst - network.rst - uctypes.rst - -Libraries specific to the ESP8266 ---------------------------------- - -The following libraries are specific to the ESP8266. - -.. toctree:: - :maxdepth: 2 - - esp.rst diff --git a/docs/library/io.rst b/docs/library/io.rst new file mode 100644 index 000000000..37e3eb7c9 --- /dev/null +++ b/docs/library/io.rst @@ -0,0 +1,114 @@ +:mod:`io` -- input/output streams +================================== + +.. module:: io + :synopsis: input/output streams + +|see_cpython_module| :mod:`cpython:io`. + +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 +--------- + +.. function:: open(name, mode='r', **kwargs) + + Open a file. Builtin ``open()`` function is aliased to this function. + All ports (which provide access to file system) are required to support + ``mode`` parameter, but support for other arguments vary by port. + +Classes +------- + +.. class:: FileIO(...) + + This is type of a file open in binary mode, e.g. using ``open(name, "rb")``. + You should not instantiate this class directly. + +.. class:: TextIOWrapper(...) + + This is type of a file open in text mode, e.g. using ``open(name, "rt")``. + You should not instantiate this class directly. + +.. class:: StringIO([string]) +.. class:: BytesIO([string]) + + In-memory file-like objects for input/output. `StringIO` is used for + text-mode I/O (similar to a normal file opened with "t" modifier). + `BytesIO` is used for binary-mode I/O (similar to a normal file + opened with "b" modifier). Initial contents of file-like objects + can be specified with `string` parameter (should be normal string + for `StringIO` or bytes object for `BytesIO`). All the usual file + methods like ``read()``, ``write()``, ``seek()``, ``flush()``, + ``close()`` are available on these objects, and additionally, a + following method: + + .. method:: getvalue() + + Get the current contents of the underlying buffer which holds data. diff --git a/docs/library/json.rst b/docs/library/json.rst new file mode 100644 index 000000000..21574e556 --- /dev/null +++ b/docs/library/json.rst @@ -0,0 +1,35 @@ +:mod:`json` -- JSON encoding and decoding +========================================== + +.. module:: json + :synopsis: JSON encoding and decoding + +|see_cpython_module| :mod:`cpython:json`. + +This modules allows to convert between Python objects and the JSON +data format. + +Functions +--------- + +.. function:: dump(obj, stream) + + Serialise ``obj`` to a JSON string, writing it to the given *stream*. + +.. function:: dumps(obj) + + Return ``obj`` represented as a JSON string. + +.. function:: load(stream) + + Parse the given ``stream``, interpreting it as a JSON string and + deserialising the data to a Python object. The resulting object is + returned. + + Parsing continues until end-of-file is encountered. + A :exc:`ValueError` is raised if the data in ``stream`` is not correctly formed. + +.. function:: loads(str) + + Parse the JSON *str* and return an object. Raises :exc:`ValueError` if the + string is not correctly formed. diff --git a/docs/library/re.rst b/docs/library/re.rst new file mode 100644 index 000000000..bdcc9f52c --- /dev/null +++ b/docs/library/re.rst @@ -0,0 +1,101 @@ +:mod:`re` -- simple regular expressions +======================================== + +.. module:: re + :synopsis: regular expressions + +|see_cpython_module| :mod:`cpython:re`. + +This module implements regular expression operations. Regular expression +syntax supported is a subset of CPython ``re`` module (and actually is +a subset of POSIX extended regular expressions). + +Supported operators are: + +``'.'`` + Match any character. + +``'[...]'`` + Match set of characters. Individual characters and ranges are supported, + including negated sets (e.g. ``[^a-c]``). + +``'^'`` + +``'$'`` + +``'?'`` + +``'*'`` + +``'+'`` + +``'??'`` + +``'*?'`` + +``'+?'`` + +``'|'`` + +``'(...)'`` + Grouping. Each group is capturing (a substring it captures can be accessed + with `match.group()` method). + +**NOT SUPPORTED**: Counted repetitions (``{m,n}``), more advanced assertions +(``\b``, ``\B``), named groups (``(?P...)``), non-capturing groups +(``(?:...)``), etc. + + +Functions +--------- + +.. function:: compile(regex_str, [flags]) + + Compile regular expression, return `regex ` object. + +.. function:: match(regex_str, string) + + Compile *regex_str* and match against *string*. Match always happens + from starting position in a string. + +.. function:: search(regex_str, string) + + Compile *regex_str* and search it in a *string*. Unlike `match`, this will search + string for first position which matches regex (which still may be + 0 if regex is anchored). + +.. data:: DEBUG + + Flag value, display debug information about compiled expression. + + +.. _regex: + +Regex objects +------------- + +Compiled regular expression. Instances of this class are created using +`re.compile()`. + +.. method:: regex.match(string) + regex.search(string) + + Similar to the module-level functions :meth:`match` and :meth:`search`. + Using methods is (much) more efficient if the same regex is applied to + multiple strings. + +.. method:: regex.split(string, max_split=-1) + + Split a *string* using regex. If *max_split* is given, it specifies + maximum number of splits to perform. Returns list of strings (there + may be up to *max_split+1* elements if it's specified). + +Match objects +------------- + +Match objects as returned by `match()` and `search()` methods. + +.. method:: match.group([index]) + + Return matching (sub)string. *index* is 0 for entire match, + 1 and above for each capturing group. Only numeric groups are supported. diff --git a/docs/library/uerrno.rst b/docs/library/uerrno.rst deleted file mode 100644 index 72f71f0aa..000000000 --- a/docs/library/uerrno.rst +++ /dev/null @@ -1,34 +0,0 @@ -:mod:`uerrno` -- system error codes -=================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc - -.. module:: uerrno - :synopsis: system error codes - -|see_cpython_module| :mod:`cpython:errno`. - -This module provides access to symbolic error codes for `OSError` exception. - -Constants ---------- - -.. data:: EEXIST, EAGAIN, etc. - - Error codes, based on ANSI C/POSIX standard. All error codes start with - "E". Errors are usually accessible as ``exc.args[0]`` - where ``exc`` is an instance of `OSError`. Usage example:: - - try: - os.mkdir("my_dir") - except OSError as exc: - if exc.args[0] == uerrno.EEXIST: - print("Directory already exists") - -.. data:: errorcode - - Dictionary mapping numeric error codes to strings with symbolic error - code (see above):: - - >>> print(uerrno.errorcode[uerrno.EEXIST]) - EEXIST diff --git a/docs/library/uio.rst b/docs/library/uio.rst deleted file mode 100644 index d1f7c111f..000000000 --- a/docs/library/uio.rst +++ /dev/null @@ -1,116 +0,0 @@ -:mod:`uio` -- input/output streams -================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc - -.. module:: uio - :synopsis: input/output streams - -|see_cpython_module| :mod:`cpython:io`. - -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 ---------- - -.. function:: open(name, mode='r', **kwargs) - - Open a file. Builtin ``open()`` function is aliased to this function. - All ports (which provide access to file system) are required to support - ``mode`` parameter, but support for other arguments vary by port. - -Classes -------- - -.. class:: FileIO(...) - - This is type of a file open in binary mode, e.g. using ``open(name, "rb")``. - You should not instantiate this class directly. - -.. class:: TextIOWrapper(...) - - This is type of a file open in text mode, e.g. using ``open(name, "rt")``. - You should not instantiate this class directly. - -.. class:: StringIO([string]) -.. class:: BytesIO([string]) - - In-memory file-like objects for input/output. `StringIO` is used for - text-mode I/O (similar to a normal file opened with "t" modifier). - `BytesIO` is used for binary-mode I/O (similar to a normal file - opened with "b" modifier). Initial contents of file-like objects - can be specified with `string` parameter (should be normal string - for `StringIO` or bytes object for `BytesIO`). All the usual file - methods like ``read()``, ``write()``, ``seek()``, ``flush()``, - ``close()`` are available on these objects, and additionally, a - following method: - - .. method:: getvalue() - - Get the current contents of the underlying buffer which holds data. diff --git a/docs/library/ujson.rst b/docs/library/ujson.rst deleted file mode 100644 index 4ed91f053..000000000 --- a/docs/library/ujson.rst +++ /dev/null @@ -1,37 +0,0 @@ -:mod:`ujson` -- JSON encoding and decoding -========================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc - -.. module:: ujson - :synopsis: JSON encoding and decoding - -|see_cpython_module| :mod:`cpython:json`. - -This modules allows to convert between Python objects and the JSON -data format. - -Functions ---------- - -.. function:: dump(obj, stream) - - Serialise ``obj`` to a JSON string, writing it to the given *stream*. - -.. function:: dumps(obj) - - Return ``obj`` represented as a JSON string. - -.. function:: load(stream) - - Parse the given ``stream``, interpreting it as a JSON string and - deserialising the data to a Python object. The resulting object is - returned. - - Parsing continues until end-of-file is encountered. - A :exc:`ValueError` is raised if the data in ``stream`` is not correctly formed. - -.. function:: loads(str) - - Parse the JSON *str* and return an object. Raises :exc:`ValueError` if the - string is not correctly formed. diff --git a/docs/library/ure.rst b/docs/library/ure.rst deleted file mode 100644 index 4af182b01..000000000 --- a/docs/library/ure.rst +++ /dev/null @@ -1,103 +0,0 @@ -:mod:`ure` -- simple regular expressions -======================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc - -.. module:: ure - :synopsis: regular expressions - -|see_cpython_module| :mod:`cpython:re`. - -This module implements regular expression operations. Regular expression -syntax supported is a subset of CPython ``re`` module (and actually is -a subset of POSIX extended regular expressions). - -Supported operators are: - -``'.'`` - Match any character. - -``'[...]'`` - Match set of characters. Individual characters and ranges are supported, - including negated sets (e.g. ``[^a-c]``). - -``'^'`` - -``'$'`` - -``'?'`` - -``'*'`` - -``'+'`` - -``'??'`` - -``'*?'`` - -``'+?'`` - -``'|'`` - -``'(...)'`` - Grouping. Each group is capturing (a substring it captures can be accessed - with `match.group()` method). - -**NOT SUPPORTED**: Counted repetitions (``{m,n}``), more advanced assertions -(``\b``, ``\B``), named groups (``(?P...)``), non-capturing groups -(``(?:...)``), etc. - - -Functions ---------- - -.. function:: compile(regex_str, [flags]) - - Compile regular expression, return `regex ` object. - -.. function:: match(regex_str, string) - - Compile *regex_str* and match against *string*. Match always happens - from starting position in a string. - -.. function:: search(regex_str, string) - - Compile *regex_str* and search it in a *string*. Unlike `match`, this will search - string for first position which matches regex (which still may be - 0 if regex is anchored). - -.. data:: DEBUG - - Flag value, display debug information about compiled expression. - - -.. _regex: - -Regex objects -------------- - -Compiled regular expression. Instances of this class are created using -`ure.compile()`. - -.. method:: regex.match(string) - regex.search(string) - - Similar to the module-level functions :meth:`match` and :meth:`search`. - Using methods is (much) more efficient if the same regex is applied to - multiple strings. - -.. method:: regex.split(string, max_split=-1) - - Split a *string* using regex. If *max_split* is given, it specifies - maximum number of splits to perform. Returns list of strings (there - may be up to *max_split+1* elements if it's specified). - -Match objects -------------- - -Match objects as returned by `match()` and `search()` methods. - -.. method:: match.group([index]) - - Return matching (sub)string. *index* is 0 for entire match, - 1 and above for each capturing group. Only numeric groups are supported. diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py index f38c0b64a..ca6ddd3ed 100644 --- a/docs/shared_bindings_matrix.py +++ b/docs/shared_bindings_matrix.py @@ -30,7 +30,7 @@ import sys from concurrent.futures import ThreadPoolExecutor -SUPPORTED_PORTS = ['atmel-samd', 'esp32s2', 'litex', 'mimxrt10xx', 'nrf', 'stm'] +SUPPORTED_PORTS = ['atmel-samd', 'esp32s2', 'litex', 'mimxrt10xx', 'nrf', 'raspberrypi', 'stm'] def get_circuitpython_root_dir(): """ The path to the root './circuitpython' directory @@ -44,7 +44,7 @@ def get_shared_bindings(): """ Get a list of modules in shared-bindings based on folder names """ shared_bindings_dir = get_circuitpython_root_dir() / "shared-bindings" - return [item.name for item in shared_bindings_dir.iterdir()] + ["ulab"] + return [item.name for item in shared_bindings_dir.iterdir()] + ["binascii", "errno", "json", "re", "ulab"] def read_mpconfig(): diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index 4b0c324fa..fc189e662 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -44,4 +44,5 @@ #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 -#define MICROPY_PY_URE 0 +// Can't fit. +#define CIRCUITPY_RE 0 diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index bce89e0b9..d2a529485 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -45,11 +45,7 @@ #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_PY_FUNCTION_ATTRS (0) -// MICROPY_PY_UJSON depends on MICROPY_PY_IO -#define MICROPY_PY_IO (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (0) -#define MICROPY_PY_UBINASCII (0) -#define MICROPY_PY_UJSON (0) #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (0) #define MICROPY_PY_UERRNO_LIST \ X(EPERM) \ @@ -84,9 +80,6 @@ #define SPI_FLASH_MAX_BAUDRATE 24000000 #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) #define MICROPY_PY_FUNCTION_ATTRS (1) -// MICROPY_PY_UJSON depends on MICROPY_PY_IO -#define MICROPY_PY_IO (1) -#define MICROPY_PY_UJSON (1) // MICROPY_PY_UERRNO_LIST - Use the default #endif // SAM_D5X_E5X diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 17e3995bf..fb9cdf2e6 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -20,26 +20,16 @@ endif # Put samd21-only choices here. ifeq ($(CHIP_FAMILY),samd21) -# frequencyio not yet verified as working on SAMD21, though make it possible to override. -ifndef CIRCUITPY_AUDIOMIXER -CIRCUITPY_AUDIOMIXER = 0 -endif - -ifndef CIRCUITPY_AUDIOMP3 -CIRCUITPY_AUDIOMP3 = 0 -endif - -ifndef CIRCUITPY_BUILTINS_POW3 -CIRCUITPY_BUILTINS_POW3 = 0 -endif -ifndef CIRCUITPY_FREQUENCYIO -CIRCUITPY_FREQUENCYIO = 0 -endif +# The ?='s allow overriding in mpconfigboard.mk. -ifndef CIRCUITPY_TOUCHIO_USE_NATIVE -CIRCUITPY_TOUCHIO_USE_NATIVE = 1 -endif +CIRCUITPY_AUDIOMIXER ?= 0 +CIRCUITPY_BINASCII ?= 0 +CIRCUITPY_AUDIOMP3 ?= 0 +CIRCUITPY_BUILTINS_POW3 ?= 0 +CIRCUITPY_FREQUENCYIO ?= 0 +CIRCUITPY_JSON ?= 0 +CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 # No room for HCI _bleio on SAMD21. CIRCUITPY_BLEIO_HCI = 0 @@ -71,27 +61,13 @@ ifeq ($(CHIP_FAMILY),samd51) # No native touchio on SAMD51. CIRCUITPY_TOUCHIO_USE_NATIVE = 0 -# The ifndef's allow overriding in mpconfigboard.mk. - -ifndef CIRCUITPY_NETWORK -CIRCUITPY_NETWORK = 0 -endif - -ifndef CIRCUITPY_PS2IO -CIRCUITPY_PS2IO = 1 -endif - -ifndef CIRCUITPY_SAMD -CIRCUITPY_SAMD = 1 -endif - -ifndef CIRCUITPY_RGBMATRIX -CIRCUITPY_RGBMATRIX = $(CIRCUITPY_FULL_BUILD) -endif +# The ?='s allow overriding in mpconfigboard.mk. -ifndef CIRCUITPY_FRAMEBUFFERIO -CIRCUITPY_FRAMEBUFFERIO = $(CIRCUITPY_FULL_BUILD) -endif +CIRCUITPY_NETWORK ?= 0 +CIRCUITPY_PS2IO ?= 1 +CIRCUITPY_SAMD ?= 1 +CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FULL_BUILD) +CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) endif # samd51 diff --git a/ports/esp32s2/mpconfigport.h b/ports/esp32s2/mpconfigport.h index 9c0fd9da3..0cf695bc9 100644 --- a/ports/esp32s2/mpconfigport.h +++ b/ports/esp32s2/mpconfigport.h @@ -30,7 +30,6 @@ #define MICROPY_NLR_THUMB (0) -#define MICROPY_PY_UJSON (1) #define MICROPY_USE_INTERNAL_PRINTF (0) #define MICROPY_PY_SYS_PLATFORM "Espressif ESP32-S2" diff --git a/ports/litex/mpconfigport.h b/ports/litex/mpconfigport.h index a7caf8526..5f739e49e 100644 --- a/ports/litex/mpconfigport.h +++ b/ports/litex/mpconfigport.h @@ -31,8 +31,6 @@ #define CIRCUITPY_INTERNAL_NVM_SIZE (0) #define MICROPY_NLR_THUMB (0) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UJSON (1) #include "py/circuitpy_mpconfig.h" diff --git a/ports/mimxrt10xx/mpconfigport.h b/ports/mimxrt10xx/mpconfigport.h index 7496256d0..51e0ef9ff 100644 --- a/ports/mimxrt10xx/mpconfigport.h +++ b/ports/mimxrt10xx/mpconfigport.h @@ -41,8 +41,6 @@ extern uint8_t _ld_default_stack_size; #define CIRCUITPY_DEFAULT_STACK_SIZE ((uint32_t) &_ld_default_stack_size) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_PY_FUNCTION_ATTRS (0) -#define MICROPY_PY_IO (1) -#define MICROPY_PY_UJSON (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 4ed42cd82..3ac41a5e4 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -35,11 +35,8 @@ #include "peripherals/nrf/nvm.h" // for FLASH_PAGE_SIZE #define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_IO (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_SYS_STDIO_BUFFER (1) -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UJSON (1) // 24kiB stack #define CIRCUITPY_DEFAULT_STACK_SIZE (24*1024) diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index 3fdc8febb..75cbd1ba8 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -27,7 +27,9 @@ #ifndef __INCLUDED_MPCONFIGPORT_H #define __INCLUDED_MPCONFIGPORT_H -#define MICROPY_PY_UJSON (1) +#define CIRCUITPY_BINASCII (1) +#define CIRCUITPY_ERRNO (1) +#define CIRCUITPY_JSON (1) #define CIRCUITPY_INTERNAL_NVM_SIZE 0 diff --git a/ports/stm/mpconfigport.h b/ports/stm/mpconfigport.h index 9489b4765..7cdab04f6 100644 --- a/ports/stm/mpconfigport.h +++ b/ports/stm/mpconfigport.h @@ -31,9 +31,7 @@ #include #define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_IO (1) #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_UJSON (1) extern uint8_t _ld_default_stack_size; diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 35f1227a9..c193e61c4 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -195,21 +195,14 @@ typedef long mp_off_t; #define MICROPY_PY_BUILTINS_STR_CENTER (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_STR_PARTITION (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_STR_SPLITLINES (CIRCUITPY_FULL_BUILD) -#define MICROPY_PY_UERRNO (CIRCUITPY_FULL_BUILD) #ifndef MICROPY_PY_COLLECTIONS_ORDEREDDICT #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (CIRCUITPY_FULL_BUILD) #endif -#ifndef MICROPY_PY_UBINASCII -#define MICROPY_PY_UBINASCII (CIRCUITPY_FULL_BUILD) -#endif // Opposite setting is deliberate. -#define MICROPY_PY_UERRNO_ERRORCODE (!CIRCUITPY_FULL_BUILD) -#ifndef MICROPY_PY_URE -#define MICROPY_PY_URE (CIRCUITPY_FULL_BUILD) -#endif -#define MICROPY_PY_URE_MATCH_GROUPS (CIRCUITPY_FULL_BUILD) -#define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_FULL_BUILD) -#define MICROPY_PY_URE_SUB (CIRCUITPY_FULL_BUILD) +#define MICROPY_PY_UERRNO_ERRORCODE (!CIRCUITPY_RE) +#define MICROPY_PY_URE_MATCH_GROUPS (CIRCUITPY_RE) +#define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_RE) +#define MICROPY_PY_URE_SUB (CIRCUITPY_RE) // LONGINT_IMPL_xxx are defined in the Makefile. // @@ -301,6 +294,13 @@ extern const struct _mp_obj_module_t audiopwmio_module; #define AUDIOPWMIO_MODULE #endif +#if CIRCUITPY_BINASCII +#define MICROPY_PY_UBINASCII CIRCUITPY_BINASCII +#define BINASCII_MODULE { MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) }, +#else +#define BINASCII_MODULE +#endif + #if CIRCUITPY_BITBANGIO #define BITBANGIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, extern const struct _mp_obj_module_t bitbangio_module; @@ -399,6 +399,13 @@ extern const struct _mp_obj_module_t terminalio_module; #define TERMINALIO_MODULE #endif +#if CIRCUITPY_ERRNO +#define MICROPY_PY_UERRNO (1) +#define ERRNO_MODULE { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, +#else +#define ERRNO_MODULE +#endif + #if CIRCUITPY_ESPIDF extern const struct _mp_obj_module_t espidf_module; #define ESPIDF_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_espidf),(mp_obj_t)&espidf_module }, @@ -470,6 +477,18 @@ extern const struct _mp_obj_module_t ipaddress_module; #define IPADDRESS_MODULE #endif +#if CIRCUITPY_JSON +#define MICROPY_PY_UJSON (1) +#define MICROPY_PY_IO (1) +#define JSON_MODULE { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) }, +#else +#ifndef MICROPY_PY_IO +// We don't need MICROPY_PY_IO unless someone else wants it. +#define MICROPY_PY_IO (0) +#endif +#define JSON_MODULE +#endif + #if CIRCUITPY_MATH extern const struct _mp_obj_module_t math_module; #define MATH_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, @@ -588,6 +607,13 @@ extern const struct _mp_obj_module_t random_module; #define RANDOM_MODULE #endif +#if CIRCUITPY_RE +#define MICROPY_PY_URE (1) +#define RE_MODULE { MP_ROM_QSTR(MP_QSTR_re), MP_ROM_PTR(&mp_module_ure) }, +#else +#define RE_MODULE +#endif + #if CIRCUITPY_RGBMATRIX extern const struct _mp_obj_module_t rgbmatrix_module; #define RGBMATRIX_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_rgbmatrix),(mp_obj_t)&rgbmatrix_module }, @@ -730,25 +756,6 @@ extern const struct _mp_obj_module_t ustack_module; #define USTACK_MODULE #endif -// These modules are not yet in shared-bindings, but we prefer the non-uxxx names. -#if MICROPY_PY_UBINASCII -#define BINASCII_MODULE { MP_ROM_QSTR(MP_QSTR_binascii), MP_ROM_PTR(&mp_module_ubinascii) }, -#else -#define BINASCII_MODULE -#endif - -#if MICROPY_PY_UERRNO -#define ERRNO_MODULE { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, -#else -#define ERRNO_MODULE -#endif - -#if MICROPY_PY_UJSON -#define JSON_MODULE { MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) }, -#else -#define JSON_MODULE -#endif - #if defined(CIRCUITPY_ULAB) && CIRCUITPY_ULAB // ulab requires reverse special methods #if defined(MICROPY_PY_REVERSE_SPECIAL_METHODS) && !MICROPY_PY_REVERSE_SPECIAL_METHODS @@ -760,12 +767,6 @@ extern const struct _mp_obj_module_t ustack_module; #define ULAB_MODULE #endif -#if MICROPY_PY_URE -#define RE_MODULE { MP_ROM_QSTR(MP_QSTR_re), MP_ROM_PTR(&mp_module_ure) }, -#else -#define RE_MODULE -#endif - // This is not a top-level module; it's microcontroller.watchdog. #if CIRCUITPY_WATCHDOG extern const struct _mp_obj_module_t watchdog_module; diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 9c9b17f4b..141ad05f8 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -86,6 +86,9 @@ endif endif CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3) +CIRCUITPY_BINASCII ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_BINASCII=$(CIRCUITPY_BINASCII) + CIRCUITPY_BITBANGIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO) @@ -124,6 +127,9 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) +CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO) + # CIRCUITPY_ESPIDF is handled in the esp32s2 tree. # Only for ESP32S chips. # Assume not a ESP build. @@ -158,6 +164,9 @@ CFLAGS += -DCIRCUITPY_I2CPERIPHERAL=$(CIRCUITPY_I2CPERIPHERAL) CIRCUITPY_IPADDRESS ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_IPADDRESS=$(CIRCUITPY_IPADDRESS) +CIRCUITPY_JSON ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_JSON=$(CIRCUITPY_JSON) + CIRCUITPY_MATH ?= 1 CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) @@ -204,6 +213,9 @@ CFLAGS += -DCIRCUITPY_PWMIO=$(CIRCUITPY_PWMIO) CIRCUITPY_RANDOM ?= 1 CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM) +CIRCUITPY_RE ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_RE=$(CIRCUITPY_RE) + # CIRCUITPY_RP2PIO is handled in the raspberrypi tree. # Only for rp2 chips. # Assume not a rp2 build. diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst index 1b75e0256..a2fb7987d 100644 --- a/shared-bindings/support_matrix.rst +++ b/shared-bindings/support_matrix.rst @@ -1,7 +1,7 @@ .. _module-support-matrix: -Support Matrix -=============== +Module Support Matrix - Which Modules Are Available on Which Boards +=================================================================== The following table lists the available built-in modules for each CircuitPython capable board. -- cgit v1.2.3 From 51f054440516d21bd2e8d07a3e6f1f8e3acfbd55 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 26 Jan 2021 09:19:44 -0600 Subject: protmatter: Update to version that supports tiling --- lib/protomatter | 2 +- shared-bindings/rgbmatrix/RGBMatrix.c | 27 ++++++++++++++++++--------- shared-bindings/rgbmatrix/RGBMatrix.h | 2 +- shared-module/rgbmatrix/RGBMatrix.c | 5 +++-- shared-module/rgbmatrix/RGBMatrix.h | 1 + 5 files changed, 24 insertions(+), 13 deletions(-) (limited to 'shared-bindings') diff --git a/lib/protomatter b/lib/protomatter index 902c16f49..5e925cea7 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit 902c16f49197a8baf5e71ec924a812a86e733a74 +Subproject commit 5e925cea7a55273e375a6129761cb29b4e750d4f diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index 5f5ea4fae..ad693066c 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -24,6 +24,8 @@ * THE SOFTWARE. */ +#include + #include "py/obj.h" #include "py/objproperty.h" #include "py/runtime.h" @@ -132,11 +134,11 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ } } -//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0) -> None: +//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0, tile: int = 1, serpentine: bool = False) -> None: //| """Create a RGBMatrix object with the given attributes. The height of -//| the display is determined by the number of rgb and address pins: -//| len(rgb_pins) // 3 * 2 ** len(address_pins). With 6 RGB pins and 4 -//| address lines, the display will be 32 pixels tall. If the optional height +//| the display is determined by the number of rgb and address pins and the number of tiles: +//| ``len(rgb_pins) // 3 * 2 ** len(address_pins) * abs(tile)``. With 6 RGB pins, 4 +//| address lines, and a single matrix, the display will be 32 pixels tall. If the optional height //| parameter is specified and is not 0, it is checked against the calculated //| height. //| @@ -172,7 +174,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list, - ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height }; + ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer, ARG_height, ARG_tile, ARG_serpentine }; static const mp_arg_t allowed_args[] = { { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, { MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED | MP_ARG_KW_ONLY }, @@ -184,6 +186,8 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n { MP_QSTR_doublebuffer, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = true } }, { MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } }, { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, + { MP_QSTR_tile, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 1 } }, + { MP_QSTR_serpentine, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -210,15 +214,20 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n mp_raise_ValueError_varg(translate("Must use a multiple of 6 rgb pins, not %d"), rgb_count); } - // TODO(@jepler) Use fewer than all rows of pixels if height < computed_height + int tile = args[ARG_tile].u_int; + if (args[ARG_height].u_int != 0) { - int computed_height = (rgb_count / 3) << (addr_count); + int computed_height = (rgb_count / 3) << (addr_count) * abs(tile); if (computed_height != args[ARG_height].u_int) { mp_raise_ValueError_varg( - translate("%d address pins and %d rgb pins indicate a height of %d, not %d"), addr_count, rgb_count, computed_height, args[ARG_height].u_int); + translate("%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"), addr_count, rgb_count, tile, computed_height, args[ARG_height].u_int); } } + if (args[ARG_serpentine].u_bool) { + tile = -tile; + } + if (args[ARG_width].u_int <= 0) { mp_raise_ValueError(translate("width must be greater than zero")); } @@ -239,7 +248,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n addr_count, addr_pins, clock_pin, latch_pin, output_enable_pin, args[ARG_doublebuffer].u_bool, - framebuffer, NULL); + framebuffer, tile, NULL); claim_and_never_reset_pins(args[ARG_rgb_list].u_obj); claim_and_never_reset_pins(args[ARG_addr_list].u_obj); diff --git a/shared-bindings/rgbmatrix/RGBMatrix.h b/shared-bindings/rgbmatrix/RGBMatrix.h index bfe37c340..3e8a4db5f 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.h +++ b/shared-bindings/rgbmatrix/RGBMatrix.h @@ -31,7 +31,7 @@ extern const mp_obj_type_t rgbmatrix_RGBMatrix_type; -void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void* timer); +void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, void* timer); void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t*); void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t*); void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, mp_obj_t framebuffer); diff --git a/shared-module/rgbmatrix/RGBMatrix.c b/shared-module/rgbmatrix/RGBMatrix.c index a09767b62..95a7eda75 100644 --- a/shared-module/rgbmatrix/RGBMatrix.c +++ b/shared-module/rgbmatrix/RGBMatrix.c @@ -42,7 +42,7 @@ extern Protomatter_core *_PM_protoPtr; -void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, void *timer) { +void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, void *timer) { self->width = width; self->bit_depth = bit_depth; self->rgb_count = rgb_count; @@ -53,6 +53,7 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i self->oe_pin = oe_pin; self->latch_pin = latch_pin; self->doublebuffer = doublebuffer; + self->tile = tile; self->timer = timer ? timer : common_hal_rgbmatrix_timer_allocate(); if (self->timer == NULL) { @@ -95,7 +96,7 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, self->rgb_count/6, self->rgb_pins, self->addr_count, self->addr_pins, self->clock_pin, self->latch_pin, self->oe_pin, - self->doublebuffer, self->timer); + self->doublebuffer, self->tile, self->timer); if (stat == PROTOMATTER_OK) { _PM_protoPtr = &self->protomatter; diff --git a/shared-module/rgbmatrix/RGBMatrix.h b/shared-module/rgbmatrix/RGBMatrix.h index 6dbc6fd41..7fce73c8b 100644 --- a/shared-module/rgbmatrix/RGBMatrix.h +++ b/shared-module/rgbmatrix/RGBMatrix.h @@ -44,4 +44,5 @@ typedef struct { bool core_is_initialized; bool paused; bool doublebuffer; + int8_t tile; } rgbmatrix_rgbmatrix_obj_t; -- cgit v1.2.3 From 368977fb906e6561bd67977a47dc0b415547cc33 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 26 Jan 2021 14:33:48 -0600 Subject: RGBMatrix: Additional tile tweaks * Introduce explicit serpentine: bool argument instead of using negative numbers (thanks, ghost of @tannewt sitting on one shoulder) * Fix several calculations of height Testing performed (matrixportal): * set up a serpentine 64x64 virtual display with 2 64x32 tiles * tried all 4 rotations * looked at output of REPL --- shared-bindings/rgbmatrix/RGBMatrix.c | 17 ++++++++--------- shared-bindings/rgbmatrix/RGBMatrix.h | 2 +- shared-module/rgbmatrix/RGBMatrix.c | 10 ++++++---- shared-module/rgbmatrix/RGBMatrix.h | 1 + 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index ad693066c..7218b2a9e 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -24,8 +24,6 @@ * THE SOFTWARE. */ -#include - #include "py/obj.h" #include "py/objproperty.h" #include "py/runtime.h" @@ -216,18 +214,19 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n int tile = args[ARG_tile].u_int; + if (tile < 0) { + mp_raise_ValueError_varg( + translate("tile must be greater than or equal to zero")); + } + if (args[ARG_height].u_int != 0) { - int computed_height = (rgb_count / 3) << (addr_count) * abs(tile); + int computed_height = (rgb_count / 3) * (1 << (addr_count)) * tile; if (computed_height != args[ARG_height].u_int) { mp_raise_ValueError_varg( translate("%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"), addr_count, rgb_count, tile, computed_height, args[ARG_height].u_int); } } - if (args[ARG_serpentine].u_bool) { - tile = -tile; - } - if (args[ARG_width].u_int <= 0) { mp_raise_ValueError(translate("width must be greater than zero")); } @@ -237,7 +236,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; if (framebuffer == mp_const_none) { int width = args[ARG_width].u_int; - int bufsize = 2 * width * rgb_count / 3 * (1 << addr_count); + int bufsize = 2 * width * rgb_count / 3 * (1 << addr_count) * tile; framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); } @@ -248,7 +247,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n addr_count, addr_pins, clock_pin, latch_pin, output_enable_pin, args[ARG_doublebuffer].u_bool, - framebuffer, tile, NULL); + framebuffer, tile, args[ARG_serpentine].u_bool, NULL); claim_and_never_reset_pins(args[ARG_rgb_list].u_obj); claim_and_never_reset_pins(args[ARG_addr_list].u_obj); diff --git a/shared-bindings/rgbmatrix/RGBMatrix.h b/shared-bindings/rgbmatrix/RGBMatrix.h index 3e8a4db5f..4eb3c04b2 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.h +++ b/shared-bindings/rgbmatrix/RGBMatrix.h @@ -31,7 +31,7 @@ extern const mp_obj_type_t rgbmatrix_RGBMatrix_type; -void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, void* timer); +void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t* self, int width, int bit_depth, uint8_t rgb_count, uint8_t* rgb_pins, uint8_t addr_count, uint8_t* addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void* timer); void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t*); void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t*); void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, mp_obj_t framebuffer); diff --git a/shared-module/rgbmatrix/RGBMatrix.c b/shared-module/rgbmatrix/RGBMatrix.c index 95a7eda75..4318604c6 100644 --- a/shared-module/rgbmatrix/RGBMatrix.c +++ b/shared-module/rgbmatrix/RGBMatrix.c @@ -42,7 +42,7 @@ extern Protomatter_core *_PM_protoPtr; -void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, void *timer) { +void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void *timer) { self->width = width; self->bit_depth = bit_depth; self->rgb_count = rgb_count; @@ -54,6 +54,7 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i self->latch_pin = latch_pin; self->doublebuffer = doublebuffer; self->tile = tile; + self->serpentine = serpentine; self->timer = timer ? timer : common_hal_rgbmatrix_timer_allocate(); if (self->timer == NULL) { @@ -61,7 +62,7 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i } self->width = width; - self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count); + self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count) * tile; common_hal_rgbmatrix_rgbmatrix_reconstruct(self, framebuffer); } @@ -96,7 +97,8 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t* self, self->rgb_count/6, self->rgb_pins, self->addr_count, self->addr_pins, self->clock_pin, self->latch_pin, self->oe_pin, - self->doublebuffer, self->tile, self->timer); + self->doublebuffer, self->serpentine ? -self->tile : self->tile, + self->timer); if (stat == PROTOMATTER_OK) { _PM_protoPtr = &self->protomatter; @@ -210,7 +212,7 @@ int common_hal_rgbmatrix_rgbmatrix_get_width(rgbmatrix_rgbmatrix_obj_t* self) { } int common_hal_rgbmatrix_rgbmatrix_get_height(rgbmatrix_rgbmatrix_obj_t* self) { - int computed_height = (self->rgb_count / 3) << (self->addr_count); + int computed_height = (self->rgb_count / 3) * (1 << (self->addr_count)) * self->tile; return computed_height; } diff --git a/shared-module/rgbmatrix/RGBMatrix.h b/shared-module/rgbmatrix/RGBMatrix.h index 7fce73c8b..4a0e9235e 100644 --- a/shared-module/rgbmatrix/RGBMatrix.h +++ b/shared-module/rgbmatrix/RGBMatrix.h @@ -44,5 +44,6 @@ typedef struct { bool core_is_initialized; bool paused; bool doublebuffer; + bool serpentine; int8_t tile; } rgbmatrix_rgbmatrix_obj_t; -- cgit v1.2.3 From 20c9f25a654df33e4fb719edfeaad8c4d4396f5e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 26 Jan 2021 14:35:26 -0600 Subject: rgbmatrix: Eliminate some duplicated height-calculating code This was hard to write, so let's have it written in 2 places instead of 4. --- shared-bindings/rgbmatrix/RGBMatrix.c | 4 ++-- shared-module/rgbmatrix/RGBMatrix.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index 7218b2a9e..3b2039e4d 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -219,8 +219,8 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n translate("tile must be greater than or equal to zero")); } + int computed_height = (rgb_count / 3) * (1 << (addr_count)) * tile; if (args[ARG_height].u_int != 0) { - int computed_height = (rgb_count / 3) * (1 << (addr_count)) * tile; if (computed_height != args[ARG_height].u_int) { mp_raise_ValueError_varg( translate("%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d"), addr_count, rgb_count, tile, computed_height, args[ARG_height].u_int); @@ -236,7 +236,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; if (framebuffer == mp_const_none) { int width = args[ARG_width].u_int; - int bufsize = 2 * width * rgb_count / 3 * (1 << addr_count) * tile; + int bufsize = 2 * width * computed_height; framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); } diff --git a/shared-module/rgbmatrix/RGBMatrix.c b/shared-module/rgbmatrix/RGBMatrix.c index 4318604c6..b8db0d893 100644 --- a/shared-module/rgbmatrix/RGBMatrix.c +++ b/shared-module/rgbmatrix/RGBMatrix.c @@ -62,7 +62,7 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i } self->width = width; - self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count) * tile; + self->bufsize = 2 * width * common_hal_rgbmatrix_rgbmatrix_get_height(self); common_hal_rgbmatrix_rgbmatrix_reconstruct(self, framebuffer); } -- cgit v1.2.3 From 189ec2fc60f8dbfb5b054174f0062b9baeb27ca3 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 26 Jan 2021 15:05:24 -0600 Subject: Disallow tile=0 --- locale/circuitpython.pot | 2 +- shared-bindings/rgbmatrix/RGBMatrix.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'shared-bindings') diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 4d8aceb85..81ee31e1e 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -3711,7 +3711,7 @@ msgid "threshold must be in the range 0-65536" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "tile must be greater than or equal to zero" +msgid "tile must be greater than zero" msgstr "" #: shared-bindings/time/__init__.c diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index 3b2039e4d..2a81bb53c 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -214,9 +214,9 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n int tile = args[ARG_tile].u_int; - if (tile < 0) { + if (tile <= 0) { mp_raise_ValueError_varg( - translate("tile must be greater than or equal to zero")); + translate("tile must be greater than zero")); } int computed_height = (rgb_count / 3) * (1 << (addr_count)) * tile; -- cgit v1.2.3 From 0098909757c80e4e924b400b7b6f35319e0458a9 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 28 Jan 2021 11:42:19 -0600 Subject: RGBMatrix: change default to serpentine=True The "serpentine" display order leads to much better wiring (shorter ribbon cables) and is preferred. Change the default accordingly. --- shared-bindings/rgbmatrix/RGBMatrix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'shared-bindings') diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index 2a81bb53c..30b72dffd 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -132,7 +132,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ } } -//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0, tile: int = 1, serpentine: bool = False) -> None: +//| def __init__(self, *, width: int, bit_depth: int, rgb_pins: Sequence[digitalio.DigitalInOut], addr_pins: Sequence[digitalio.DigitalInOut], clock_pin: digitalio.DigitalInOut, latch_pin: digitalio.DigitalInOut, output_enable_pin: digitalio.DigitalInOut, doublebuffer: bool = True, framebuffer: Optional[WriteableBuffer] = None, height: int = 0, tile: int = 1, serpentine: bool = True) -> None: //| """Create a RGBMatrix object with the given attributes. The height of //| the display is determined by the number of rgb and address pins and the number of tiles: //| ``len(rgb_pins) // 3 * 2 ** len(address_pins) * abs(tile)``. With 6 RGB pins, 4 @@ -185,7 +185,7 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n { MP_QSTR_framebuffer, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } }, { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, { MP_QSTR_tile, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 1 } }, - { MP_QSTR_serpentine, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } }, + { MP_QSTR_serpentine, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = true } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); -- cgit v1.2.3