From 5c6d94d3e5ac2c4bb8514ac920d59a465300465b Mon Sep 17 00:00:00 2001 From: James Bowman Date: Fri, 7 Feb 2020 10:30:49 -0800 Subject: Split into shared-module and shared-bindings --- shared-module/_eve/__init__.c | 270 ++++++++++++++++++++++++++++++++++++++++++ shared-module/_eve/__init__.h | 91 ++++++++++++++ 2 files changed, 361 insertions(+) create mode 100644 shared-module/_eve/__init__.c create mode 100644 shared-module/_eve/__init__.h (limited to 'shared-module') diff --git a/shared-module/_eve/__init__.c b/shared-module/_eve/__init__.c new file mode 100644 index 000000000..ca6fd4031 --- /dev/null +++ b/shared-module/_eve/__init__.c @@ -0,0 +1,270 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 James Bowman for Excamera Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include "py/runtime.h" +#include "shared-module/_eve/__init__.h" + +STATIC void write(common_hal__eve_t *eve, size_t len, void *buf) { + eve->dest[2] = mp_obj_new_bytearray_by_ref(len, buf); + mp_call_method_n_kw(1, 0, eve->dest); +} + +void common_hal__eve_flush(common_hal__eve_t *eve) { + if (eve->n != 0) { + write(eve, eve->n, eve->buf); + eve->n = 0; + } +} + +static void *append(common_hal__eve_t *eve, size_t m) { + if ((eve->n + m) > sizeof(eve->buf)) + common_hal__eve_flush(eve); + uint8_t *r = eve->buf + eve->n; + eve->n += m; + return (void*)r; +} + +void common_hal__eve_add(common_hal__eve_t *eve, size_t len, void *buf) { + if (len <= sizeof(eve->buf)) { + uint8_t *p = (uint8_t*)append(eve, len); + // memcpy(p, buffer_info.buf, buffer_info.len); + uint8_t *s = buf; for (size_t i = 0; i < len; i++) *p++ = *s++; + } else { + common_hal__eve_flush(eve); + write(eve, len, buf); + } +} + +#define C4(eve, u) (*(uint32_t*)append((eve), sizeof(uint32_t)) = (u)) + +void common_hal__eve_Vertex2f(common_hal__eve_t *eve, mp_float_t x, mp_float_t y) { + int16_t ix = (int)(eve->vscale * x); + int16_t iy = (int)(eve->vscale * y); + C4(eve, (1 << 30) | ((ix & 32767) << 15) | (iy & 32767)); +} + +void common_hal__eve_VertexFormat(common_hal__eve_t *eve, uint32_t frac) +{ + C4(eve, ((27 << 24) | ((frac & 7)))); + eve->vscale = 1 << eve->vscale; +} + + + +void common_hal__eve_AlphaFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref) { + C4(eve, ((9 << 24) | ((func & 7) << 8) | ((ref & 255)))); +} + +void common_hal__eve_Begin(common_hal__eve_t *eve, uint32_t prim) { + C4(eve, ((31 << 24) | ((prim & 15)))); +} + +void common_hal__eve_BitmapExtFormat(common_hal__eve_t *eve, uint32_t fmt) { + C4(eve, ((46 << 24) | (fmt & 65535))); +} + +void common_hal__eve_BitmapHandle(common_hal__eve_t *eve, uint32_t handle) { + C4(eve, ((5 << 24) | ((handle & 31)))); +} + +void common_hal__eve_BitmapLayoutH(common_hal__eve_t *eve, uint32_t linestride, uint32_t height) { + C4(eve, ((40 << 24) | (((linestride) & 3) << 2) | (((height) & 3)))); +} + +void common_hal__eve_BitmapLayout(common_hal__eve_t *eve, uint32_t format, uint32_t linestride, uint32_t height) { + C4(eve, ((7 << 24) | ((format & 31) << 19) | ((linestride & 1023) << 9) | ((height & 511)))); +} + +void common_hal__eve_BitmapSizeH(common_hal__eve_t *eve, uint32_t width, uint32_t height) { + C4(eve, ((41 << 24) | (((width) & 3) << 2) | (((height) & 3)))); +} + +void common_hal__eve_BitmapSize(common_hal__eve_t *eve, uint32_t filter, uint32_t wrapx, uint32_t wrapy, uint32_t width, uint32_t height) { + C4(eve, ((8 << 24) | ((filter & 1) << 20) | ((wrapx & 1) << 19) | ((wrapy & 1) << 18) | ((width & 511) << 9) | ((height & 511)))); +} + +void common_hal__eve_BitmapSource(common_hal__eve_t *eve, uint32_t addr) { + C4(eve, ((1 << 24) | ((addr & 0xffffff)))); +} + +void common_hal__eve_BitmapSwizzle(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a) { + C4(eve, ((47 << 24) | ((r & 7) << 9) | ((g & 7) << 6) | ((b & 7) << 3) | ((a & 7)))); +} + +void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t a, uint32_t p) { + C4(eve, ((21 << 24) | ((p & 1) << 17) | ((a & 131071)))); +} + +void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t b, uint32_t p) { + C4(eve, ((22 << 24) | ((p & 1) << 17) | ((b & 131071)))); +} + +void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t c, uint32_t p) { + C4(eve, ((23 << 24) | ((p & 1) << 17) | ((c & 16777215)))); +} + +void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t d, uint32_t p) { + C4(eve, ((24 << 24) | ((p & 1) << 17) | ((d & 131071)))); +} + +void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t e, uint32_t p) { + C4(eve, ((25 << 24) | ((p & 1) << 17) | ((e & 131071)))); +} + +void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t f, uint32_t p) { + C4(eve, ((26 << 24) | ((p & 1) << 17) | ((f & 16777215)))); +} + +void common_hal__eve_BlendFunc(common_hal__eve_t *eve, uint32_t src, uint32_t dst) { + C4(eve, ((11 << 24) | ((src & 7) << 3) | ((dst & 7)))); +} + +void common_hal__eve_Call(common_hal__eve_t *eve, uint32_t dest) { + C4(eve, ((29 << 24) | ((dest & 65535)))); +} + +void common_hal__eve_Cell(common_hal__eve_t *eve, uint32_t cell) { + C4(eve, ((6 << 24) | ((cell & 127)))); +} + +void common_hal__eve_ClearColorA(common_hal__eve_t *eve, uint32_t alpha) { + C4(eve, ((15 << 24) | ((alpha & 255)))); +} + +void common_hal__eve_ClearColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue) { + C4(eve, ((2 << 24) | ((red & 255) << 16) | ((green & 255) << 8) | ((blue & 255)))); +} + +void common_hal__eve_Clear(common_hal__eve_t *eve, uint32_t c, uint32_t s, uint32_t t) { + C4(eve, ((38 << 24) | ((c & 1) << 2) | ((s & 1) << 1) | ((t & 1)))); +} + +void common_hal__eve_ClearStencil(common_hal__eve_t *eve, uint32_t s) { + C4(eve, ((17 << 24) | ((s & 255)))); +} + +void common_hal__eve_ClearTag(common_hal__eve_t *eve, uint32_t s) { + C4(eve, ((18 << 24) | ((s & 255)))); +} + +void common_hal__eve_ColorA(common_hal__eve_t *eve, uint32_t alpha) { + C4(eve, ((16 << 24) | ((alpha & 255)))); +} + +void common_hal__eve_ColorMask(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a) { + C4(eve, ((32 << 24) | ((r & 1) << 3) | ((g & 1) << 2) | ((b & 1) << 1) | ((a & 1)))); +} + +void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue) { + C4(eve, ((4 << 24) | ((red & 255) << 16) | ((green & 255) << 8) | ((blue & 255)))); +} + +void common_hal__eve_Display(common_hal__eve_t *eve) { + C4(eve, ((0 << 24))); +} + +void common_hal__eve_End(common_hal__eve_t *eve) { + C4(eve, ((33 << 24))); +} + +void common_hal__eve_Jump(common_hal__eve_t *eve, uint32_t dest) { + C4(eve, ((30 << 24) | ((dest & 65535)))); +} + +void common_hal__eve_LineWidth(common_hal__eve_t *eve, uint32_t width) { + C4(eve, ((14 << 24) | ((width & 4095)))); +} + +void common_hal__eve_Macro(common_hal__eve_t *eve, uint32_t m) { + C4(eve, ((37 << 24) | ((m & 1)))); +} + +void common_hal__eve_Nop(common_hal__eve_t *eve) { + C4(eve, ((45 << 24))); +} + +void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr) { + C4(eve, ((42 << 24) | (((addr) & 4194303)))); +} + +void common_hal__eve_PointSize(common_hal__eve_t *eve, uint32_t size) { + C4(eve, ((13 << 24) | ((size & 8191)))); +} + +void common_hal__eve_RestoreContext(common_hal__eve_t *eve) { + C4(eve, ((35 << 24))); +} + +void common_hal__eve_Return(common_hal__eve_t *eve) { + C4(eve, ((36 << 24))); +} + +void common_hal__eve_SaveContext(common_hal__eve_t *eve) { + C4(eve, ((34 << 24))); +} + +void common_hal__eve_ScissorSize(common_hal__eve_t *eve, uint32_t width, uint32_t height) { + C4(eve, ((28 << 24) | ((width & 4095) << 12) | ((height & 4095)))); +} + +void common_hal__eve_ScissorXY(common_hal__eve_t *eve, uint32_t x, uint32_t y) { + C4(eve, ((27 << 24) | ((x & 2047) << 11) | ((y & 2047)))); +} + +void common_hal__eve_StencilFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref, uint32_t mask) { + C4(eve, ((10 << 24) | ((func & 7) << 16) | ((ref & 255) << 8) | ((mask & 255)))); +} + +void common_hal__eve_StencilMask(common_hal__eve_t *eve, uint32_t mask) { + C4(eve, ((19 << 24) | ((mask & 255)))); +} + +void common_hal__eve_StencilOp(common_hal__eve_t *eve, uint32_t sfail, uint32_t spass) { + C4(eve, ((12 << 24) | ((sfail & 7) << 3) | ((spass & 7)))); +} + +void common_hal__eve_TagMask(common_hal__eve_t *eve, uint32_t mask) { + C4(eve, ((20 << 24) | ((mask & 1)))); +} + +void common_hal__eve_Tag(common_hal__eve_t *eve, uint32_t s) { + C4(eve, ((3 << 24) | ((s & 255)))); +} + +void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, uint32_t x) { + C4(eve, ((43 << 24) | (((x) & 131071)))); +} + +void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, uint32_t y) { + C4(eve, ((44 << 24) | (((y) & 131071)))); +} + +void common_hal__eve_Vertex2ii(common_hal__eve_t *eve, uint32_t x, uint32_t y, uint32_t handle, uint32_t cell) { + C4(eve, ((2 << 30) | (((x) & 511) << 21) | (((y) & 511) << 12) | (((handle) & 31) << 7) | (((cell) & 127) << 0))); +} + diff --git a/shared-module/_eve/__init__.h b/shared-module/_eve/__init__.h new file mode 100644 index 000000000..f2fd7a943 --- /dev/null +++ b/shared-module/_eve/__init__.h @@ -0,0 +1,91 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 James Bowman for Excamera Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE__EVE___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE__EVE___INIT___H + +typedef struct _common_hal__eve_t { + mp_obj_t dest[3]; // Own 'write' method, plus argument + int vscale; // fixed-point scaling used for Vertex2f + size_t n; // Current size of command buffer + uint8_t buf[512]; // Command buffer +} common_hal__eve_t; + +void common_hal__eve_flush(common_hal__eve_t *eve); +void common_hal__eve_add(common_hal__eve_t *eve, size_t len, void *buf); +void common_hal__eve_Vertex2f(common_hal__eve_t *eve, mp_float_t x, mp_float_t y); + +void common_hal__eve_AlphaFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref); +void common_hal__eve_Begin(common_hal__eve_t *eve, uint32_t prim); +void common_hal__eve_BitmapExtFormat(common_hal__eve_t *eve, uint32_t fmt); +void common_hal__eve_BitmapHandle(common_hal__eve_t *eve, uint32_t handle); +void common_hal__eve_BitmapLayoutH(common_hal__eve_t *eve, uint32_t linestride, uint32_t height); +void common_hal__eve_BitmapLayout(common_hal__eve_t *eve, uint32_t format, uint32_t linestride, uint32_t height); +void common_hal__eve_BitmapSizeH(common_hal__eve_t *eve, uint32_t width, uint32_t height); +void common_hal__eve_BitmapSize(common_hal__eve_t *eve, uint32_t filter, uint32_t wrapx, uint32_t wrapy, uint32_t width, uint32_t height); +void common_hal__eve_BitmapSource(common_hal__eve_t *eve, uint32_t addr); +void common_hal__eve_BitmapSwizzle(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); +void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t a, uint32_t p); +void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t b, uint32_t p); +void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t c, uint32_t p); +void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t d, uint32_t p); +void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t e, uint32_t p); +void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t f, uint32_t p); +void common_hal__eve_BlendFunc(common_hal__eve_t *eve, uint32_t src, uint32_t dst); +void common_hal__eve_Call(common_hal__eve_t *eve, uint32_t dest); +void common_hal__eve_Cell(common_hal__eve_t *eve, uint32_t cell); +void common_hal__eve_ClearColorA(common_hal__eve_t *eve, uint32_t alpha); +void common_hal__eve_ClearColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue); +void common_hal__eve_Clear(common_hal__eve_t *eve, uint32_t c, uint32_t s, uint32_t t); +void common_hal__eve_ClearStencil(common_hal__eve_t *eve, uint32_t s); +void common_hal__eve_ClearTag(common_hal__eve_t *eve, uint32_t s); +void common_hal__eve_ColorA(common_hal__eve_t *eve, uint32_t alpha); +void common_hal__eve_ColorMask(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); +void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue); +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_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_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); +void common_hal__eve_ScissorSize(common_hal__eve_t *eve, uint32_t width, uint32_t height); +void common_hal__eve_ScissorXY(common_hal__eve_t *eve, uint32_t x, uint32_t y); +void common_hal__eve_StencilFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref, uint32_t mask); +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_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); + +#endif // MICROPY_INCLUDED_SHARED_MODULE__EVE___INIT___H -- cgit v1.2.3 From f101ff60c505f5ddcdd69cfd1f58e83c4676eb46 Mon Sep 17 00:00:00 2001 From: James Bowman Date: Fri, 7 Feb 2020 17:10:19 -0800 Subject: Move _eve module declarations into shared-bindings header --- shared-bindings/_eve/__init__.c | 3 +- shared-bindings/_eve/__init__.h | 84 +++++++++++++++++++++++++++++++++++++++++ shared-module/_eve/__init__.h | 54 -------------------------- 3 files changed, 86 insertions(+), 55 deletions(-) create mode 100644 shared-bindings/_eve/__init__.h (limited to 'shared-module') diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c index b398c0a5d..d3076afbf 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2020 James Bowman + * Copyright (c) 2020 James Bowman for Excamera Labs * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,7 @@ #include "py/binary.h" #include "shared-module/_eve/__init__.h" +#include "shared-bindings/_eve/__init__.h" //| :mod:`_eve` --- low-level BridgeTek EVE bindings //| ================================================ diff --git a/shared-bindings/_eve/__init__.h b/shared-bindings/_eve/__init__.h new file mode 100644 index 000000000..6287fb606 --- /dev/null +++ b/shared-bindings/_eve/__init__.h @@ -0,0 +1,84 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 James Bowman for Excamera Labs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS__EVE___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS__EVE___INIT___H + +void common_hal__eve_flush(common_hal__eve_t *eve); +void common_hal__eve_add(common_hal__eve_t *eve, size_t len, void *buf); +void common_hal__eve_Vertex2f(common_hal__eve_t *eve, mp_float_t x, mp_float_t y); + +void common_hal__eve_AlphaFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref); +void common_hal__eve_Begin(common_hal__eve_t *eve, uint32_t prim); +void common_hal__eve_BitmapExtFormat(common_hal__eve_t *eve, uint32_t fmt); +void common_hal__eve_BitmapHandle(common_hal__eve_t *eve, uint32_t handle); +void common_hal__eve_BitmapLayoutH(common_hal__eve_t *eve, uint32_t linestride, uint32_t height); +void common_hal__eve_BitmapLayout(common_hal__eve_t *eve, uint32_t format, uint32_t linestride, uint32_t height); +void common_hal__eve_BitmapSizeH(common_hal__eve_t *eve, uint32_t width, uint32_t height); +void common_hal__eve_BitmapSize(common_hal__eve_t *eve, uint32_t filter, uint32_t wrapx, uint32_t wrapy, uint32_t width, uint32_t height); +void common_hal__eve_BitmapSource(common_hal__eve_t *eve, uint32_t addr); +void common_hal__eve_BitmapSwizzle(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); +void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t a, uint32_t p); +void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t b, uint32_t p); +void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t c, uint32_t p); +void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t d, uint32_t p); +void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t e, uint32_t p); +void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t f, uint32_t p); +void common_hal__eve_BlendFunc(common_hal__eve_t *eve, uint32_t src, uint32_t dst); +void common_hal__eve_Call(common_hal__eve_t *eve, uint32_t dest); +void common_hal__eve_Cell(common_hal__eve_t *eve, uint32_t cell); +void common_hal__eve_ClearColorA(common_hal__eve_t *eve, uint32_t alpha); +void common_hal__eve_ClearColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue); +void common_hal__eve_Clear(common_hal__eve_t *eve, uint32_t c, uint32_t s, uint32_t t); +void common_hal__eve_ClearStencil(common_hal__eve_t *eve, uint32_t s); +void common_hal__eve_ClearTag(common_hal__eve_t *eve, uint32_t s); +void common_hal__eve_ColorA(common_hal__eve_t *eve, uint32_t alpha); +void common_hal__eve_ColorMask(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); +void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue); +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_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_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); +void common_hal__eve_ScissorSize(common_hal__eve_t *eve, uint32_t width, uint32_t height); +void common_hal__eve_ScissorXY(common_hal__eve_t *eve, uint32_t x, uint32_t y); +void common_hal__eve_StencilFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref, uint32_t mask); +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_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); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS__EVE___INIT___H diff --git a/shared-module/_eve/__init__.h b/shared-module/_eve/__init__.h index f2fd7a943..5217d860a 100644 --- a/shared-module/_eve/__init__.h +++ b/shared-module/_eve/__init__.h @@ -34,58 +34,4 @@ typedef struct _common_hal__eve_t { uint8_t buf[512]; // Command buffer } common_hal__eve_t; -void common_hal__eve_flush(common_hal__eve_t *eve); -void common_hal__eve_add(common_hal__eve_t *eve, size_t len, void *buf); -void common_hal__eve_Vertex2f(common_hal__eve_t *eve, mp_float_t x, mp_float_t y); - -void common_hal__eve_AlphaFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref); -void common_hal__eve_Begin(common_hal__eve_t *eve, uint32_t prim); -void common_hal__eve_BitmapExtFormat(common_hal__eve_t *eve, uint32_t fmt); -void common_hal__eve_BitmapHandle(common_hal__eve_t *eve, uint32_t handle); -void common_hal__eve_BitmapLayoutH(common_hal__eve_t *eve, uint32_t linestride, uint32_t height); -void common_hal__eve_BitmapLayout(common_hal__eve_t *eve, uint32_t format, uint32_t linestride, uint32_t height); -void common_hal__eve_BitmapSizeH(common_hal__eve_t *eve, uint32_t width, uint32_t height); -void common_hal__eve_BitmapSize(common_hal__eve_t *eve, uint32_t filter, uint32_t wrapx, uint32_t wrapy, uint32_t width, uint32_t height); -void common_hal__eve_BitmapSource(common_hal__eve_t *eve, uint32_t addr); -void common_hal__eve_BitmapSwizzle(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); -void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t a, uint32_t p); -void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t b, uint32_t p); -void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t c, uint32_t p); -void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t d, uint32_t p); -void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t e, uint32_t p); -void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t f, uint32_t p); -void common_hal__eve_BlendFunc(common_hal__eve_t *eve, uint32_t src, uint32_t dst); -void common_hal__eve_Call(common_hal__eve_t *eve, uint32_t dest); -void common_hal__eve_Cell(common_hal__eve_t *eve, uint32_t cell); -void common_hal__eve_ClearColorA(common_hal__eve_t *eve, uint32_t alpha); -void common_hal__eve_ClearColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue); -void common_hal__eve_Clear(common_hal__eve_t *eve, uint32_t c, uint32_t s, uint32_t t); -void common_hal__eve_ClearStencil(common_hal__eve_t *eve, uint32_t s); -void common_hal__eve_ClearTag(common_hal__eve_t *eve, uint32_t s); -void common_hal__eve_ColorA(common_hal__eve_t *eve, uint32_t alpha); -void common_hal__eve_ColorMask(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); -void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue); -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_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_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); -void common_hal__eve_ScissorSize(common_hal__eve_t *eve, uint32_t width, uint32_t height); -void common_hal__eve_ScissorXY(common_hal__eve_t *eve, uint32_t x, uint32_t y); -void common_hal__eve_StencilFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref, uint32_t mask); -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_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); - #endif // MICROPY_INCLUDED_SHARED_MODULE__EVE___INIT___H -- cgit v1.2.3 From a87dee2f66732690bde509e7d1221cce4c1fb466 Mon Sep 17 00:00:00 2001 From: James Bowman Date: Mon, 10 Feb 2020 19:34:38 -0800 Subject: Correct the BitmapTransform operations. Correct argument order better argument naming fix copypaste bug on C and F arguments --- shared-bindings/_eve/__init__.c | 58 ++++++++++++++++++--------------- shared-bindings/_eve/__init__.h | 12 +++---- shared-module/_eve/__init__.c | 71 ++++++++++++++++++++++++++++++++++------- 3 files changed, 97 insertions(+), 44 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c index 8ea9d033f..97b4e8c47 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -268,13 +268,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmapswizzle_obj, 5, 5, _bitmapswizz //| :param int p: precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0 //| :param int v: The :math:`a` component of the bitmap transform matrix, in signed 8.8 or 1.15 bit fixed-point form. Range 0-131071. The initial value is 256 //| +//| The initial value is **p** = 0, **v** = 256. This represents the value 1.0. +//| //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| STATIC mp_obj_t _bitmaptransforma(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { - uint32_t a = mp_obj_get_int_truncated(a0); - uint32_t p = mp_obj_get_int_truncated(a1); - common_hal__eve_BitmapTransformA(EVEHAL(self), a, p); + uint32_t p = mp_obj_get_int_truncated(a0); + uint32_t v = mp_obj_get_int_truncated(a1); + common_hal__eve_BitmapTransformA(EVEHAL(self), p, v); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransforma_obj, _bitmaptransforma); @@ -286,33 +288,34 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransforma_obj, _bitmaptransforma); //| :param int p: precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0 //| :param int v: The :math:`b` component of the bitmap transform matrix, in signed 8.8 or 1.15 bit fixed-point form. Range 0-131071. The initial value is 0 //| +//| The initial value is **p** = 0, **v** = 0. This represents the value 0.0. +//| //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| STATIC mp_obj_t _bitmaptransformb(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { - uint32_t b = mp_obj_get_int_truncated(a0); - uint32_t p = mp_obj_get_int_truncated(a1); - common_hal__eve_BitmapTransformB(EVEHAL(self), b, p); + uint32_t p = mp_obj_get_int_truncated(a0); + uint32_t v = mp_obj_get_int_truncated(a1); + common_hal__eve_BitmapTransformB(EVEHAL(self), p, v); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformb_obj, _bitmaptransformb); -//| .. method:: BitmapTransformC(c) +//| .. method:: BitmapTransformC(v) //| //| Set the :math:`c` component of the bitmap transform matrix //| -//| :param int c: The :math:`c` component of the bitmap transform matrix, in signed 15.8 bit fixed-point form. Range 0-16777215. The initial value is 0 +//| :param int v: The :math:`c` component of the bitmap transform matrix, in signed 15.8 bit fixed-point form. Range 0-16777215. 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 _bitmaptransformc(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { - uint32_t c = mp_obj_get_int_truncated(a0); - uint32_t p = mp_obj_get_int_truncated(a1); - common_hal__eve_BitmapTransformC(EVEHAL(self), c, p); +STATIC mp_obj_t _bitmaptransformc(mp_obj_t self, mp_obj_t a0) { + uint32_t v = mp_obj_get_int_truncated(a0); + common_hal__eve_BitmapTransformC(EVEHAL(self), v); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformc_obj, _bitmaptransformc); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmaptransformc_obj, _bitmaptransformc); //| .. method:: BitmapTransformD(p, v) //| @@ -321,13 +324,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformc_obj, _bitmaptransformc); //| :param int p: precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0 //| :param int v: The :math:`d` component of the bitmap transform matrix, in signed 8.8 or 1.15 bit fixed-point form. Range 0-131071. The initial value is 0 //| +//| The initial value is **p** = 0, **v** = 0. This represents the value 0.0. +//| //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| STATIC mp_obj_t _bitmaptransformd(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { - uint32_t d = mp_obj_get_int_truncated(a0); - uint32_t p = mp_obj_get_int_truncated(a1); - common_hal__eve_BitmapTransformD(EVEHAL(self), d, p); + uint32_t p = mp_obj_get_int_truncated(a0); + uint32_t v = mp_obj_get_int_truncated(a1); + common_hal__eve_BitmapTransformD(EVEHAL(self), p, v); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformd_obj, _bitmaptransformd); @@ -339,33 +344,34 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformd_obj, _bitmaptransformd); //| :param int p: precision control: 0 is 8.8, 1 is 1.15. Range 0-1. The initial value is 0 //| :param int v: The :math:`e` component of the bitmap transform matrix, in signed 8.8 or 1.15 bit fixed-point form. Range 0-131071. The initial value is 256 //| +//| The initial value is **p** = 0, **v** = 256. This represents the value 1.0. +//| //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| STATIC mp_obj_t _bitmaptransforme(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { - uint32_t e = mp_obj_get_int_truncated(a0); - uint32_t p = mp_obj_get_int_truncated(a1); - common_hal__eve_BitmapTransformE(EVEHAL(self), e, p); + uint32_t p = mp_obj_get_int_truncated(a0); + uint32_t v = mp_obj_get_int_truncated(a1); + common_hal__eve_BitmapTransformE(EVEHAL(self), p, v); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransforme_obj, _bitmaptransforme); -//| .. method:: BitmapTransformF(f) +//| .. method:: BitmapTransformF(v) //| //| Set the :math:`f` component of the bitmap transform matrix //| -//| :param int f: The :math:`f` component of the bitmap transform matrix, in signed 15.8 bit fixed-point form. Range 0-16777215. The initial value is 0 +//| :param int v: The :math:`f` component of the bitmap transform matrix, in signed 15.8 bit fixed-point form. Range 0-16777215. 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 _bitmaptransformf(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { - uint32_t f = mp_obj_get_int_truncated(a0); - uint32_t p = mp_obj_get_int_truncated(a1); - common_hal__eve_BitmapTransformF(EVEHAL(self), f, p); +STATIC mp_obj_t _bitmaptransformf(mp_obj_t self, mp_obj_t a0) { + uint32_t v = mp_obj_get_int_truncated(a0); + common_hal__eve_BitmapTransformF(EVEHAL(self), v); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_3(bitmaptransformf_obj, _bitmaptransformf); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bitmaptransformf_obj, _bitmaptransformf); //| .. method:: BlendFunc(src, dst) //| diff --git a/shared-bindings/_eve/__init__.h b/shared-bindings/_eve/__init__.h index 6287fb606..759a629bb 100644 --- a/shared-bindings/_eve/__init__.h +++ b/shared-bindings/_eve/__init__.h @@ -41,12 +41,12 @@ void common_hal__eve_BitmapSizeH(common_hal__eve_t *eve, uint32_t width, uint32_ void common_hal__eve_BitmapSize(common_hal__eve_t *eve, uint32_t filter, uint32_t wrapx, uint32_t wrapy, uint32_t width, uint32_t height); void common_hal__eve_BitmapSource(common_hal__eve_t *eve, uint32_t addr); void common_hal__eve_BitmapSwizzle(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a); -void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t a, uint32_t p); -void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t b, uint32_t p); -void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t c, uint32_t p); -void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t d, uint32_t p); -void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t e, uint32_t p); -void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t f, uint32_t p); +void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t p, uint32_t v); +void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t p, uint32_t v); +void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t v); +void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t p, uint32_t v); +void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t p, uint32_t v); +void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t v); void common_hal__eve_BlendFunc(common_hal__eve_t *eve, uint32_t src, uint32_t dst); void common_hal__eve_Call(common_hal__eve_t *eve, uint32_t dest); void common_hal__eve_Cell(common_hal__eve_t *eve, uint32_t cell); diff --git a/shared-module/_eve/__init__.c b/shared-module/_eve/__init__.c index ca6fd4031..2c93eb69f 100644 --- a/shared-module/_eve/__init__.c +++ b/shared-module/_eve/__init__.c @@ -80,190 +80,237 @@ void common_hal__eve_AlphaFunc(common_hal__eve_t *eve, uint32_t func, uint32_t r C4(eve, ((9 << 24) | ((func & 7) << 8) | ((ref & 255)))); } + void common_hal__eve_Begin(common_hal__eve_t *eve, uint32_t prim) { C4(eve, ((31 << 24) | ((prim & 15)))); } + void common_hal__eve_BitmapExtFormat(common_hal__eve_t *eve, uint32_t fmt) { C4(eve, ((46 << 24) | (fmt & 65535))); } + void common_hal__eve_BitmapHandle(common_hal__eve_t *eve, uint32_t handle) { C4(eve, ((5 << 24) | ((handle & 31)))); } + void common_hal__eve_BitmapLayoutH(common_hal__eve_t *eve, uint32_t linestride, uint32_t height) { C4(eve, ((40 << 24) | (((linestride) & 3) << 2) | (((height) & 3)))); } + void common_hal__eve_BitmapLayout(common_hal__eve_t *eve, uint32_t format, uint32_t linestride, uint32_t height) { C4(eve, ((7 << 24) | ((format & 31) << 19) | ((linestride & 1023) << 9) | ((height & 511)))); } + void common_hal__eve_BitmapSizeH(common_hal__eve_t *eve, uint32_t width, uint32_t height) { C4(eve, ((41 << 24) | (((width) & 3) << 2) | (((height) & 3)))); } + void common_hal__eve_BitmapSize(common_hal__eve_t *eve, uint32_t filter, uint32_t wrapx, uint32_t wrapy, uint32_t width, uint32_t height) { C4(eve, ((8 << 24) | ((filter & 1) << 20) | ((wrapx & 1) << 19) | ((wrapy & 1) << 18) | ((width & 511) << 9) | ((height & 511)))); } + void common_hal__eve_BitmapSource(common_hal__eve_t *eve, uint32_t addr) { C4(eve, ((1 << 24) | ((addr & 0xffffff)))); } + void common_hal__eve_BitmapSwizzle(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a) { C4(eve, ((47 << 24) | ((r & 7) << 9) | ((g & 7) << 6) | ((b & 7) << 3) | ((a & 7)))); } -void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t a, uint32_t p) { - C4(eve, ((21 << 24) | ((p & 1) << 17) | ((a & 131071)))); + +void common_hal__eve_BitmapTransformA(common_hal__eve_t *eve, uint32_t p, uint32_t v) { + C4(eve, ((21 << 24) | ((p & 1) << 17) | ((v & 131071)))); } -void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t b, uint32_t p) { - C4(eve, ((22 << 24) | ((p & 1) << 17) | ((b & 131071)))); + +void common_hal__eve_BitmapTransformB(common_hal__eve_t *eve, uint32_t p, uint32_t v) { + C4(eve, ((22 << 24) | ((p & 1) << 17) | ((v & 131071)))); } -void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t c, uint32_t p) { - C4(eve, ((23 << 24) | ((p & 1) << 17) | ((c & 16777215)))); + +void common_hal__eve_BitmapTransformC(common_hal__eve_t *eve, uint32_t v) { + C4(eve, ((23 << 24) | ((v & 16777215)))); } -void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t d, uint32_t p) { - C4(eve, ((24 << 24) | ((p & 1) << 17) | ((d & 131071)))); + +void common_hal__eve_BitmapTransformD(common_hal__eve_t *eve, uint32_t p, uint32_t v) { + C4(eve, ((24 << 24) | ((p & 1) << 17) | ((v & 131071)))); } -void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t e, uint32_t p) { - C4(eve, ((25 << 24) | ((p & 1) << 17) | ((e & 131071)))); + +void common_hal__eve_BitmapTransformE(common_hal__eve_t *eve, uint32_t p, uint32_t v) { + C4(eve, ((25 << 24) | ((p & 1) << 17) | ((v & 131071)))); } -void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t f, uint32_t p) { - C4(eve, ((26 << 24) | ((p & 1) << 17) | ((f & 16777215)))); + +void common_hal__eve_BitmapTransformF(common_hal__eve_t *eve, uint32_t v) { + C4(eve, ((26 << 24) | ((v & 16777215)))); } + void common_hal__eve_BlendFunc(common_hal__eve_t *eve, uint32_t src, uint32_t dst) { C4(eve, ((11 << 24) | ((src & 7) << 3) | ((dst & 7)))); } + void common_hal__eve_Call(common_hal__eve_t *eve, uint32_t dest) { C4(eve, ((29 << 24) | ((dest & 65535)))); } + void common_hal__eve_Cell(common_hal__eve_t *eve, uint32_t cell) { C4(eve, ((6 << 24) | ((cell & 127)))); } + void common_hal__eve_ClearColorA(common_hal__eve_t *eve, uint32_t alpha) { C4(eve, ((15 << 24) | ((alpha & 255)))); } + void common_hal__eve_ClearColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue) { C4(eve, ((2 << 24) | ((red & 255) << 16) | ((green & 255) << 8) | ((blue & 255)))); } + void common_hal__eve_Clear(common_hal__eve_t *eve, uint32_t c, uint32_t s, uint32_t t) { C4(eve, ((38 << 24) | ((c & 1) << 2) | ((s & 1) << 1) | ((t & 1)))); } + void common_hal__eve_ClearStencil(common_hal__eve_t *eve, uint32_t s) { C4(eve, ((17 << 24) | ((s & 255)))); } + void common_hal__eve_ClearTag(common_hal__eve_t *eve, uint32_t s) { C4(eve, ((18 << 24) | ((s & 255)))); } + void common_hal__eve_ColorA(common_hal__eve_t *eve, uint32_t alpha) { C4(eve, ((16 << 24) | ((alpha & 255)))); } + void common_hal__eve_ColorMask(common_hal__eve_t *eve, uint32_t r, uint32_t g, uint32_t b, uint32_t a) { C4(eve, ((32 << 24) | ((r & 1) << 3) | ((g & 1) << 2) | ((b & 1) << 1) | ((a & 1)))); } + void common_hal__eve_ColorRGB(common_hal__eve_t *eve, uint32_t red, uint32_t green, uint32_t blue) { C4(eve, ((4 << 24) | ((red & 255) << 16) | ((green & 255) << 8) | ((blue & 255)))); } + void common_hal__eve_Display(common_hal__eve_t *eve) { C4(eve, ((0 << 24))); } + void common_hal__eve_End(common_hal__eve_t *eve) { C4(eve, ((33 << 24))); } + void common_hal__eve_Jump(common_hal__eve_t *eve, uint32_t dest) { C4(eve, ((30 << 24) | ((dest & 65535)))); } + void common_hal__eve_LineWidth(common_hal__eve_t *eve, uint32_t width) { C4(eve, ((14 << 24) | ((width & 4095)))); } + void common_hal__eve_Macro(common_hal__eve_t *eve, uint32_t m) { C4(eve, ((37 << 24) | ((m & 1)))); } + void common_hal__eve_Nop(common_hal__eve_t *eve) { C4(eve, ((45 << 24))); } + void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr) { C4(eve, ((42 << 24) | (((addr) & 4194303)))); } + void common_hal__eve_PointSize(common_hal__eve_t *eve, uint32_t size) { C4(eve, ((13 << 24) | ((size & 8191)))); } + void common_hal__eve_RestoreContext(common_hal__eve_t *eve) { C4(eve, ((35 << 24))); } + void common_hal__eve_Return(common_hal__eve_t *eve) { C4(eve, ((36 << 24))); } + void common_hal__eve_SaveContext(common_hal__eve_t *eve) { C4(eve, ((34 << 24))); } + void common_hal__eve_ScissorSize(common_hal__eve_t *eve, uint32_t width, uint32_t height) { C4(eve, ((28 << 24) | ((width & 4095) << 12) | ((height & 4095)))); } + void common_hal__eve_ScissorXY(common_hal__eve_t *eve, uint32_t x, uint32_t y) { C4(eve, ((27 << 24) | ((x & 2047) << 11) | ((y & 2047)))); } + void common_hal__eve_StencilFunc(common_hal__eve_t *eve, uint32_t func, uint32_t ref, uint32_t mask) { C4(eve, ((10 << 24) | ((func & 7) << 16) | ((ref & 255) << 8) | ((mask & 255)))); } + void common_hal__eve_StencilMask(common_hal__eve_t *eve, uint32_t mask) { C4(eve, ((19 << 24) | ((mask & 255)))); } + void common_hal__eve_StencilOp(common_hal__eve_t *eve, uint32_t sfail, uint32_t spass) { C4(eve, ((12 << 24) | ((sfail & 7) << 3) | ((spass & 7)))); } + void common_hal__eve_TagMask(common_hal__eve_t *eve, uint32_t mask) { C4(eve, ((20 << 24) | ((mask & 1)))); } + void common_hal__eve_Tag(common_hal__eve_t *eve, uint32_t s) { C4(eve, ((3 << 24) | ((s & 255)))); } + void common_hal__eve_VertexTranslateX(common_hal__eve_t *eve, uint32_t x) { C4(eve, ((43 << 24) | (((x) & 131071)))); } + void common_hal__eve_VertexTranslateY(common_hal__eve_t *eve, uint32_t y) { C4(eve, ((44 << 24) | (((y) & 131071)))); } + void common_hal__eve_Vertex2ii(common_hal__eve_t *eve, uint32_t x, uint32_t y, uint32_t handle, uint32_t cell) { C4(eve, ((2 << 30) | (((x) & 511) << 21) | (((y) & 511) << 12) | (((handle) & 31) << 7) | (((cell) & 127) << 0))); } -- cgit v1.2.3 From 07708f15185d96930621493c3e2886cc2e948622 Mon Sep 17 00:00:00 2001 From: Gadi Rotenberg Date: Sun, 9 Feb 2020 13:25:16 +0200 Subject: Added fix to allow remount when usb enabled but msc is ejected --- shared-module/storage/__init__.c | 4 +--- supervisor/shared/usb/usb_msc_flash.c | 10 +++++++++- supervisor/usb.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'shared-module') diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index 215e1356a..c3d4b50c8 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -149,9 +149,7 @@ void common_hal_storage_remount(const char *mount_path, bool readonly, bool disa } #ifdef USB_AVAILABLE - // TODO(dhalbert): is this is a good enough check? It checks for - // CDC enabled. There is no "MSC enabled" check. - if (usb_enabled()) { + if (!usb_msc_ejected()) { mp_raise_RuntimeError(translate("Cannot remount '/' when USB is active.")); } #endif diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 0376cfc1d..c0279f9e5 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -39,7 +39,7 @@ #define MSC_FLASH_BLOCK_SIZE 512 -static bool ejected[1]; +static bool ejected[1] = {true}; void usb_msc_mount(void) { // Reset the ejection tracking every time we're plugged into USB. This allows for us to battery @@ -53,6 +53,14 @@ void usb_msc_umount(void) { } +bool usb_msc_ejected(void) { + bool all_ejected = true; + for (uint8_t i = 0; i < sizeof(ejected); i++) { + all_ejected &= ejected[i]; + } + return all_ejected; +} + // The root FS is always at the end of the list. static fs_user_mount_t* get_vfs(int lun) { // TODO(tannewt): Return the mount which matches the lun where 0 is the end diff --git a/supervisor/usb.h b/supervisor/usb.h index 0cc361619..29280c725 100644 --- a/supervisor/usb.h +++ b/supervisor/usb.h @@ -44,5 +44,6 @@ void usb_init(void); // Propagate plug/unplug events to the MSC logic. void usb_msc_mount(void); void usb_msc_umount(void); +bool usb_msc_ejected(void); #endif // MICROPY_INCLUDED_SUPERVISOR_USB_H -- cgit v1.2.3 From 84ad3d8393db46eacfe3432d6476f1c5c48077e3 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Sun, 16 Feb 2020 00:23:43 +0000 Subject: Addition of RTS/CTS/RS485 UART functionality --- ports/mimxrt10xx/common-hal/busio/UART.c | 62 ++++++++++++++--- .../peripherals/mimxrt10xx/MIMXRT1021/periph.c | 80 ++++++++++++++++------ .../peripherals/mimxrt10xx/MIMXRT1021/periph.h | 2 + shared-bindings/busio/UART.c | 13 +++- shared-bindings/busio/UART.h | 7 +- shared-module/board/__init__.c | 17 ++++- 6 files changed, 145 insertions(+), 36 deletions(-) (limited to 'shared-module') diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index a4819798b..2842b2cd9 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -53,8 +53,8 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) { IOMUXC_SetPinConfig(0, 0, 0, 0, periph->pin->cfg_reg, IOMUXC_SW_PAD_CTL_PAD_HYS(0) - | IOMUXC_SW_PAD_CTL_PAD_PUS(0) - | IOMUXC_SW_PAD_CTL_PAD_PUE(0) + | IOMUXC_SW_PAD_CTL_PAD_PUS(1) + | IOMUXC_SW_PAD_CTL_PAD_PUE(1) | IOMUXC_SW_PAD_CTL_PAD_PKE(1) | IOMUXC_SW_PAD_CTL_PAD_ODE(0) | IOMUXC_SW_PAD_CTL_PAD_SPEED(1) @@ -72,9 +72,10 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st } void common_hal_busio_uart_construct(busio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, - uint16_t receiver_buffer_size) { + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, + const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode, + uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size) { // TODO: Allow none rx or tx @@ -111,12 +112,48 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if(self->rx_pin == NULL || self->tx_pin == NULL) { mp_raise_RuntimeError(translate("Invalid UART pin selection")); - } else { - self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1]; } + // Now check for RTS/CTS pin(s) + const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t); + const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t); + + if (rts != mp_const_none) { + for (uint32_t i=0; i < rts_count; ++i) + { + if (mcu_uart_rts_list[i].bank_idx == self->rx_pin->bank_idx) { + if (mcu_uart_rts_list[i].pin == rts) { + self->rts_pin = &mcu_uart_rts_list[i]; + break; + } + } + } + if (self->rts_pin == NULL) + mp_raise_ValueError(translate("Selected RTS pin not valid")); + } + + if (cts != mp_const_none) { + for (uint32_t i=0; i < cts_count; ++i) + { + if (mcu_uart_cts_list[i].bank_idx == self->rx_pin->bank_idx) { + if (mcu_uart_cts_list[i].pin == cts) { + self->cts_pin = &mcu_uart_cts_list[i]; + break; + } + } + } + if (self->cts_pin == NULL) + mp_raise_ValueError(translate("Selected CTS pin not valid")); + } + + self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1]; + config_periph_pin(self->rx_pin); config_periph_pin(self->tx_pin); + if (self->rts_pin) + config_periph_pin(self->rts_pin); + if (self->cts_pin) + config_periph_pin(self->cts_pin); lpuart_config_t config = { 0 }; LPUART_GetDefaultConfig(&config); @@ -125,10 +162,13 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, config.baudRate_Bps = self->baudrate; config.enableTx = self->tx_pin != NULL; config.enableRx = self->rx_pin != NULL; - + config.enableRxRTS = self->rts_pin != NULL; + config.enableTxCTS = self->cts_pin != NULL; + LPUART_Init(self->uart, &config, UART_CLOCK_FREQ); - claim_pin(self->tx_pin->pin); + if (self->tx_pin != NULL) + claim_pin(self->tx_pin->pin); if (self->rx_pin != NULL) { ringbuf_alloc(&self->rbuf, receiver_buffer_size, true); @@ -203,7 +243,9 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t LPUART_TransferAbortReceive(self->uart, &self->handle); } - return len - self->handle.rxDataSize; + // The only place we can reliably tell how many bytes have been received is from the current + // wp in the handle (because the abort nukes rxDataSize, and reading it before abort is a race.) + return self->handle.rxData-data; } // Write characters. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c index 39e4f0131..0417f29cc 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.c @@ -109,53 +109,93 @@ LPUART_Type *mcu_uart_banks[] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, L const mcu_periph_obj_t mcu_uart_rx_list[16] = { PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_23), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_09), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_09), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_23), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_07), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_15), PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_03), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_33), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_11), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_11), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_RX_SELECT_INPUT, 2, &pin_GPIO_EMC_33), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_39), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_11), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_11), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_39), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_13), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_01), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_35), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_05), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_05), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_35), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_27), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_03), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_03), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_27), }; const mcu_periph_obj_t mcu_uart_tx_list[16] = { PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_06), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_22), - PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_08), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B1_08), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_22), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_06), PERIPH_PIN(3, 2, kIOMUXC_LPUART3_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_14), PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_02), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_32), - PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_10), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B1_10), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_TX_SELECT_INPUT, 2, &pin_GPIO_EMC_32), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_38), - PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_10), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 0, &pin_GPIO_AD_B0_10), + PERIPH_PIN(5, 2, kIOMUXC_LPUART5_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_38), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_12), PERIPH_PIN(6, 2, kIOMUXC_LPUART6_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_00), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_34), - PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B0_04), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B0_04), + PERIPH_PIN(7, 2, kIOMUXC_LPUART7_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_34), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_EMC_26), - PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_02), + PERIPH_PIN(8, 2, kIOMUXC_LPUART8_TX_SELECT_INPUT, 1, &pin_GPIO_EMC_26), +}; + +const mcu_periph_obj_t mcu_uart_rts_list[10] = { + PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_09), + + PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_21), + PERIPH_PIN(2, 2, 0, 1, &pin_GPIO_AD_B1_07), + + PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_13), + + PERIPH_PIN(4, 2, 0, 0, &pin_GPIO_EMC_01), + PERIPH_PIN(4, 2, 0, 1, &pin_GPIO_EMC_31), + + PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_37), + + PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_15), + + PERIPH_PIN(7, 2, 0, 1, &pin_GPIO_SD_B0_03), + + PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_25), +}; + +const mcu_periph_obj_t mcu_uart_cts_list[10] = { + PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_08), + + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 0, &pin_GPIO_AD_B1_06), + PERIPH_PIN(2, 2, kIOMUXC_LPUART2_CTS_B_SELECT_INPUT, 1, &pin_GPIO_EMC_20), + + PERIPH_PIN(3, 2, 0, 1, &pin_GPIO_AD_B0_12), + + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_00), + PERIPH_PIN(4, 2, kIOMUXC_LPUART4_CTS_B_SELECT_INPUT, 0, &pin_GPIO_EMC_30), + + PERIPH_PIN(5, 2, 0, 0, &pin_GPIO_EMC_36), + + PERIPH_PIN(6, 2, 0, 0, &pin_GPIO_EMC_14), + + PERIPH_PIN(7, 2, 0, 0, &pin_GPIO_SD_B0_02), + + PERIPH_PIN(8, 2, 0, 0, &pin_GPIO_EMC_24), }; const mcu_pwm_obj_t mcu_pwm_list[39] = { diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h index 1d720f633..ba88ef4c6 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/periph.h @@ -37,6 +37,8 @@ extern const mcu_periph_obj_t mcu_spi_miso_list[8]; extern const mcu_periph_obj_t mcu_uart_rx_list[16]; extern const mcu_periph_obj_t mcu_uart_tx_list[16]; +extern const mcu_periph_obj_t mcu_uart_rts_list[10]; +extern const mcu_periph_obj_t mcu_uart_cts_list[10]; extern const mcu_pwm_obj_t mcu_pwm_list[39]; diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 1fc81e78e..529d2d3ce 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -82,7 +82,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co // https://github.com/adafruit/circuitpython/issues/1056) busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; - enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size}; + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, ARG_rts, ARG_cts, ARG_rs485}; static const mp_arg_t allowed_args[] = { { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -92,6 +92,9 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, + { MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_rs485, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.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); @@ -124,7 +127,13 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); validate_timeout(timeout); - common_hal_busio_uart_construct(self, tx, rx, + const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(args[ARG_rts].u_obj); + + const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj); + + bool rs485 = args[ARG_rs485].u_bool; + + common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, args[ARG_baudrate].u_int, bits, parity, stop, timeout, args[ARG_receiver_buffer_size].u_int); return (mp_obj_t)self; diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h index cfd2c800c..1d748ecc7 100644 --- a/shared-bindings/busio/UART.h +++ b/shared-bindings/busio/UART.h @@ -40,9 +40,10 @@ typedef enum { // Construct an underlying UART object. extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, - uint16_t receiver_buffer_size); + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, + const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode, + uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size); extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 914bc4313..05567d7ab 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -100,8 +100,23 @@ mp_obj_t common_hal_board_create_uart(void) { const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX); const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX); +#ifdef DEFAULT_UART_BUS_RTS + const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RTS); +#else + const mcu_pin_obj_t* rts = mp_const_none; +#endif +#ifdef DEFAULT_UART_BUS_CTS + const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_CTS); +#else + const mcu_pin_obj_t* cts = mp_const_none; +#endif +#ifdef DEFAULT_UART_IS_RS485 + const bool rs485 = true; +#else + const bool rs485 = false; +#endif - common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64); + common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, 9600, 8, PARITY_NONE, 1, 1.0f, 64); MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self); return MP_STATE_VM(shared_uart_bus); } -- cgit v1.2.3 From d388899985b24530cc08cdf10ed15e3c7ba41349 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Tue, 18 Feb 2020 00:09:35 +0000 Subject: Addition of RS485 support --- ports/mimxrt10xx/common-hal/busio/UART.c | 38 +++++++++++++++++++--- .../mimxrt10xx/supervisor/flexspi_nor_flash_ops.c | 2 +- shared-bindings/busio/UART.c | 15 ++++++--- shared-bindings/busio/UART.h | 3 +- shared-module/board/__init__.c | 11 +++++-- 5 files changed, 56 insertions(+), 13 deletions(-) (limited to 'shared-module') diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index 2842b2cd9..3609a9998 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -73,7 +73,8 @@ void LPUART_UserCallback(LPUART_Type *base, lpuart_handle_t *handle, status_t st void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, - const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode, + const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, + const mcu_pin_obj_t * rs485_dir, bool rs485_invert, uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, uint16_t receiver_buffer_size) { @@ -114,7 +115,22 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_raise_RuntimeError(translate("Invalid UART pin selection")); } - // Now check for RTS/CTS pin(s) + // Filter for sane settings for RS485 + if (rs485_dir != mp_const_none) { + if ((rts != mp_const_none) || (cts != mp_const_none)) { + mp_raise_ValueError(translate("Cannot specify RTS or CTS in RS485 mode")); + } + // For IMXRT the RTS pin is used for RS485 direction + rts = rs485_dir; + } + else + { + if (rs485_invert == true) { + mp_raise_ValueError(translate("RS485 inversion specified when not in RS485 mode")); + } + } + + // Now check for RTS/CTS (or overloaded RS485 direction) pin(s) const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t); const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t); @@ -163,10 +179,24 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, config.enableTx = self->tx_pin != NULL; config.enableRx = self->rx_pin != NULL; config.enableRxRTS = self->rts_pin != NULL; - config.enableTxCTS = self->cts_pin != NULL; - + config.enableTxCTS = self->cts_pin != NULL; + if (self->rts_pin != NULL) + claim_pin(self->rts_pin->pin); + if (self->cts_pin != NULL) + claim_pin(self->cts_pin->pin); + LPUART_Init(self->uart, &config, UART_CLOCK_FREQ); + // Before we init, setup RS485 direction pin + // ..unfortunately this isn't done by the driver library + uint32_t modir = (self->uart->MODIR) & ~(LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK); + if (rs485_dir != mp_const_none) { + modir |= LPUART_MODIR_TXRTSE_MASK; + if ( rs485_invert == true ) + modir |= LPUART_MODIR_TXRTSPOL_MASK; + } + self->uart->MODIR = modir; + if (self->tx_pin != NULL) claim_pin(self->tx_pin->pin); diff --git a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c index 71252d677..f97a54a89 100644 --- a/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c +++ b/ports/mimxrt10xx/supervisor/flexspi_nor_flash_ops.c @@ -324,7 +324,7 @@ void flexspi_nor_flash_init(FLEXSPI_Type *base) config.ahbConfig.enableAHBBufferable = true; config.ahbConfig.enableReadAddressOpt = true; config.ahbConfig.enableAHBCachable = true; - config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad; + config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackInternally; //kFLEXSPI_ReadSampleClkLoopbackFromDqsPad; FLEXSPI_Init(base, &config); /* Configure flash settings according to serial flash feature. */ diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 529d2d3ce..02c5afb16 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -53,6 +53,10 @@ //| //| :param ~microcontroller.Pin tx: the pin to transmit with, or ``None`` if this ``UART`` is receive-only. //| :param ~microcontroller.Pin rx: the pin to receive on, or ``None`` if this ``UART`` is transmit-only. +//| :param ~microcontroller.Pin rts: the pin for rts, or ``None`` if rts not in use. +//| :param ~microcontroller.Pin cts: the pin for cts, or ``None`` if cts not in use. +//| :param ~microcontroller.Pin rs485_dir: the pin for rs485 direction setting, or ``None`` if rs485 not in use. +//| :param bool rs485_invert: set to invert the sense of the rs485_dir pin. //| :param int baudrate: the transmit and receive speed. //| :param int bits: the number of bits per byte, 7, 8 or 9. //| :param Parity parity: the parity used for error checking. @@ -82,7 +86,8 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co // https://github.com/adafruit/circuitpython/issues/1056) busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); self->base.type = &busio_uart_type; - enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, ARG_rts, ARG_cts, ARG_rs485}; + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, + ARG_rts, ARG_cts, ARG_rs485_dir,ARG_rs485_invert}; static const mp_arg_t allowed_args[] = { { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -94,7 +99,8 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, { MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_rs485, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } }, + { MP_QSTR_rs485_dir, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none } }, + { MP_QSTR_rs485_invert, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.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); @@ -131,9 +137,10 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj); - bool rs485 = args[ARG_rs485].u_bool; + const mcu_pin_obj_t* rs485_dir = args[ARG_rs485_dir].u_obj; + bool rs485_invert = args[ARG_rs485_invert].u_bool; - common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, + common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, args[ARG_baudrate].u_int, bits, parity, stop, timeout, args[ARG_receiver_buffer_size].u_int); return (mp_obj_t)self; diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h index 1d748ecc7..fe71e8668 100644 --- a/shared-bindings/busio/UART.h +++ b/shared-bindings/busio/UART.h @@ -41,7 +41,8 @@ typedef enum { // Construct an underlying UART object. extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, - const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, bool rs485_mode, + const mcu_pin_obj_t * rts, const mcu_pin_obj_t * cts, + const mcu_pin_obj_t * rs485_dir, bool rs485_invert, uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, uint16_t receiver_buffer_size); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 05567d7ab..952e1fc10 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -111,12 +111,17 @@ mp_obj_t common_hal_board_create_uart(void) { const mcu_pin_obj_t* cts = mp_const_none; #endif #ifdef DEFAULT_UART_IS_RS485 - const bool rs485 = true; + const mcu_pin_obj_t* rs485_dir = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RS485DIR); +#ifdef DEFAULT_UART_RS485_INVERT + const bool rs485_invert = true; +#endif #else - const bool rs485 = false; + const mcu_pin_obj_t* rs485_dir = mp_const_none; + const bool rs485_invert = true; #endif - common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485, 9600, 8, PARITY_NONE, 1, 1.0f, 64); + common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, + 9600, 8, PARITY_NONE, 1, 1.0f, 64); MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self); return MP_STATE_VM(shared_uart_bus); } -- cgit v1.2.3 From d41cf2e9265e3250d8e98c06ce0ea8dfc523edb1 Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Sun, 23 Feb 2020 11:16:24 +0000 Subject: Fix incorrect initialisation of default UART --- shared-module/board/__init__.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 952e1fc10..bbf177384 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -114,10 +114,12 @@ mp_obj_t common_hal_board_create_uart(void) { const mcu_pin_obj_t* rs485_dir = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RS485DIR); #ifdef DEFAULT_UART_RS485_INVERT const bool rs485_invert = true; +#else + const bool rs485_invert = false; #endif #else const mcu_pin_obj_t* rs485_dir = mp_const_none; - const bool rs485_invert = true; + const bool rs485_invert = false; #endif common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, -- cgit v1.2.3 From b6206406de2a232299ebdd1d187c7656ae79f8f2 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 28 Feb 2020 23:32:24 -0500 Subject: new pin validation routines; don't use mp_const_none if NULL will do --- .../atmel-samd/boards/hallowing_m4_express/board.c | 2 +- ports/atmel-samd/boards/monster_m4sk/board.c | 2 +- ports/atmel-samd/boards/openbook_m4/board.c | 2 +- ports/atmel-samd/boards/pewpew_m4/board.c | 2 +- ports/atmel-samd/boards/pybadge/board.c | 2 +- ports/atmel-samd/boards/pybadge_airlift/board.c | 2 +- ports/atmel-samd/boards/pygamer/board.c | 2 +- ports/atmel-samd/boards/pygamer_advance/board.c | 2 +- ports/atmel-samd/common-hal/analogio/AnalogIn.c | 4 +- ports/atmel-samd/common-hal/audiobusio/I2SOut.c | 8 ++-- ports/atmel-samd/common-hal/audiobusio/PDMIn.c | 6 +-- ports/atmel-samd/common-hal/audioio/AudioOut.c | 6 +-- ports/atmel-samd/common-hal/busio/SPI.c | 4 +- ports/atmel-samd/common-hal/busio/UART.c | 8 ++-- .../atmel-samd/common-hal/digitalio/DigitalInOut.c | 4 +- ports/atmel-samd/common-hal/pulseio/PWMOut.c | 4 +- ports/cxd56/common-hal/analogio/AnalogIn.c | 4 +- ports/cxd56/common-hal/busio/UART.c | 4 +- ports/cxd56/common-hal/digitalio/DigitalInOut.c | 4 +- ports/cxd56/common-hal/pulseio/PWMOut.c | 8 ++-- ports/cxd56/common-hal/pulseio/PulseIn.c | 25 ++++++------ ports/mimxrt10xx/common-hal/analogio/AnalogIn.c | 4 +- ports/mimxrt10xx/common-hal/busio/UART.c | 18 ++++----- .../mimxrt10xx/common-hal/digitalio/DigitalInOut.c | 4 +- ports/nrf/boards/clue_nrf52840_express/board.c | 2 +- ports/nrf/boards/ohs2020_badge/board.c | 2 +- ports/nrf/common-hal/analogio/AnalogIn.c | 4 +- ports/nrf/common-hal/busio/SPI.c | 4 +- ports/nrf/common-hal/busio/UART.c | 14 +++---- ports/nrf/common-hal/digitalio/DigitalInOut.c | 4 +- ports/stm32f4/common-hal/analogio/AnalogIn.c | 14 +++---- ports/stm32f4/common-hal/analogio/AnalogOut.c | 4 +- ports/stm32f4/common-hal/busio/I2C.c | 18 ++++----- ports/stm32f4/common-hal/busio/SPI.c | 44 +++++++++++----------- ports/stm32f4/common-hal/busio/UART.c | 16 ++++---- ports/stm32f4/common-hal/digitalio/DigitalInOut.c | 12 +++--- ports/stm32f4/common-hal/pulseio/PWMOut.c | 16 ++++---- shared-bindings/analogio/AnalogIn.c | 9 ++--- shared-bindings/analogio/AnalogOut.c | 6 +-- shared-bindings/audiobusio/I2SOut.c | 14 ++----- shared-bindings/audiobusio/PDMIn.c | 11 +----- shared-bindings/audioio/AudioOut.c | 12 +----- shared-bindings/audiopwmio/PWMAudioOut.c | 12 +----- shared-bindings/bitbangio/I2C.c | 7 ++-- shared-bindings/bitbangio/OneWire.c | 5 +-- shared-bindings/bitbangio/SPI.c | 10 ++--- shared-bindings/busio/I2C.c | 10 ++--- shared-bindings/busio/OneWire.c | 4 +- shared-bindings/busio/SPI.c | 16 +++----- shared-bindings/busio/UART.c | 20 +++++----- shared-bindings/digitalio/DigitalInOut.c | 6 +-- shared-bindings/displayio/Display.c | 8 +--- shared-bindings/displayio/EPaperDisplay.c | 8 +--- shared-bindings/frequencyio/FrequencyIn.c | 4 +- shared-bindings/i2cslave/I2CSlave.c | 8 +--- shared-bindings/microcontroller/Pin.c | 29 +++++++++++++- shared-bindings/microcontroller/Pin.h | 6 ++- shared-bindings/ps2io/Ps2.c | 9 ++--- shared-bindings/pulseio/PWMOut.c | 5 +-- shared-bindings/pulseio/PulseIn.c | 4 +- shared-bindings/rotaryio/IncrementalEncoder.c | 9 +---- shared-bindings/touchio/TouchIn.c | 5 +-- shared-bindings/wiznet/wiznet5k.c | 6 +-- shared-module/bitbangio/SPI.c | 6 +-- shared-module/board/__init__.c | 6 +-- 65 files changed, 241 insertions(+), 299 deletions(-) (limited to 'shared-module') diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index 5d1ef6d9b..6bb2a591f 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PA01, &pin_PA00, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 40141ca15..2377f4a9d 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA12, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 85a588879..2d9b31647 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -55,7 +55,7 @@ uint8_t stop_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 1872d1876..5f5a01e48 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -97,7 +97,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA15, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PA13, &pin_PA15, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 28e1aec13..bead06f3c 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -72,7 +72,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c index fbb4441f0..061f3d777 100644 --- a/ports/atmel-samd/boards/pybadge_airlift/board.c +++ b/ports/atmel-samd/boards/pybadge_airlift/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index c052614db..70d4a05dc 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -72,7 +72,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB15, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c index a138c7e50..ff2da34a2 100644 --- a/ports/atmel-samd/boards/pygamer_advance/board.c +++ b/ports/atmel-samd/boards/pygamer_advance/board.c @@ -50,7 +50,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB12, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_PB13, &pin_PB12, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.c b/ports/atmel-samd/common-hal/analogio/AnalogIn.c index fc11d5d19..2bd218cdd 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogIn.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogIn.c @@ -73,7 +73,7 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, } bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { @@ -81,7 +81,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { return; } reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } void analogin_reset() { diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index 05a6aaf7b..99d3762cb 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -204,7 +204,7 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t* self, } bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t* self) { - return self->bit_clock == mp_const_none; + return self->bit_clock == NULL; } void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self) { @@ -213,11 +213,11 @@ void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t* self) { } reset_pin_number(self->bit_clock->number); - self->bit_clock = mp_const_none; + self->bit_clock = NULL; reset_pin_number(self->word_select->number); - self->word_select = mp_const_none; + self->word_select = NULL; reset_pin_number(self->data->number); - self->data = mp_const_none; + self->data = NULL; } void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t* self, diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c index 3a51cce8f..f70f1fec0 100644 --- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -219,7 +219,7 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t* self, } bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t* self) { - return self->clock_pin == mp_const_none; + return self->clock_pin == NULL; } void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { @@ -237,8 +237,8 @@ void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t* self) { reset_pin_number(self->clock_pin->number); reset_pin_number(self->data_pin->number); - self->clock_pin = mp_const_none; - self->data_pin = mp_const_none; + self->clock_pin = NULL; + self->data_pin = NULL; } uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t* self) { diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index b75c2b335..1d9b4cbe8 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -304,7 +304,7 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t* self, } bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t* self) { - return self->left_channel == mp_const_none; + return self->left_channel == NULL; } void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { @@ -332,10 +332,10 @@ void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t* self) { tc_set_enable(tc_insts[self->tc_index], false); reset_pin_number(self->left_channel->number); - self->left_channel = mp_const_none; + self->left_channel = NULL; #ifdef SAMD51 reset_pin_number(self->right_channel->number); - self->right_channel = mp_const_none; + self->right_channel = NULL; #endif } diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 7a1426bed..1dc389027 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -89,8 +89,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, Sercom* sercom = NULL; uint8_t sercom_index; uint32_t clock_pinmux = 0; - bool mosi_none = mosi == mp_const_none || mosi == NULL; - bool miso_none = miso == mp_const_none || miso == NULL; + bool mosi_none = mosi == NULL; + bool miso_none = miso == NULL; uint32_t mosi_pinmux = 0; uint32_t miso_pinmux = 0; uint8_t clock_pad = 0; diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index fb9968605..1f6b75f97 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -65,7 +65,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uint32_t tx_pinmux = 0; uint8_t tx_pad = 255; // Unset pad - if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert)) { + if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) { mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device")); } @@ -73,8 +73,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_raise_NotImplementedError(translate("bytes > 8 bits not supported")); } - bool have_tx = tx != mp_const_none; - bool have_rx = rx != mp_const_none; + bool have_tx = tx != NULL; + bool have_rx = rx != NULL; if (!have_tx && !have_rx) { mp_raise_ValueError(translate("tx and rx cannot both be None")); } @@ -109,7 +109,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, #endif tx_pinmux = PINMUX(tx->number, (i == 0) ? MUX_C : MUX_D); tx_pad = tx->sercom[i].pad; - if (rx == mp_const_none) { + if (rx == NULL) { sercom = potential_sercom; break; } diff --git a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c index e167cbb69..68d3da806 100644 --- a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +++ b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c @@ -55,7 +55,7 @@ void common_hal_digitalio_digitalinout_never_reset( } bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { @@ -63,7 +63,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self return; } reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } void common_hal_digitalio_digitalinout_switch_to_input( diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c index 0adb23fc5..fef581584 100644 --- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c @@ -292,7 +292,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { @@ -319,7 +319,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { } } reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { diff --git a/ports/cxd56/common-hal/analogio/AnalogIn.c b/ports/cxd56/common-hal/analogio/AnalogIn.c index e2ca5e4a4..cdf37c06a 100644 --- a/ports/cxd56/common-hal/analogio/AnalogIn.c +++ b/ports/cxd56/common-hal/analogio/AnalogIn.c @@ -83,7 +83,7 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const // start ADC ioctl(analogin_dev[self->number].fd, ANIOC_CXD56_START, 0); - + self->pin = pin; } @@ -97,7 +97,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { close(analogin_dev[self->number].fd); analogin_dev[self->number].fd = -1; - self->pin = mp_const_none; + self->pin = NULL; } bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { diff --git a/ports/cxd56/common-hal/busio/UART.c b/ports/cxd56/common-hal/busio/UART.c index 3ed980952..3bca240e0 100644 --- a/ports/cxd56/common-hal/busio/UART.c +++ b/ports/cxd56/common-hal/busio/UART.c @@ -60,10 +60,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_float_t timeout, uint16_t receiver_buffer_size) { struct termios tio; - if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert)) { + if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) { mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device")); } - + if (bits != 8) { mp_raise_ValueError(translate("Could not initialize UART")); } diff --git a/ports/cxd56/common-hal/digitalio/DigitalInOut.c b/ports/cxd56/common-hal/digitalio/DigitalInOut.c index 7b1f6cc03..c9af12e44 100644 --- a/ports/cxd56/common-hal/digitalio/DigitalInOut.c +++ b/ports/cxd56/common-hal/digitalio/DigitalInOut.c @@ -56,11 +56,11 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self board_gpio_config(self->pin->number, 0, false, true, PIN_FLOAT); reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { diff --git a/ports/cxd56/common-hal/pulseio/PWMOut.c b/ports/cxd56/common-hal/pulseio/PWMOut.c index a0b4e79c6..7e0be566b 100644 --- a/ports/cxd56/common-hal/pulseio/PWMOut.c +++ b/ports/cxd56/common-hal/pulseio/PWMOut.c @@ -50,7 +50,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t *self, const mcu_pin_obj_t *pin, uint16_t duty, uint32_t frequency, bool variable_frequency) { self->number = -1; - + for (int i = 0; i < MP_ARRAY_SIZE(pwmout_dev); i++) { if (pin->number == pwmout_dev[i].pin->number) { self->number = i; @@ -95,7 +95,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t *self) { pwmout_dev[self->number].fd = -1; reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t *self) { @@ -131,11 +131,11 @@ bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t *self void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { never_reset_pin_number(self->pin->number); - pwmout_dev[self->number].reset = false; + pwmout_dev[self->number].reset = false; } void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { - pwmout_dev[self->number].reset = true; + pwmout_dev[self->number].reset = true; } void pwmout_reset(void) { diff --git a/ports/cxd56/common-hal/pulseio/PulseIn.c b/ports/cxd56/common-hal/pulseio/PulseIn.c index dd2773d1d..65ca1d97e 100644 --- a/ports/cxd56/common-hal/pulseio/PulseIn.c +++ b/ports/cxd56/common-hal/pulseio/PulseIn.c @@ -106,7 +106,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, board_gpio_int(self->pin->number, true); } - + void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { if (common_hal_pulseio_pulsein_deinited(self)) { return; @@ -116,18 +116,18 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { board_gpio_intconfig(self->pin->number, 0, false, NULL); reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } - + bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } - + void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t *self) { board_gpio_int(self->pin->number, false); self->paused = true; } - + void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, uint16_t trigger_duration) { // Make sure we're paused. common_hal_pulseio_pulsein_pause(self); @@ -147,14 +147,14 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, uint16_t tri pulsein_set_config(self, true); board_gpio_int(self->pin->number, true); } - + void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t *self) { common_hal_mcu_disable_interrupts(); self->start = 0; self->len = 0; common_hal_mcu_enable_interrupts(); } - + uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self) { if (self->len == 0) { mp_raise_IndexError(translate("pop from an empty PulseIn")); @@ -167,19 +167,19 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self) { return value; } - + uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t *self) { return self->maxlen; } - + bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t *self) { return self->paused; } - + uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t *self) { return self->len; } - + uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t *self, int16_t index) { common_hal_mcu_disable_interrupts(); if (index < 0) { @@ -193,4 +193,3 @@ uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t *self, int16_ common_hal_mcu_enable_interrupts(); return value; } - \ No newline at end of file diff --git a/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c b/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c index d714001f3..2cc2681b4 100644 --- a/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c +++ b/ports/mimxrt10xx/common-hal/analogio/AnalogIn.c @@ -58,7 +58,7 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, } bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { @@ -66,7 +66,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { return; } reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index 4fd7afecb..b34b948b2 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -80,8 +80,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // TODO: Allow none rx or tx - bool have_tx = tx != mp_const_none; - bool have_rx = rx != mp_const_none; + bool have_tx = tx != NULL; + bool have_rx = rx != NULL; if (!have_tx && !have_rx) { mp_raise_ValueError(translate("tx and rx cannot both be None")); } @@ -116,8 +116,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, } // Filter for sane settings for RS485 - if (rs485_dir != mp_const_none) { - if ((rts != mp_const_none) || (cts != mp_const_none)) { + if (rs485_dir != NULL) { + if ((rts != NULL) || (cts != NULL)) { mp_raise_ValueError(translate("Cannot specify RTS or CTS in RS485 mode")); } // For IMXRT the RTS pin is used for RS485 direction @@ -133,7 +133,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, const uint32_t rts_count = sizeof(mcu_uart_rts_list) / sizeof(mcu_periph_obj_t); const uint32_t cts_count = sizeof(mcu_uart_cts_list) / sizeof(mcu_periph_obj_t); - if (rts != mp_const_none) { + if (rts != NULL) { for (uint32_t i=0; i < rts_count; ++i) { if (mcu_uart_rts_list[i].bank_idx == self->rx_pin->bank_idx) { if (mcu_uart_rts_list[i].pin == rts) { @@ -146,7 +146,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_raise_ValueError(translate("Selected RTS pin not valid")); } - if (cts != mp_const_none) { + if (cts != NULL) { for (uint32_t i=0; i < cts_count; ++i) { if (mcu_uart_cts_list[i].bank_idx == self->rx_pin->bank_idx) { if (mcu_uart_cts_list[i].pin == cts) { @@ -158,7 +158,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (self->cts_pin == NULL) mp_raise_ValueError(translate("Selected CTS pin not valid")); } - + self->uart = mcu_uart_banks[self->tx_pin->bank_idx - 1]; config_periph_pin(self->rx_pin); @@ -166,7 +166,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (self->rts_pin) config_periph_pin(self->rts_pin); if (self->cts_pin) - config_periph_pin(self->cts_pin); + config_periph_pin(self->cts_pin); lpuart_config_t config = { 0 }; LPUART_GetDefaultConfig(&config); @@ -187,7 +187,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, // Before we init, setup RS485 direction pin // ..unfortunately this isn't done by the driver library uint32_t modir = (self->uart->MODIR) & ~(LPUART_MODIR_TXRTSPOL_MASK | LPUART_MODIR_TXRTSE_MASK); - if (rs485_dir != mp_const_none) { + if (rs485_dir != NULL) { modir |= LPUART_MODIR_TXRTSE_MASK; if (rs485_invert) modir |= LPUART_MODIR_TXRTSPOL_MASK; diff --git a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c index d69a18d96..603515764 100644 --- a/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +++ b/ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c @@ -78,7 +78,7 @@ void common_hal_digitalio_digitalinout_never_reset( } bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { @@ -86,7 +86,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self return; } reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } void common_hal_digitalio_digitalinout_switch_to_input( diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c index 5f5337a3d..e342c6d93 100644 --- a/ports/nrf/boards/clue_nrf52840_express/board.c +++ b/ports/nrf/boards/clue_nrf52840_express/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_14, &pin_P0_15, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_P0_14, &pin_P0_15, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c index 7e3e05814..9e881d763 100644 --- a/ports/nrf/boards/ohs2020_badge/board.c +++ b/ports/nrf/boards/ohs2020_badge/board.c @@ -49,7 +49,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { busio_spi_obj_t* spi = &displays[0].fourwire_bus.inline_bus; - common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, mp_const_none); + common_hal_busio_spi_construct(spi, &pin_P0_11, &pin_P0_12, NULL); common_hal_busio_spi_never_reset(spi); displayio_fourwire_obj_t* bus = &displays[0].fourwire_bus; diff --git a/ports/nrf/common-hal/analogio/AnalogIn.c b/ports/nrf/common-hal/analogio/AnalogIn.c index 3bc097019..dbcc5281c 100644 --- a/ports/nrf/common-hal/analogio/AnalogIn.c +++ b/ports/nrf/common-hal/analogio/AnalogIn.c @@ -55,7 +55,7 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const } bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { @@ -65,7 +65,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { nrf_gpio_cfg_default(self->pin->number); reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { diff --git a/ports/nrf/common-hal/busio/SPI.c b/ports/nrf/common-hal/busio/SPI.c index b4ebddde1..3f205e778 100644 --- a/ports/nrf/common-hal/busio/SPI.c +++ b/ports/nrf/common-hal/busio/SPI.c @@ -155,7 +155,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * self->clock_pin_number = clock->number; claim_pin(clock); - if (mosi != mp_const_none) { + if (mosi != NULL) { config.mosi_pin = mosi->number; self->MOSI_pin_number = mosi->number; claim_pin(mosi); @@ -163,7 +163,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t * self->MOSI_pin_number = NO_PIN; } - if (miso != mp_const_none) { + if (miso != NULL) { config.miso_pin = miso->number; self->MISO_pin_number = mosi->number; claim_pin(miso); diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 933faf17b..14fa36374 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -135,10 +135,10 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uint32_t baudrate, uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout, uint16_t receiver_buffer_size) { - if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert)) { + if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert)) { mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device")); } - + // Find a free UART peripheral. self->uarte = NULL; for (size_t i = 0 ; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { @@ -152,7 +152,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, mp_raise_ValueError(translate("All UART peripherals are in use")); } - if ( (tx == mp_const_none) && (rx == mp_const_none) ) { + if ( (tx == NULL) && (rx == NULL) ) { mp_raise_ValueError(translate("tx and rx cannot both be None")); } @@ -165,8 +165,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, } nrfx_uarte_config_t config = { - .pseltxd = (tx == mp_const_none) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, - .pselrxd = (rx == mp_const_none) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, + .pseltxd = (tx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : tx->number, + .pselrxd = (rx == NULL) ? NRF_UARTE_PSEL_DISCONNECTED : rx->number, .pselcts = NRF_UARTE_PSEL_DISCONNECTED, .pselrts = NRF_UARTE_PSEL_DISCONNECTED, .p_context = self, @@ -181,7 +181,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, _VERIFY_ERR(nrfx_uarte_init(self->uarte, &config, uart_callback_irq)); // Init buffer for rx - if ( rx != mp_const_none ) { + if ( rx != NULL ) { // Initially allocate the UART's buffer in the long-lived part of the // heap. UARTs are generally long-lived objects, but the "make long- // lived" machinery is incapable of moving internal pointers like @@ -200,7 +200,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, claim_pin(rx); } - if ( tx != mp_const_none ) { + if ( tx != NULL ) { self->tx_pin_number = tx->number; claim_pin(tx); } else { diff --git a/ports/nrf/common-hal/digitalio/DigitalInOut.c b/ports/nrf/common-hal/digitalio/DigitalInOut.c index 0836962c6..c5a7a7dfb 100644 --- a/ports/nrf/common-hal/digitalio/DigitalInOut.c +++ b/ports/nrf/common-hal/digitalio/DigitalInOut.c @@ -46,7 +46,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( } bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) { @@ -56,7 +56,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self nrf_gpio_cfg_default(self->pin->number); reset_pin_number(self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } void common_hal_digitalio_digitalinout_switch_to_input( diff --git a/ports/stm32f4/common-hal/analogio/AnalogIn.c b/ports/stm32f4/common-hal/analogio/AnalogIn.c index 3ee3c4dbb..1d1b308b6 100644 --- a/ports/stm32f4/common-hal/analogio/AnalogIn.c +++ b/ports/stm32f4/common-hal/analogio/AnalogIn.c @@ -45,11 +45,11 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, } // TODO: add ADC traits to structure? - // Note that ADC2 is always bundled pin-to-pin with ADC1 if it exists, and used only - // for dual conversion. For this basic application it is never used. + // Note that ADC2 is always bundled pin-to-pin with ADC1 if it exists, and used only + // for dual conversion. For this basic application it is never used. LL_GPIO_SetPinMode(pin_port(pin->port), (uint32_t)pin_mask(pin->number), LL_GPIO_MODE_ANALOG); if (pin->adc_unit & 0x01) { - LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1); } else if (pin->adc_unit == 0x04) { #ifdef LL_APB2_GRP1_PERIPH_ADC3 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC3); @@ -62,7 +62,7 @@ void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, } bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { @@ -70,7 +70,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { return; } reset_pin_number(self->pin->port,self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { @@ -116,10 +116,10 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { HAL_ADC_ConfigChannel(&AdcHandle, &sConfig); HAL_ADC_Start(&AdcHandle); - HAL_ADC_PollForConversion(&AdcHandle,1); + HAL_ADC_PollForConversion(&AdcHandle,1); uint16_t value = (uint16_t)HAL_ADC_GetValue(&AdcHandle); HAL_ADC_Stop(&AdcHandle); - + // // Shift the value to be 16 bit. return value << 4; } diff --git a/ports/stm32f4/common-hal/analogio/AnalogOut.c b/ports/stm32f4/common-hal/analogio/AnalogOut.c index 79ced0492..2ea969f50 100644 --- a/ports/stm32f4/common-hal/analogio/AnalogOut.c +++ b/ports/stm32f4/common-hal/analogio/AnalogOut.c @@ -39,7 +39,7 @@ #include "stm32f4xx_hal.h" -//DAC is shared between both channels. +//DAC is shared between both channels. #if HAS_DAC DAC_HandleTypeDef handle; #endif @@ -97,7 +97,7 @@ bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { #if HAS_DAC reset_pin_number(self->pin->port,self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; dac_on[self->dac_index] = false; //turn off the DAC if both channels are off diff --git a/ports/stm32f4/common-hal/busio/I2C.c b/ports/stm32f4/common-hal/busio/I2C.c index 1437e5e78..8e98b966d 100644 --- a/ports/stm32f4/common-hal/busio/I2C.c +++ b/ports/stm32f4/common-hal/busio/I2C.c @@ -100,14 +100,14 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = self->sda->altfn_index; + GPIO_InitStruct.Alternate = self->sda->altfn_index; HAL_GPIO_Init(pin_port(sda->port), &GPIO_InitStruct); GPIO_InitStruct.Pin = pin_mask(scl->number); GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = self->scl->altfn_index; + GPIO_InitStruct.Alternate = self->scl->altfn_index; HAL_GPIO_Init(pin_port(scl->port), &GPIO_InitStruct); //Note: due to I2C soft reboot issue, do not relocate clock init. @@ -144,7 +144,7 @@ void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { } bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { - return self->sda->pin == mp_const_none; + return self->sda == NULL; } void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { @@ -158,8 +158,8 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { reset_pin_number(self->sda->pin->port,self->sda->pin->number); reset_pin_number(self->scl->pin->port,self->scl->pin->number); - self->sda = mp_const_none; - self->scl = mp_const_none; + self->sda = NULL; + self->scl = NULL; } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { @@ -169,7 +169,7 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { bool grabbed_lock = false; - //Critical section code that may be required at some point. + //Critical section code that may be required at some point. // uint32_t store_primask = __get_PRIMASK(); // __disable_irq(); // __DMB(); @@ -195,19 +195,19 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { - HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1), + HAL_StatusTypeDef result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1), (uint8_t *)data, (uint16_t)len, 500); return result == HAL_OK ? 0 : MP_EIO; } uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) + return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr<<1), data, (uint16_t)len, 500) == HAL_OK ? 0 : MP_EIO; } STATIC void i2c_clock_enable(uint8_t mask) { - //Note: hard reset required due to soft reboot issue. + //Note: hard reset required due to soft reboot issue. #ifdef I2C1 if (mask & (1 << 0)) { __HAL_RCC_I2C1_CLK_ENABLE(); diff --git a/ports/stm32f4/common-hal/busio/SPI.c b/ports/stm32f4/common-hal/busio/SPI.c index e00b5e9f0..7e25e0a57 100644 --- a/ports/stm32f4/common-hal/busio/SPI.c +++ b/ports/stm32f4/common-hal/busio/SPI.c @@ -49,7 +49,7 @@ STATIC void spi_clock_enable(uint8_t mask); STATIC void spi_clock_disable(uint8_t mask); STATIC uint32_t get_busclock(SPI_TypeDef * instance) { - //SPI2 and 3 are on PCLK1, if they exist. + //SPI2 and 3 are on PCLK1, if they exist. #ifdef SPI2 if (instance == SPI2) return HAL_RCC_GetPCLK1Freq(); #endif @@ -113,7 +113,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, for (uint i = 0; i < sck_len; i++) { if (mcu_spi_sck_list[i].pin == sck) { //if both MOSI and MISO exist, loop search normally - if ((mosi != mp_const_none) && (miso != mp_const_none)) { + if ((mosi != NULL) && (miso != NULL)) { //MOSI for (uint j = 0; j < mosi_len; j++) { if (mcu_spi_mosi_list[j].pin == mosi) { @@ -133,11 +133,11 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, self->miso = &mcu_spi_miso_list[k]; break; } - } + } } } // if just MISO, reduce search - } else if (miso != mp_const_none) { + } else if (miso != NULL) { for (uint j = 0; j < miso_len; j++) { if ((mcu_spi_miso_list[j].pin == miso) //only SCK and MISO need the same index && (mcu_spi_sck_list[i].spi_index == mcu_spi_miso_list[j].spi_index)) { @@ -152,9 +152,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, self->miso = &mcu_spi_miso_list[j]; break; } - } + } // if just MOSI, reduce search - } else if (mosi != mp_const_none) { + } else if (mosi != NULL) { for (uint j = 0; j < mosi_len; j++) { if ((mcu_spi_mosi_list[j].pin == mosi) //only SCK and MOSI need the same index && (mcu_spi_sck_list[i].spi_index == mcu_spi_mosi_list[j].spi_index)) { @@ -169,7 +169,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, self->miso = NULL; break; } - } + } } else { //throw an error immediately mp_raise_ValueError(translate("Must provide MISO or MOSI pin")); @@ -179,8 +179,8 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, //handle typedef selection, errors if ( (self->sck != NULL && self->mosi != NULL && self->miso != NULL) || - (self->sck != NULL && self->mosi != NULL && miso == mp_const_none) || - (self->sck != NULL && self->miso != NULL && mosi == mp_const_none)) { + (self->sck != NULL && self->mosi != NULL && miso == NULL) || + (self->sck != NULL && self->miso != NULL && mosi == NULL)) { SPIx = mcu_spi_banks[self->sck->spi_index - 1]; } else { if (spi_taken) { @@ -196,7 +196,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = self->sck->altfn_index; + GPIO_InitStruct.Alternate = self->sck->altfn_index; HAL_GPIO_Init(pin_port(sck->port), &GPIO_InitStruct); if (self->mosi != NULL) { @@ -204,7 +204,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = self->mosi->altfn_index; + GPIO_InitStruct.Alternate = self->mosi->altfn_index; HAL_GPIO_Init(pin_port(mosi->port), &GPIO_InitStruct); } @@ -213,14 +213,14 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = self->miso->altfn_index; + GPIO_InitStruct.Alternate = self->miso->altfn_index; HAL_GPIO_Init(pin_port(miso->port), &GPIO_InitStruct); } spi_clock_enable(1 << (self->sck->spi_index - 1)); reserved_spi[self->sck->spi_index - 1] = true; - - self->handle.Instance = SPIx; + + self->handle.Instance = SPIx; self->handle.Init.Mode = SPI_MODE_MASTER; // Direction change only required for RX-only, see RefMan RM0090:884 self->handle.Init.Direction = (self->mosi == NULL) ? SPI_CR1_RXONLY : SPI_DIRECTION_2LINES; @@ -269,7 +269,7 @@ void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { } bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { - return self->sck->pin == mp_const_none; + return self->sck->pin == NULL; } void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { @@ -287,15 +287,15 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (self->miso != NULL) { reset_pin_number(self->miso->pin->port,self->miso->pin->number); } - self->sck = mp_const_none; - self->mosi = mp_const_none; - self->miso = mp_const_none; + self->sck = NULL; + self->mosi = NULL; + self->miso = NULL; } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { //This resets the SPI, so check before updating it redundantly - if (baudrate == self->baudrate && polarity== self->polarity + if (baudrate == self->baudrate && polarity== self->polarity && phase == self->phase && bits == self->bits) { return true; } @@ -307,7 +307,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, self->handle.Init.CLKPolarity = (polarity) ? SPI_POLARITY_HIGH : SPI_POLARITY_LOW; self->handle.Init.CLKPhase = (phase) ? SPI_PHASE_2EDGE : SPI_PHASE_1EDGE; - self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler, + self->handle.Init.BaudRatePrescaler = stm32_baud_to_spi_div(baudrate, &self->prescaler, get_busclock(self->handle.Instance)); if (HAL_SPI_Init(&self->handle) != HAL_OK) @@ -325,7 +325,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { bool grabbed_lock = false; - //Critical section code that may be required at some point. + //Critical section code that may be required at some point. // uint32_t store_primask = __get_PRIMASK(); // __disable_irq(); // __DMB(); @@ -367,7 +367,7 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self, return result == HAL_OK; } -bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) { if (self->miso == NULL || self->mosi == NULL) { mp_raise_ValueError(translate("Missing MISO or MOSI Pin")); diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c index 3c1909259..0b434fd02 100644 --- a/ports/stm32f4/common-hal/busio/UART.c +++ b/ports/stm32f4/common-hal/busio/UART.c @@ -86,12 +86,12 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, bool uart_taken = false; uint8_t uart_index = 0; //origin 0 corrected - if ((rts != mp_const_none) || (cts != mp_const_none) || (rs485_dir != mp_const_none) || (rs485_invert == true)) { + if ((rts != NULL) || (cts != NULL) || (rs485_dir != NULL) || (rs485_invert == true)) { mp_raise_ValueError(translate("RTS/CTS/RS485 Not yet supported on this device")); } - + //Can have both pins, or either - if ((tx != mp_const_none) && (rx != mp_const_none)) { + if ((tx != NULL) && (rx != NULL)) { //normal find loop if both pins exist for (uint i = 0; i < tx_len; i++) { if (mcu_uart_tx_list[i].pin == tx) { @@ -115,7 +115,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uart_index = self->tx->uart_index - 1; USARTx = assign_uart_or_throw(self, (self->tx != NULL && self->rx != NULL), uart_index, uart_taken); - } else if (tx == mp_const_none) { + } else if (tx == NULL) { //If there is no tx, run only rx for (uint i = 0; i < rx_len; i++) { if (mcu_uart_rx_list[i].pin == rx) { @@ -132,7 +132,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uart_index = self->rx->uart_index - 1; USARTx = assign_uart_or_throw(self, (self->rx != NULL), uart_index, uart_taken); - } else if (rx == mp_const_none) { + } else if (rx == NULL) { //If there is no rx, run only tx for (uint i = 0; i < tx_len; i++) { if (mcu_uart_tx_list[i].pin == tx) { @@ -236,7 +236,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, } bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { - return self->tx->pin == mp_const_none; + return self->tx->pin == NULL; } void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { @@ -244,8 +244,8 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { reset_pin_number(self->tx->pin->port,self->tx->pin->number); reset_pin_number(self->rx->pin->port,self->rx->pin->number); - self->tx = mp_const_none; - self->rx = mp_const_none; + self->tx = NULL; + self->rx = NULL; gc_free(self->rbuf.buf); self->rbuf.size = 0; self->rbuf.iput = self->rbuf.iget = 0; diff --git a/ports/stm32f4/common-hal/digitalio/DigitalInOut.c b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c index 36c1075e2..be2db4dac 100644 --- a/ports/stm32f4/common-hal/digitalio/DigitalInOut.c +++ b/ports/stm32f4/common-hal/digitalio/DigitalInOut.c @@ -54,7 +54,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_construct( } bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { - return self->pin == mp_const_none; + return self->pin == NULL; } void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) { @@ -63,7 +63,7 @@ void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self } reset_pin_number(self->pin->port, self->pin->number); - self->pin = mp_const_none; + self->pin = NULL; } void common_hal_digitalio_digitalinout_switch_to_input( @@ -90,7 +90,7 @@ void common_hal_digitalio_digitalinout_switch_to_output( digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( digitalio_digitalinout_obj_t *self) { - return (LL_GPIO_GetPinMode(pin_port(self->pin->port), pin_mask(self->pin->number)) + return (LL_GPIO_GetPinMode(pin_port(self->pin->port), pin_mask(self->pin->number)) == LL_GPIO_MODE_INPUT) ? DIRECTION_INPUT : DIRECTION_OUTPUT; } @@ -111,7 +111,7 @@ void common_hal_digitalio_digitalinout_set_drive_mode( digitalio_drive_mode_t drive_mode) { GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = pin_mask(self->pin->number); - GPIO_InitStruct.Mode = (drive_mode == DRIVE_MODE_OPEN_DRAIN ? + GPIO_InitStruct.Mode = (drive_mode == DRIVE_MODE_OPEN_DRAIN ? GPIO_MODE_OUTPUT_OD : GPIO_MODE_OUTPUT_PP); GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; @@ -121,7 +121,7 @@ void common_hal_digitalio_digitalinout_set_drive_mode( digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( digitalio_digitalinout_obj_t *self) { - return LL_GPIO_GetPinOutputType(pin_port(self->pin->port), pin_mask(self->pin->number)) + return LL_GPIO_GetPinOutputType(pin_port(self->pin->port), pin_mask(self->pin->number)) == LL_GPIO_OUTPUT_OPENDRAIN ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL; } @@ -145,7 +145,7 @@ void common_hal_digitalio_digitalinout_set_pull( digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( digitalio_digitalinout_obj_t *self) { - + switch (LL_GPIO_GetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number))) { case LL_GPIO_PULL_UP: diff --git a/ports/stm32f4/common-hal/pulseio/PWMOut.c b/ports/stm32f4/common-hal/pulseio/PWMOut.c index 50bacbb51..c23fa7462 100644 --- a/ports/stm32f4/common-hal/pulseio/PWMOut.c +++ b/ports/stm32f4/common-hal/pulseio/PWMOut.c @@ -72,7 +72,7 @@ STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) { return (duty*period) / ((1 << 16) - 1); } -STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler, +STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler, uint32_t frequency, uint32_t source_freq) { //Find the largest possible period supported by this frequency for (int i = 0; i < (1 << 16); i++) { @@ -139,7 +139,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, first_time_setup = false; //skip setting up the timer } //No problems taken, so set it up - self->tim = l_tim; + self->tim = l_tim; break; } } @@ -182,7 +182,7 @@ pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, uint32_t prescaler = 0; //prescaler is 15 bit uint32_t period = 0; //period is 16 bit - timer_get_optimal_divisors(&period, &prescaler, frequency, + timer_get_optimal_divisors(&period, &prescaler, frequency, timer_get_source_freq(self->tim->tim_index)); //Timer init @@ -240,7 +240,7 @@ void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { } bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) { - return self->tim == mp_const_none; + return self->tim == NULL; } void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { @@ -255,7 +255,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { HAL_TIM_PWM_Stop(&self->handle, self->channel); } reset_pin_number(self->tim->pin->port,self->tim->pin->number); - self->tim = mp_const_none; + self->tim = NULL; //if reserved timer has no active channels, we can disable it if (!reserved_tim[self->tim->tim_index - 1]) { @@ -276,13 +276,13 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) { //don't halt setup for the same frequency - if (frequency == self->frequency) { + if (frequency == self->frequency) { return; } uint32_t prescaler = 0; uint32_t period = 0; - timer_get_optimal_divisors(&period, &prescaler, frequency, + timer_get_optimal_divisors(&period, &prescaler, frequency, timer_get_source_freq(self->tim->tim_index)); //shut down @@ -290,7 +290,7 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_ //Only change altered values self->handle.Init.Period = period - 1; - self->handle.Init.Prescaler = prescaler - 1; + self->handle.Init.Prescaler = prescaler - 1; //restart everything, adjusting for new speed if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) { diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index 9a9b525d8..9d1312dd8 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -63,16 +63,13 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, mp_arg_check_num(n_args, kw_args, 1, 1, false); // 1st argument is the pin - mp_obj_t pin_obj = args[0]; - assert_pin(pin_obj, false); + const mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t); self->base.type = &analogio_analogin_type; - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - assert_pin_free(pin); common_hal_analogio_analogin_construct(self, pin); - return (mp_obj_t) self; + return MP_OBJ_FROM_PTR(self); } //| .. method:: deinit() @@ -141,7 +138,7 @@ STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { float reference_voltage = common_hal_analogio_analogin_get_reference_voltage(self); if (reference_voltage <= 0.0f) { - return mp_const_none; + return mp_const_none; } else { return mp_obj_new_float(reference_voltage); } diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 0816da465..2496f1784 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -62,15 +62,13 @@ STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t // check arguments mp_arg_check_num(n_args, kw_args, 1, 1, false); - assert_pin(args[0], false); - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); + const mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); analogio_analogout_obj_t *self = m_new_obj(analogio_analogout_obj_t); self->base.type = &analogio_analogout_type; - assert_pin_free(pin); common_hal_analogio_analogout_construct(self, pin); - return self; + return MP_OBJ_FROM_PTR(self); } //| .. method:: deinit() diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 8f7382fde..45f703795 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -105,17 +105,9 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a 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); - mp_obj_t bit_clock_obj = args[ARG_bit_clock].u_obj; - assert_pin(bit_clock_obj, false); - const mcu_pin_obj_t *bit_clock = MP_OBJ_TO_PTR(bit_clock_obj); - - mp_obj_t word_select_obj = args[ARG_word_select].u_obj; - assert_pin(word_select_obj, false); - const mcu_pin_obj_t *word_select = MP_OBJ_TO_PTR(word_select_obj); - - mp_obj_t data_obj = args[ARG_data].u_obj; - assert_pin(data_obj, false); - const mcu_pin_obj_t *data = MP_OBJ_TO_PTR(data_obj); + const mcu_pin_obj_t *bit_clock = validate_is_free_pin(args[ARG_bit_clock].u_obj); + const mcu_pin_obj_t *word_select = validate_is_free_pin(args[ARG_word_select].u_obj); + const mcu_pin_obj_t *data = validate_is_free_pin(args[ARG_data].u_obj); audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t); self->base.type = &audiobusio_i2sout_type; diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 0c92c2478..65bc5a9d2 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -104,15 +104,8 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar 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); - mp_obj_t clock_pin_obj = args[ARG_clock_pin].u_obj; - assert_pin(clock_pin_obj, false); - const mcu_pin_obj_t *clock_pin = MP_OBJ_TO_PTR(clock_pin_obj); - assert_pin_free(clock_pin); - - mp_obj_t data_pin_obj = args[ARG_data_pin].u_obj; - assert_pin(data_pin_obj, false); - const mcu_pin_obj_t *data_pin = MP_OBJ_TO_PTR(data_pin_obj); - assert_pin_free(data_pin); + const mcu_pin_obj_t *clock_pin = validate_is_free_pin(args[ARG_clock_pin].u_obj); + const mcu_pin_obj_t *data_pin = validate_is_free_pin(args[ARG_data_pin].u_obj); // create PDMIn object from the given pin audiobusio_pdmin_obj_t *self = m_new_obj(audiobusio_pdmin_obj_t); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index eb4ef1fc6..687db22d3 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -104,16 +104,8 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar 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); - mp_obj_t left_channel_obj = args[ARG_left_channel].u_obj; - assert_pin(left_channel_obj, false); - const mcu_pin_obj_t *left_channel_pin = MP_OBJ_TO_PTR(left_channel_obj); - - mp_obj_t right_channel_obj = args[ARG_right_channel].u_obj; - const mcu_pin_obj_t *right_channel_pin = NULL; - if (right_channel_obj != mp_const_none) { - assert_pin(right_channel_obj, false); - right_channel_pin = MP_OBJ_TO_PTR(right_channel_obj); - } + const mcu_pin_obj_t *left_channel_pin = validate_is_free_pin(args[ARG_left_channel].u_obj); + const mcu_pin_obj_t *right_channel_pin = validate_is_free_pin_or_none(args[ARG_right_channel].u_obj); // create AudioOut object from the given pin audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index 60bf08500..c1c11f9cd 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -107,16 +107,8 @@ STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ 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); - mp_obj_t left_channel_obj = args[ARG_left_channel].u_obj; - assert_pin(left_channel_obj, false); - const mcu_pin_obj_t *left_channel_pin = MP_OBJ_TO_PTR(left_channel_obj); - - mp_obj_t right_channel_obj = args[ARG_right_channel].u_obj; - const mcu_pin_obj_t *right_channel_pin = NULL; - if (right_channel_obj != mp_const_none) { - assert_pin(right_channel_obj, false); - right_channel_pin = MP_OBJ_TO_PTR(right_channel_obj); - } + const mcu_pin_obj_t *left_channel_pin = validate_is_free_pin(args[ARG_left_channel].u_obj); + const mcu_pin_obj_t *right_channel_pin = validate_is_free_pin_or_none(args[ARG_right_channel].u_obj) // create AudioOut object from the given pin audiopwmio_pwmaudioout_obj_t *self = m_new_obj(audiopwmio_pwmaudioout_obj_t); diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 01a128393..bdfbfb2ca 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -63,10 +63,9 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, }; 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); - assert_pin(args[ARG_scl].u_obj, false); - assert_pin(args[ARG_sda].u_obj, false); - const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); - const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + + const mcu_pin_obj_t* scl = validate_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_is_free_pin(args[ARG_sda].u_obj); bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); self->base.type = &bitbangio_i2c_type; diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c index 73bedcd8d..20ca81c5d 100644 --- a/shared-bindings/bitbangio/OneWire.c +++ b/shared-bindings/bitbangio/OneWire.c @@ -69,9 +69,8 @@ STATIC mp_obj_t bitbangio_onewire_make_new(const mp_obj_type_t *type, size_t n_a }; 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); - assert_pin(args[ARG_pin].u_obj, false); - const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); - assert_pin_free(pin); + + const mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); bitbangio_onewire_obj_t *self = m_new_obj(bitbangio_onewire_obj_t); self->base.type = &bitbangio_onewire_type; diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 9a51bde66..462352352 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -71,12 +71,10 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, }; 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); - assert_pin(args[ARG_clock].u_obj, false); - assert_pin(args[ARG_MOSI].u_obj, true); - assert_pin(args[ARG_MISO].u_obj, true); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); + + const mcu_pin_obj_t* clock = validate_is_free_pin(args[ARG_clock].u_obj); + const mcu_pin_obj_t* mosi = validate_is_free_pin_or_none(args[ARG_MOSI].u_obj); + const mcu_pin_obj_t* miso = validate_is_free_pin_or_none(args[ARG_MISO].u_obj); bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); self->base.type = &bitbangio_spi_type; diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 50a95beb2..618a5ad32 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -76,12 +76,10 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, con }; 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); - assert_pin(args[ARG_scl].u_obj, false); - assert_pin(args[ARG_sda].u_obj, false); - const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); - assert_pin_free(scl); - const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); - assert_pin_free(sda); + + const mcu_pin_obj_t* scl = validate_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_is_free_pin(args[ARG_sda].u_obj); + common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; } diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c index aca2a3ef2..b28495096 100644 --- a/shared-bindings/busio/OneWire.c +++ b/shared-bindings/busio/OneWire.c @@ -69,9 +69,7 @@ STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, }; 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); - assert_pin(args[ARG_pin].u_obj, false); - const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); - assert_pin_free(pin); + const mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); busio_onewire_obj_t *self = m_new_obj(busio_onewire_obj_t); self->base.type = &busio_onewire_type; diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 828ffb8d0..ca84c0f24 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -89,17 +89,13 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con }; 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); - assert_pin(args[ARG_clock].u_obj, false); - assert_pin(args[ARG_MOSI].u_obj, true); - assert_pin(args[ARG_MISO].u_obj, true); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); - assert_pin_free(clock); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); - assert_pin_free(mosi); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); - assert_pin_free(miso); + + const mcu_pin_obj_t* clock = validate_is_free_pin(args[ARG_clock].u_obj); + const mcu_pin_obj_t* mosi = validate_is_free_pin_or_none(args[ARG_MOSI].u_obj); + const mcu_pin_obj_t* miso = validate_is_free_pin_or_none(args[ARG_MISO].u_obj); + common_hal_busio_spi_construct(self, clock, mosi, miso); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } //| .. method:: deinit() diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 02c5afb16..ffa50fd7d 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -105,13 +105,12 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co 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); - assert_pin(args[ARG_rx].u_obj, true); - const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj); - assert_pin_free(rx); + const mcu_pin_obj_t* rx = validate_is_free_pin_or_none(args[ARG_rx].u_obj); + const mcu_pin_obj_t* tx = validate_is_free_pin_or_none(args[ARG_tx].u_obj); - assert_pin(args[ARG_tx].u_obj, true); - const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(args[ARG_tx].u_obj); - assert_pin_free(tx); + if ( (tx == NULL) && (rx == NULL) ) { + mp_raise_ValueError(translate("tx and rx cannot both be None")); + } uint8_t bits = args[ARG_bits].u_int; if (bits < 7 || bits > 9) { @@ -133,12 +132,11 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); validate_timeout(timeout); - const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(args[ARG_rts].u_obj); - - const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(args[ARG_cts].u_obj); + const mcu_pin_obj_t* rts = validate_is_free_pin_or_none(args[ARG_rts].u_obj); + const mcu_pin_obj_t* cts = validate_is_free_pin_or_none(args[ARG_cts].u_obj); + const mcu_pin_obj_t* rs485_dir = validate_is_free_pin_or_none(args[ARG_rs485_dir].u_obj); - const mcu_pin_obj_t* rs485_dir = args[ARG_rs485_dir].u_obj; - bool rs485_invert = args[ARG_rs485_invert].u_bool; + const bool rs485_invert = args[ARG_rs485_invert].u_bool; common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, args[ARG_baudrate].u_int, bits, parity, stop, timeout, diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 16472c12c..1610c83f8 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -68,12 +68,10 @@ STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); self->base.type = &digitalio_digitalinout_type; - assert_pin(args[0], false); - mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); - assert_pin_free(pin); + mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); common_hal_digitalio_digitalinout_construct(self, pin); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } //| .. method:: deinit() diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 5759e8ad2..9fa976b86 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -141,13 +141,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - mp_obj_t backlight_pin_obj = args[ARG_backlight_pin].u_obj; - assert_pin(backlight_pin_obj, true); - const mcu_pin_obj_t* backlight_pin = NULL; - if (backlight_pin_obj != NULL && backlight_pin_obj != mp_const_none) { - backlight_pin = MP_OBJ_TO_PTR(backlight_pin_obj); - assert_pin_free(backlight_pin); - } + const mcu_pin_obj_t* backlight_pin = validate_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index 81e06f82f..60a3838a4 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -129,13 +129,7 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size mp_get_buffer_raise(args[ARG_stop_sequence].u_obj, &stop_bufinfo, MP_BUFFER_READ); - mp_obj_t busy_pin_obj = args[ARG_busy_pin].u_obj; - assert_pin(busy_pin_obj, true); - const mcu_pin_obj_t* busy_pin = NULL; - if (busy_pin_obj != NULL && busy_pin_obj != mp_const_none) { - busy_pin = MP_OBJ_TO_PTR(busy_pin_obj); - assert_pin_free(busy_pin); - } + const mcu_pin_obj_t* busy_pin = validate_is_free_pin_or_none(args[ARG_busy_pin].u_obj); mp_int_t rotation = args[ARG_rotation].u_int; if (rotation % 90 != 0) { diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index e2b924c07..349ef7e97 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -87,9 +87,7 @@ STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size 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); - assert_pin(args[ARG_pin].u_obj, false); - mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); - assert_pin_free(pin); + mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); const uint16_t capture_period = args[ARG_capture_period].u_int; diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c index c98ea52e0..b7980d517 100644 --- a/shared-bindings/i2cslave/I2CSlave.c +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -77,12 +77,8 @@ STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_ 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); - assert_pin(args[ARG_scl].u_obj, false); - assert_pin(args[ARG_sda].u_obj, false); - const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); - assert_pin_free(scl); - const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); - assert_pin_free(sda); + const mcu_pin_obj_t* scl = validate_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_is_free_pin(args[ARG_sda].u_obj); mp_obj_iter_buf_t iter_buf; mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index 3635f0afb..ef8008827 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -84,10 +84,35 @@ const mp_obj_type_t mcu_pin_type = { .print = mcu_pin_print }; -void assert_pin(mp_obj_t obj, bool none_ok) { - if ((obj != mp_const_none || !none_ok) && !MP_OBJ_IS_TYPE(obj, &mcu_pin_type)) { +mcu_pin_obj_t *validate_is_pin(mp_obj_t obj) { + if (!MP_OBJ_IS_TYPE(obj, &mcu_pin_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), mcu_pin_type.name); } + return MP_OBJ_TO_PTR(obj); +} + +// Validate that the obj is a pin or None. Return an mcu_pin_obj_t* or NULL, correspondingly. +mcu_pin_obj_t *validate_is_pin_or_none(mp_obj_t obj) { + if (obj == mp_const_none) { + return NULL; + } + return validate_is_pin(obj); +} + +mcu_pin_obj_t *validate_is_free_pin(mp_obj_t obj) { + mcu_pin_obj_t *pin = validate_is_pin(obj); + assert_pin_free(pin); + return pin; +} + +// Validate that the obj is a free pin or None. Return an mcu_pin_obj_t* or NULL, correspondingly. +mcu_pin_obj_t *validate_is_free_pin_or_none(mp_obj_t obj) { + if (obj == mp_const_none) { + return NULL; + } + mcu_pin_obj_t *pin = validate_is_pin(obj); + assert_pin_free(pin); + return pin; } void assert_pin_free(const mcu_pin_obj_t* pin) { diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 2d15dd5c5..2b4083827 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -33,7 +33,11 @@ // Type object used in Python. Should be shared between ports. extern const mp_obj_type_t mcu_pin_type; -void assert_pin(mp_obj_t obj, bool none_ok); +mcu_pin_obj_t *validate_is_pin(mp_obj_t obj); +mcu_pin_obj_t *validate_is_pin_or_none(mp_obj_t obj); +mcu_pin_obj_t *validate_is_free_pin(mp_obj_t obj); +mcu_pin_obj_t *validate_is_free_pin_or_none(mp_obj_t obj); + void assert_pin_free(const mcu_pin_obj_t* pin); bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin); diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index fb5c24b85..f5aa70907 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -77,12 +77,9 @@ STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, con }; 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); - assert_pin(args[ARG_clkpin].u_obj, false); - assert_pin(args[ARG_datapin].u_obj, false); - const mcu_pin_obj_t* clkpin = MP_OBJ_TO_PTR(args[ARG_clkpin].u_obj); - assert_pin_free(clkpin); - const mcu_pin_obj_t* datapin = MP_OBJ_TO_PTR(args[ARG_datapin].u_obj); - assert_pin_free(datapin); + + const mcu_pin_obj_t* clkpin = validate_is_free_pin(args[ARG_clkpin].u_obj); + const mcu_pin_obj_t* datapin = validate_is_free_pin(args[ARG_datapin].u_obj); ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t); self->base.type = &ps2io_ps2_type; diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index 53b88c61a..d04b469c1 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -96,10 +96,7 @@ STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); - mp_obj_t pin_obj = parsed_args[ARG_pin].u_obj; - assert_pin(pin_obj, false); - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - assert_pin_free(pin); + const mcu_pin_obj_t *pin = validate_is_free_pin(parsed_args[ARG_pin].u_obj); uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; uint32_t frequency = parsed_args[ARG_frequency].u_int; diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 8b69109f0..dbab253af 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -90,9 +90,7 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg }; 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); - assert_pin(args[ARG_pin].u_obj, false); - const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); - assert_pin_free(pin); + const mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); pulseio_pulsein_obj_t *self = m_new_obj(pulseio_pulsein_obj_t); self->base.type = &pulseio_pulsein_type; diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index f2f157847..78dccacb5 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -73,13 +73,8 @@ STATIC mp_obj_t rotaryio_incrementalencoder_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); - assert_pin(args[ARG_pin_a].u_obj, false); - const mcu_pin_obj_t* pin_a = MP_OBJ_TO_PTR(args[ARG_pin_a].u_obj); - assert_pin_free(pin_a); - - assert_pin(args[ARG_pin_b].u_obj, false); - const mcu_pin_obj_t* pin_b = MP_OBJ_TO_PTR(args[ARG_pin_b].u_obj); - assert_pin_free(pin_b); + const mcu_pin_obj_t* pin_a = validate_is_free_pin(args[ARG_pin_a].u_obj); + const mcu_pin_obj_t* pin_b = validate_is_free_pin(args[ARG_pin_b].u_obj); rotaryio_incrementalencoder_obj_t *self = m_new_obj(rotaryio_incrementalencoder_obj_t); self->base.type = &rotaryio_incrementalencoder_type; diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 33d369c74..5eadb2cc4 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -66,10 +66,7 @@ STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, mp_arg_check_num(n_args, kw_args, 1, 1, false); // 1st argument is the pin - mp_obj_t pin_obj = args[0]; - assert_pin(pin_obj, false); - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - assert_pin_free(pin); + const mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); touchio_touchin_obj_t *self = m_new_obj(touchio_touchin_obj_t); self->base.type = &touchio_touchin_type; diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index ac89cc691..1b7f76e12 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -78,10 +78,10 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, cons 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); // TODO check type of ARG_spi? - assert_pin(args[ARG_cs].u_obj, false); - assert_pin(args[ARG_rst].u_obj, true); // may be NULL + const mcu_pin_obj_t *cs = validate_is_free_pin(args[ARG_cs].u_obj); + const mcu_pin_obj_t *rst = validate_is_free_pin_or_none(args[ARG_rst].u_obj); - mp_obj_t ret = wiznet5k_create(args[ARG_spi].u_obj, args[ARG_cs].u_obj, args[ARG_rst].u_obj); + mp_obj_t ret = wiznet5k_create(args[ARG_spi].u_obj, cs, rst); if (args[ARG_dhcp].u_bool) wiznet5k_start_dhcp(); return ret; } diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index d02adf34f..e0ff1184f 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -45,7 +45,7 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, } common_hal_digitalio_digitalinout_switch_to_output(&self->clock, self->polarity == 1, DRIVE_MODE_PUSH_PULL); - if (mosi != mp_const_none) { + if (mosi != NULL) { result = common_hal_digitalio_digitalinout_construct(&self->mosi, mosi); if (result != DIGITALINOUT_OK) { common_hal_digitalio_digitalinout_deinit(&self->clock); @@ -55,12 +55,12 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, common_hal_digitalio_digitalinout_switch_to_output(&self->mosi, false, DRIVE_MODE_PUSH_PULL); } - if (miso != mp_const_none) { + if (miso != NULL) { // Starts out as input by default, no need to change. result = common_hal_digitalio_digitalinout_construct(&self->miso, miso); if (result != DIGITALINOUT_OK) { common_hal_digitalio_digitalinout_deinit(&self->clock); - if (mosi != mp_const_none) { + if (mosi != NULL) { common_hal_digitalio_digitalinout_deinit(&self->mosi); } mp_raise_ValueError(translate("MISO pin init failed.")); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index bbf177384..789318a05 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -103,12 +103,12 @@ mp_obj_t common_hal_board_create_uart(void) { #ifdef DEFAULT_UART_BUS_RTS const mcu_pin_obj_t* rts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RTS); #else - const mcu_pin_obj_t* rts = mp_const_none; + const mcu_pin_obj_t* rts = NULL; #endif #ifdef DEFAULT_UART_BUS_CTS const mcu_pin_obj_t* cts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_CTS); #else - const mcu_pin_obj_t* cts = mp_const_none; + const mcu_pin_obj_t* cts = NULL; #endif #ifdef DEFAULT_UART_IS_RS485 const mcu_pin_obj_t* rs485_dir = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RS485DIR); @@ -118,7 +118,7 @@ mp_obj_t common_hal_board_create_uart(void) { const bool rs485_invert = false; #endif #else - const mcu_pin_obj_t* rs485_dir = mp_const_none; + const mcu_pin_obj_t* rs485_dir = NULL; const bool rs485_invert = false; #endif -- cgit v1.2.3 From 817b5be320b36b9cac59b195b1c19359783fe032 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 5 Mar 2020 16:35:31 -0500 Subject: rename routines to be clearer; fix wiznet arg types --- shared-bindings/analogio/AnalogIn.c | 2 +- shared-bindings/analogio/AnalogOut.c | 2 +- shared-bindings/audiobusio/I2SOut.c | 6 +++--- shared-bindings/audiobusio/PDMIn.c | 4 ++-- shared-bindings/audioio/AudioOut.c | 4 ++-- shared-bindings/audiopwmio/PWMAudioOut.c | 4 ++-- shared-bindings/bitbangio/I2C.c | 4 ++-- shared-bindings/bitbangio/OneWire.c | 2 +- shared-bindings/bitbangio/SPI.c | 6 +++--- shared-bindings/busio/I2C.c | 4 ++-- shared-bindings/busio/OneWire.c | 2 +- shared-bindings/busio/SPI.c | 6 +++--- shared-bindings/busio/UART.c | 10 +++++----- shared-bindings/digitalio/DigitalInOut.c | 2 +- shared-bindings/displayio/Display.c | 2 +- shared-bindings/displayio/EPaperDisplay.c | 2 +- shared-bindings/displayio/FourWire.c | 6 +++--- shared-bindings/displayio/I2CDisplay.c | 2 +- shared-bindings/displayio/ParallelBus.c | 12 ++++++------ shared-bindings/frequencyio/FrequencyIn.c | 2 +- shared-bindings/i2cslave/I2CSlave.c | 4 ++-- shared-bindings/microcontroller/Pin.c | 14 +++++++------- shared-bindings/microcontroller/Pin.h | 8 ++++---- shared-bindings/ps2io/Ps2.c | 4 ++-- shared-bindings/pulseio/PWMOut.c | 2 +- shared-bindings/pulseio/PulseIn.c | 2 +- shared-bindings/rotaryio/IncrementalEncoder.c | 4 ++-- shared-bindings/touchio/TouchIn.c | 2 +- shared-bindings/wiznet/wiznet5k.c | 4 ++-- shared-module/wiznet/wiznet5k.c | 4 ++-- shared-module/wiznet/wiznet5k.h | 2 +- 31 files changed, 67 insertions(+), 67 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index 9d1312dd8..b4eeb2af1 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -63,7 +63,7 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, mp_arg_check_num(n_args, kw_args, 1, 1, false); // 1st argument is the pin - const mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t); self->base.type = &analogio_analogin_type; diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 2496f1784..89cf147b2 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -62,7 +62,7 @@ STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t // check arguments mp_arg_check_num(n_args, kw_args, 1, 1, false); - const mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); analogio_analogout_obj_t *self = m_new_obj(analogio_analogout_obj_t); self->base.type = &analogio_analogout_type; diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 45f703795..cd662acb5 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -105,9 +105,9 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a 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); - const mcu_pin_obj_t *bit_clock = validate_is_free_pin(args[ARG_bit_clock].u_obj); - const mcu_pin_obj_t *word_select = validate_is_free_pin(args[ARG_word_select].u_obj); - const mcu_pin_obj_t *data = validate_is_free_pin(args[ARG_data].u_obj); + const mcu_pin_obj_t *bit_clock = validate_obj_is_free_pin(args[ARG_bit_clock].u_obj); + const mcu_pin_obj_t *word_select = validate_obj_is_free_pin(args[ARG_word_select].u_obj); + const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj); audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t); self->base.type = &audiobusio_i2sout_type; diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 65bc5a9d2..fce6cf7a2 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -104,8 +104,8 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar 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); - const mcu_pin_obj_t *clock_pin = validate_is_free_pin(args[ARG_clock_pin].u_obj); - const mcu_pin_obj_t *data_pin = validate_is_free_pin(args[ARG_data_pin].u_obj); + const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj); + const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj); // create PDMIn object from the given pin audiobusio_pdmin_obj_t *self = m_new_obj(audiobusio_pdmin_obj_t); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 687db22d3..ea1efcdff 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -104,8 +104,8 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar 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); - const mcu_pin_obj_t *left_channel_pin = validate_is_free_pin(args[ARG_left_channel].u_obj); - const mcu_pin_obj_t *right_channel_pin = validate_is_free_pin_or_none(args[ARG_right_channel].u_obj); + const mcu_pin_obj_t *left_channel_pin = validate_obj_is_free_pin(args[ARG_left_channel].u_obj); + const mcu_pin_obj_t *right_channel_pin = validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj); // create AudioOut object from the given pin audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index ab1d9c9fc..9fa2b1578 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -107,8 +107,8 @@ STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ 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); - const mcu_pin_obj_t *left_channel_pin = validate_is_free_pin(args[ARG_left_channel].u_obj); - const mcu_pin_obj_t *right_channel_pin = validate_is_free_pin_or_none(args[ARG_right_channel].u_obj); + const mcu_pin_obj_t *left_channel_pin = validate_obj_is_free_pin(args[ARG_left_channel].u_obj); + const mcu_pin_obj_t *right_channel_pin = validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj); // create AudioOut object from the given pin audiopwmio_pwmaudioout_obj_t *self = m_new_obj(audiopwmio_pwmaudioout_obj_t); diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index bdfbfb2ca..3c4f13777 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -64,8 +64,8 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, 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); - const mcu_pin_obj_t* scl = validate_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t* sda = validate_is_free_pin(args[ARG_sda].u_obj); + const mcu_pin_obj_t* scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); self->base.type = &bitbangio_i2c_type; diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c index 20ca81c5d..95bbd0679 100644 --- a/shared-bindings/bitbangio/OneWire.c +++ b/shared-bindings/bitbangio/OneWire.c @@ -70,7 +70,7 @@ STATIC mp_obj_t bitbangio_onewire_make_new(const mp_obj_type_t *type, size_t n_a 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); - const mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); bitbangio_onewire_obj_t *self = m_new_obj(bitbangio_onewire_obj_t); self->base.type = &bitbangio_onewire_type; diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 462352352..b1a94c184 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -72,9 +72,9 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, 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); - const mcu_pin_obj_t* clock = validate_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t* mosi = validate_is_free_pin_or_none(args[ARG_MOSI].u_obj); - const mcu_pin_obj_t* miso = validate_is_free_pin_or_none(args[ARG_MISO].u_obj); + const mcu_pin_obj_t* clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); + const mcu_pin_obj_t* mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj); + const mcu_pin_obj_t* miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj); bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); self->base.type = &bitbangio_spi_type; diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 618a5ad32..c89215acd 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -77,8 +77,8 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, con 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); - const mcu_pin_obj_t* scl = validate_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t* sda = validate_is_free_pin(args[ARG_sda].u_obj); + const mcu_pin_obj_t* scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c index b28495096..022d6afcf 100644 --- a/shared-bindings/busio/OneWire.c +++ b/shared-bindings/busio/OneWire.c @@ -69,7 +69,7 @@ STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, }; 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); - const mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); busio_onewire_obj_t *self = m_new_obj(busio_onewire_obj_t); self->base.type = &busio_onewire_type; diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index ca84c0f24..043c1089d 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -90,9 +90,9 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con 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); - const mcu_pin_obj_t* clock = validate_is_free_pin(args[ARG_clock].u_obj); - const mcu_pin_obj_t* mosi = validate_is_free_pin_or_none(args[ARG_MOSI].u_obj); - const mcu_pin_obj_t* miso = validate_is_free_pin_or_none(args[ARG_MISO].u_obj); + const mcu_pin_obj_t* clock = validate_obj_is_free_pin(args[ARG_clock].u_obj); + const mcu_pin_obj_t* mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj); + const mcu_pin_obj_t* miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj); common_hal_busio_spi_construct(self, clock, mosi, miso); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index ffa50fd7d..f231924d5 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -105,8 +105,8 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co 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); - const mcu_pin_obj_t* rx = validate_is_free_pin_or_none(args[ARG_rx].u_obj); - const mcu_pin_obj_t* tx = validate_is_free_pin_or_none(args[ARG_tx].u_obj); + const mcu_pin_obj_t* rx = validate_obj_is_free_pin_or_none(args[ARG_rx].u_obj); + const mcu_pin_obj_t* tx = validate_obj_is_free_pin_or_none(args[ARG_tx].u_obj); if ( (tx == NULL) && (rx == NULL) ) { mp_raise_ValueError(translate("tx and rx cannot both be None")); @@ -132,9 +132,9 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); validate_timeout(timeout); - const mcu_pin_obj_t* rts = validate_is_free_pin_or_none(args[ARG_rts].u_obj); - const mcu_pin_obj_t* cts = validate_is_free_pin_or_none(args[ARG_cts].u_obj); - const mcu_pin_obj_t* rs485_dir = validate_is_free_pin_or_none(args[ARG_rs485_dir].u_obj); + const mcu_pin_obj_t* rts = validate_obj_is_free_pin_or_none(args[ARG_rts].u_obj); + const mcu_pin_obj_t* cts = validate_obj_is_free_pin_or_none(args[ARG_cts].u_obj); + const mcu_pin_obj_t* rs485_dir = validate_obj_is_free_pin_or_none(args[ARG_rs485_dir].u_obj); const bool rs485_invert = args[ARG_rs485_invert].u_bool; diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 1610c83f8..39da00cf7 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -68,7 +68,7 @@ STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); self->base.type = &digitalio_digitalinout_type; - mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); + mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); common_hal_digitalio_digitalinout_construct(self, pin); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 9fa976b86..991c828be 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -141,7 +141,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - const mcu_pin_obj_t* backlight_pin = validate_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); + const mcu_pin_obj_t* backlight_pin = validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index 60a3838a4..25a4a41e9 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -129,7 +129,7 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size mp_get_buffer_raise(args[ARG_stop_sequence].u_obj, &stop_bufinfo, MP_BUFFER_READ); - const mcu_pin_obj_t* busy_pin = validate_is_free_pin_or_none(args[ARG_busy_pin].u_obj); + const mcu_pin_obj_t* busy_pin = validate_obj_is_free_pin_or_none(args[ARG_busy_pin].u_obj); mp_int_t rotation = args[ARG_rotation].u_int; if (rotation % 90 != 0) { diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index f013cc18f..2cbceec48 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -73,9 +73,9 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ 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); - mcu_pin_obj_t *command = validate_is_free_pin(args[ARG_command].u_obj); - mcu_pin_obj_t *chip_select = validate_is_free_pin(args[ARG_chip_select].u_obj); - mcu_pin_obj_t *reset = validate_is_free_pin_or_none(args[ARG_reset].u_obj); + mcu_pin_obj_t *command = validate_obj_is_free_pin(args[ARG_command].u_obj); + mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); + mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index 03779fba9..2e312aa14 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -69,7 +69,7 @@ STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t 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); - mcu_pin_obj_t *reset = validate_is_free_pin_or_none(args[ARG_reset].u_obj); + mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); displayio_i2cdisplay_obj_t* self = NULL; mp_obj_t i2c = args[ARG_i2c_bus].u_obj; diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index 33a165af9..ea1753f31 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -76,12 +76,12 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t 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); - mcu_pin_obj_t *data0 = validate_is_free_pin(args[ARG_data0].u_obj); - mcu_pin_obj_t *command = validate_is_free_pin(args[ARG_command].u_obj); - mcu_pin_obj_t *chip_select = validate_is_free_pin(args[ARG_chip_select].u_obj); - mcu_pin_obj_t *write = validate_is_free_pin(args[ARG_write].u_obj); - mcu_pin_obj_t *read = validate_is_free_pin(args[ARG_read].u_obj); - mcu_pin_obj_t *reset = validate_is_free_pin(args[ARG_reset].u_obj); + mcu_pin_obj_t *data0 = validate_obj_is_free_pin(args[ARG_data0].u_obj); + mcu_pin_obj_t *command = validate_obj_is_free_pin(args[ARG_command].u_obj); + mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); + mcu_pin_obj_t *write = validate_obj_is_free_pin(args[ARG_write].u_obj); + mcu_pin_obj_t *read = validate_obj_is_free_pin(args[ARG_read].u_obj); + mcu_pin_obj_t *reset = validate_obj_is_free_pin(args[ARG_reset].u_obj); displayio_parallelbus_obj_t* self = NULL; for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index 349ef7e97..6743f8706 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -87,7 +87,7 @@ STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size 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); - mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); + mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); const uint16_t capture_period = args[ARG_capture_period].u_int; diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c index b7980d517..e28eb3f25 100644 --- a/shared-bindings/i2cslave/I2CSlave.c +++ b/shared-bindings/i2cslave/I2CSlave.c @@ -77,8 +77,8 @@ STATIC mp_obj_t i2cslave_i2c_slave_make_new(const mp_obj_type_t *type, size_t n_ 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); - const mcu_pin_obj_t* scl = validate_is_free_pin(args[ARG_scl].u_obj); - const mcu_pin_obj_t* sda = validate_is_free_pin(args[ARG_sda].u_obj); + const mcu_pin_obj_t* scl = validate_obj_is_free_pin(args[ARG_scl].u_obj); + const mcu_pin_obj_t* sda = validate_obj_is_free_pin(args[ARG_sda].u_obj); mp_obj_iter_buf_t iter_buf; mp_obj_t iterable = mp_getiter(args[ARG_addresses].u_obj, &iter_buf); diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index ef8008827..67aecaf66 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -84,7 +84,7 @@ const mp_obj_type_t mcu_pin_type = { .print = mcu_pin_print }; -mcu_pin_obj_t *validate_is_pin(mp_obj_t obj) { +mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj) { if (!MP_OBJ_IS_TYPE(obj, &mcu_pin_type)) { mp_raise_TypeError_varg(translate("Expected a %q"), mcu_pin_type.name); } @@ -92,25 +92,25 @@ mcu_pin_obj_t *validate_is_pin(mp_obj_t obj) { } // Validate that the obj is a pin or None. Return an mcu_pin_obj_t* or NULL, correspondingly. -mcu_pin_obj_t *validate_is_pin_or_none(mp_obj_t obj) { +mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj) { if (obj == mp_const_none) { return NULL; } - return validate_is_pin(obj); + return validate_obj_is_pin(obj); } -mcu_pin_obj_t *validate_is_free_pin(mp_obj_t obj) { - mcu_pin_obj_t *pin = validate_is_pin(obj); +mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj) { + mcu_pin_obj_t *pin = validate_obj_is_pin(obj); assert_pin_free(pin); return pin; } // Validate that the obj is a free pin or None. Return an mcu_pin_obj_t* or NULL, correspondingly. -mcu_pin_obj_t *validate_is_free_pin_or_none(mp_obj_t obj) { +mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj) { if (obj == mp_const_none) { return NULL; } - mcu_pin_obj_t *pin = validate_is_pin(obj); + mcu_pin_obj_t *pin = validate_obj_is_pin(obj); assert_pin_free(pin); return pin; } diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 2b4083827..4f29322a0 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -33,10 +33,10 @@ // Type object used in Python. Should be shared between ports. extern const mp_obj_type_t mcu_pin_type; -mcu_pin_obj_t *validate_is_pin(mp_obj_t obj); -mcu_pin_obj_t *validate_is_pin_or_none(mp_obj_t obj); -mcu_pin_obj_t *validate_is_free_pin(mp_obj_t obj); -mcu_pin_obj_t *validate_is_free_pin_or_none(mp_obj_t obj); +mcu_pin_obj_t *validate_obj_is_pin(mp_obj_t obj); +mcu_pin_obj_t *validate_obj_is_pin_or_none(mp_obj_t obj); +mcu_pin_obj_t *validate_obj_is_free_pin(mp_obj_t obj); +mcu_pin_obj_t *validate_obj_is_free_pin_or_none(mp_obj_t obj); void assert_pin_free(const mcu_pin_obj_t* pin); diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index f5aa70907..89ed0a76c 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -78,8 +78,8 @@ STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, con 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); - const mcu_pin_obj_t* clkpin = validate_is_free_pin(args[ARG_clkpin].u_obj); - const mcu_pin_obj_t* datapin = validate_is_free_pin(args[ARG_datapin].u_obj); + const mcu_pin_obj_t* clkpin = validate_obj_is_free_pin(args[ARG_clkpin].u_obj); + const mcu_pin_obj_t* datapin = validate_obj_is_free_pin(args[ARG_datapin].u_obj); ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t); self->base.type = &ps2io_ps2_type; diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c index d04b469c1..2491a5c3f 100644 --- a/shared-bindings/pulseio/PWMOut.c +++ b/shared-bindings/pulseio/PWMOut.c @@ -96,7 +96,7 @@ STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); - const mcu_pin_obj_t *pin = validate_is_free_pin(parsed_args[ARG_pin].u_obj); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(parsed_args[ARG_pin].u_obj); uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; uint32_t frequency = parsed_args[ARG_frequency].u_int; diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index dbab253af..6c01a4c17 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -90,7 +90,7 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg }; 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); - const mcu_pin_obj_t* pin = validate_is_free_pin(args[ARG_pin].u_obj); + const mcu_pin_obj_t* pin = validate_obj_is_free_pin(args[ARG_pin].u_obj); pulseio_pulsein_obj_t *self = m_new_obj(pulseio_pulsein_obj_t); self->base.type = &pulseio_pulsein_type; diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index 78dccacb5..058241d24 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -73,8 +73,8 @@ STATIC mp_obj_t rotaryio_incrementalencoder_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); - const mcu_pin_obj_t* pin_a = validate_is_free_pin(args[ARG_pin_a].u_obj); - const mcu_pin_obj_t* pin_b = validate_is_free_pin(args[ARG_pin_b].u_obj); + const mcu_pin_obj_t* pin_a = validate_obj_is_free_pin(args[ARG_pin_a].u_obj); + const mcu_pin_obj_t* pin_b = validate_obj_is_free_pin(args[ARG_pin_b].u_obj); rotaryio_incrementalencoder_obj_t *self = m_new_obj(rotaryio_incrementalencoder_obj_t); self->base.type = &rotaryio_incrementalencoder_type; diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 5eadb2cc4..db53ec1bc 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -66,7 +66,7 @@ STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, mp_arg_check_num(n_args, kw_args, 1, 1, false); // 1st argument is the pin - const mcu_pin_obj_t *pin = validate_is_free_pin(args[0]); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0]); touchio_touchin_obj_t *self = m_new_obj(touchio_touchin_obj_t); self->base.type = &touchio_touchin_type; diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c index 1b7f76e12..786978bfe 100644 --- a/shared-bindings/wiznet/wiznet5k.c +++ b/shared-bindings/wiznet/wiznet5k.c @@ -78,8 +78,8 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, cons 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); // TODO check type of ARG_spi? - const mcu_pin_obj_t *cs = validate_is_free_pin(args[ARG_cs].u_obj); - const mcu_pin_obj_t *rst = validate_is_free_pin_or_none(args[ARG_rst].u_obj); + const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj); + const mcu_pin_obj_t *rst = validate_obj_is_free_pin_or_none(args[ARG_rst].u_obj); mp_obj_t ret = wiznet5k_create(args[ARG_spi].u_obj, cs, rst); if (args[ARG_dhcp].u_bool) wiznet5k_start_dhcp(); diff --git a/shared-module/wiznet/wiznet5k.c b/shared-module/wiznet/wiznet5k.c index 3c5c5f0c8..a603a5593 100644 --- a/shared-module/wiznet/wiznet5k.c +++ b/shared-module/wiznet/wiznet5k.c @@ -379,12 +379,12 @@ void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket) { } /// Create and return a WIZNET5K object. -mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in) { +mp_obj_t wiznet5k_create(busio_spi_obj_t *spi_in, const mcu_pin_obj_t *cs_in, const mcu_pin_obj_t *rst_in) { // init the wiznet5k object wiznet5k_obj.base.type = (mp_obj_type_t*)&mod_network_nic_type_wiznet5k; wiznet5k_obj.cris_state = 0; - wiznet5k_obj.spi = MP_OBJ_TO_PTR(spi_in); + wiznet5k_obj.spi = spi_in; wiznet5k_obj.socket_used = 0; wiznet5k_obj.dhcp_socket = -1; diff --git a/shared-module/wiznet/wiznet5k.h b/shared-module/wiznet/wiznet5k.h index 0154831c7..19823ae55 100644 --- a/shared-module/wiznet/wiznet5k.h +++ b/shared-module/wiznet/wiznet5k.h @@ -59,7 +59,7 @@ int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, m void wiznet5k_socket_timer_tick(mod_network_socket_obj_t *socket); void wiznet5k_socket_deinit(mod_network_socket_obj_t *socket); mp_obj_t wiznet5k_socket_disconnect(mp_obj_t self_in); -mp_obj_t wiznet5k_create(mp_obj_t spi_in, mp_obj_t cs_in, mp_obj_t rst_in); +mp_obj_t wiznet5k_create(busio_spi_obj_t *spi_in, const mcu_pin_obj_t *cs_in, const mcu_pin_obj_t *rst_in); int wiznet5k_start_dhcp(void); int wiznet5k_stop_dhcp(void); -- cgit v1.2.3 From 310f2ccdf4c07bb2c99d7cbe9bc627299f1f3a3e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 16 Mar 2020 10:09:46 -0500 Subject: Pixelbuf: subscr: Get correct pixel value Previously, the 0th pixel's value was always returned --- shared-module/_pixelbuf/PixelBuf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-module') diff --git a/shared-module/_pixelbuf/PixelBuf.c b/shared-module/_pixelbuf/PixelBuf.c index bad8539ea..31350b875 100644 --- a/shared-module/_pixelbuf/PixelBuf.c +++ b/shared-module/_pixelbuf/PixelBuf.c @@ -243,6 +243,7 @@ mp_obj_t common_hal__pixelbuf_pixelbuf_get_pixel(mp_obj_t self_in, size_t index) if (self->pre_brightness_buffer != NULL) { pixel_buffer = self->pre_brightness_buffer; } + pixel_buffer += self->byteorder.bpp * index; pixelbuf_rgbw_t *rgbw_order = &self->byteorder.byteorder; elems[0] = MP_OBJ_NEW_SMALL_INT(pixel_buffer[rgbw_order->r]); -- cgit v1.2.3 From 6b7acc65b655dd203b08b2d53f08ad56c7da1041 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 25 Mar 2020 11:22:46 -0700 Subject: Add polarity and phase to FourWire. It was fixed as 0/0 even though it used to get it from the current SPI state. This makes it more explicit with kwargs. Thanks to magpie_lark and kmatocha on the Adafruit Support forum for finding the issue: https://forums.adafruit.com/viewtopic.php?f=60&t=162515 --- shared-bindings/displayio/FourWire.c | 21 ++++++++++++++++++--- shared-bindings/displayio/FourWire.h | 3 ++- shared-module/displayio/FourWire.c | 7 ++++--- 3 files changed, 24 insertions(+), 7 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 2cbceec48..9ce08283b 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -46,7 +46,8 @@ //| Manage updating a display over SPI four wire protocol in the background while Python code runs. //| It doesn't handle display initialization. //| -//| .. class:: FourWire(spi_bus, *, command, chip_select, reset=None, baudrate=24000000) +//| .. class:: FourWire(spi_bus, *, command, chip_select, reset=None, baudrate=24000000, polarity=0, +//| phase=0) //| //| Create a FourWire object associated with the given pins. //| @@ -60,15 +61,20 @@ //| :param microcontroller.Pin chip_select: Chip select pin //| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used //| :param int baudrate: Maximum baudrate in Hz for the display on the bus +//| :param int polarity: the base state of the clock line (0 or 1) +//| :param int phase: the edge of the clock that data is captured. First (0) +//| or second (1). Rising or falling depends on clock polarity. //| STATIC mp_obj_t displayio_fourwire_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_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate }; + enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate, ARG_polarity, ARG_phase }; static const mp_arg_t allowed_args[] = { { MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_baudrate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 24000000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; 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); @@ -91,8 +97,17 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mp_raise_RuntimeError(translate("Too many display busses")); } + uint8_t polarity = args[ARG_polarity].u_int; + if (polarity != 0 && polarity != 1) { + mp_raise_ValueError(translate("Invalid polarity")); + } + uint8_t phase = args[ARG_phase].u_int; + if (phase != 0 && phase != 1) { + mp_raise_ValueError(translate("Invalid phase")); + } + common_hal_displayio_fourwire_construct(self, - MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int); + MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int, polarity, phase); return self; } diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index d0935f063..ac186d2c3 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -38,7 +38,8 @@ extern const mp_obj_type_t displayio_fourwire_type; void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, busio_spi_obj_t* spi, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate); + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate, + uint8_t polarity, uint8_t phase); void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c index 256c29642..fe7234aa7 100644 --- a/shared-module/displayio/FourWire.c +++ b/shared-module/displayio/FourWire.c @@ -40,7 +40,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, busio_spi_obj_t* spi, const mcu_pin_obj_t* command, - const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate) { + const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate, + uint8_t polarity, uint8_t phase) { self->bus = spi; common_hal_busio_spi_never_reset(self->bus); @@ -49,8 +50,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, gc_never_free(self->bus); self->frequency = baudrate; - self->polarity = 0; - self->phase = 0; + self->polarity = polarity; + self->phase = phase; common_hal_digitalio_digitalinout_construct(&self->command, command); common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); -- cgit v1.2.3 From 9e0c00dfd42504a53f000da374355829da7c7c77 Mon Sep 17 00:00:00 2001 From: siddacious Date: Wed, 25 Mar 2020 22:43:18 -0700 Subject: adding a backlight polarity flag to Display --- ports/atmel-samd/boards/hallowing_m0_express/board.c | 3 ++- ports/atmel-samd/boards/hallowing_m4_express/board.c | 3 ++- ports/atmel-samd/boards/monster_m4sk/board.c | 3 ++- ports/atmel-samd/boards/pewpew_m4/board.c | 3 ++- ports/atmel-samd/boards/pybadge/board.c | 3 ++- ports/atmel-samd/boards/pybadge_airlift/board.c | 3 ++- ports/atmel-samd/boards/pygamer/board.c | 3 ++- ports/atmel-samd/boards/pygamer_advance/board.c | 3 ++- ports/atmel-samd/boards/pyportal/board.c | 3 ++- ports/atmel-samd/boards/pyportal_titano/board.c | 3 ++- ports/atmel-samd/boards/ugame10/board.c | 3 ++- ports/nrf/boards/clue_nrf52840_express/board.c | 3 ++- ports/nrf/boards/ohs2020_badge/board.c | 11 +++++------ ports/stm/boards/meowbit_v121/board.c | 3 ++- shared-bindings/displayio/Display.c | 7 +++++-- shared-bindings/displayio/Display.h | 2 +- shared-module/displayio/Display.c | 5 ++++- shared-module/displayio/Display.h | 1 + 18 files changed, 42 insertions(+), 23 deletions(-) (limited to 'shared-module') diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index b4c54062f..07546abf5 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -108,7 +108,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index 6bb2a591f..6822368d7 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -88,7 +88,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 2377f4a9d..eeafdb4b8 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -89,7 +89,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 5f5a01e48..ef259e27a 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -139,7 +139,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands false, // auto_refresh - 20); // native_frames_per_second + 20, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index bead06f3c..1209c027e 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -111,7 +111,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c index 061f3d777..dfbf7023f 100644 --- a/ports/atmel-samd/boards/pybadge_airlift/board.c +++ b/ports/atmel-samd/boards/pybadge_airlift/board.c @@ -89,7 +89,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 70d4a05dc..6df485fa9 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -111,7 +111,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c index ff2da34a2..ad5abd3f6 100644 --- a/ports/atmel-samd/boards/pygamer_advance/board.c +++ b/ports/atmel-samd/boards/pygamer_advance/board.c @@ -89,7 +89,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index 2a7289778..a86f0ee48 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -100,7 +100,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c index 828ceebc4..a9ded1760 100644 --- a/ports/atmel-samd/boards/pyportal_titano/board.c +++ b/ports/atmel-samd/boards/pyportal_titano/board.c @@ -117,7 +117,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index ce389a2b1..96f2361fd 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -108,7 +108,8 @@ void board_init(void) { false, // single_byte_bounds false, // data as commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c index e342c6d93..03b212f9e 100644 --- a/ports/nrf/boards/clue_nrf52840_express/board.c +++ b/ports/nrf/boards/clue_nrf52840_express/board.c @@ -88,7 +88,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c index c777d707a..106bbd6e1 100644 --- a/ports/nrf/boards/ohs2020_badge/board.c +++ b/ports/nrf/boards/ohs2020_badge/board.c @@ -81,16 +81,15 @@ void board_init(void) { 0x37, // set vertical scroll command display_init_sequence, sizeof(display_init_sequence), - //NULL, // backlight pin - &pin_P0_02, // backlight pin + &pin_P0_02, // backlight pin NO_BRIGHTNESS_COMMAND, - 0.0f, // brightness (ignored) - false, // auto_brightness + 1.0f, // brightness (ignored) + true, // auto_brightness false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second - + 60, // native_frames_per_second + false); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index a0ae98824..da87f00ec 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -109,7 +109,8 @@ void board_init(void) { false, // single_byte_bounds false, // data_as_commands true, // auto_refresh - 60); // native_frames_per_second + 60, // native_frames_per_second + true); // backlight_on_high } bool board_requests_safe_mode(void) { diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 991c828be..3ef7e74e9 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -104,9 +104,10 @@ //| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this. //| :param bool auto_refresh: Automatically refresh the screen //| :param int native_frames_per_second: Number of display refreshes per second that occur with the given init_sequence. +//| :param bool backlight_on_high: If True, pulling the backlight pin high turns the backlight on. //| STATIC mp_obj_t displayio_display_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_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second }; + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -132,6 +133,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_data_as_commands, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, + { MP_QSTR_backlight_on_high, 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); @@ -178,7 +180,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a args[ARG_single_byte_bounds].u_bool, args[ARG_data_as_commands].u_bool, args[ARG_auto_refresh].u_bool, - args[ARG_native_frames_per_second].u_int + args[ARG_native_frames_per_second].u_int, + args[ARG_backlight_on_high].u_bool ); return self; diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index b82a68ebe..8c2e20262 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -45,7 +45,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, - bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second); + bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second, bool backlight_on_high); bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group); diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 299c8ad35..820fbcce6 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -50,7 +50,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, - bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second) { + bool single_byte_bounds, bool data_as_commands, bool auto_refresh, uint16_t native_frames_per_second, bool backlight_on_high) { // Turn off auto-refresh as we init. self->auto_refresh = false; uint16_t ram_width = 0x100; @@ -159,6 +159,9 @@ mp_float_t common_hal_displayio_display_get_brightness(displayio_display_obj_t* bool common_hal_displayio_display_set_brightness(displayio_display_obj_t* self, mp_float_t brightness) { self->updating_backlight = true; + if (!self->backlight_on_high){ + brightness = 1.0-brightness; + } bool ok = false; if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); diff --git a/shared-module/displayio/Display.h b/shared-module/displayio/Display.h index e5fe0a708..8adaf597f 100644 --- a/shared-module/displayio/Display.h +++ b/shared-module/displayio/Display.h @@ -55,6 +55,7 @@ typedef struct { bool data_as_commands; bool auto_brightness; bool updating_backlight; + bool backlight_on_high; } displayio_display_obj_t; void displayio_display_background(displayio_display_obj_t* self); -- cgit v1.2.3 From 4ee6754ccd531bb50e059e9a4d962dee5c93bae3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 8 Apr 2020 10:32:54 -0700 Subject: Save backlight_on_high correctly. Fixes #2750 --- shared-module/displayio/Display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'shared-module') diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 820fbcce6..2edded927 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -69,6 +69,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, self->auto_brightness = auto_brightness; self->first_manual_refresh = !auto_refresh; self->data_as_commands = data_as_commands; + self->backlight_on_high = backlight_on_high; self->native_frames_per_second = native_frames_per_second; self->native_ms_per_frame = 1000 / native_frames_per_second; -- cgit v1.2.3 From 49fff2d9b47a51e0f2f600602aaa2fddc234b4be Mon Sep 17 00:00:00 2001 From: caternuson Date: Thu, 9 Apr 2020 08:37:07 -0700 Subject: initial working fill --- shared-bindings/displayio/Bitmap.c | 19 +++++++++++++++++++ shared-bindings/displayio/Bitmap.h | 1 + shared-module/displayio/Bitmap.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) (limited to 'shared-module') diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 91c17f2d1..48d04c215 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -178,9 +178,28 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } +//| .. method:: fill() +//| +//| Fills the bitmap. +//| +STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) { + displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); + + mp_int_t value = mp_obj_get_int(value_obj); + if (value >= 1 << common_hal_displayio_bitmap_get_bits_per_value(self)) { + mp_raise_ValueError(translate("pixel value requires too many bits")); + } + common_hal_displayio_bitmap_fill(self, value); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(displayio_bitmap_fill_obj, displayio_bitmap_obj_fill); + STATIC const mp_rom_map_elem_t displayio_bitmap_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_bitmap_height_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_bitmap_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&displayio_bitmap_fill_obj) }, + }; STATIC MP_DEFINE_CONST_DICT(displayio_bitmap_locals_dict, displayio_bitmap_locals_dict_table); diff --git a/shared-bindings/displayio/Bitmap.h b/shared-bindings/displayio/Bitmap.h index 90694951f..46c337329 100644 --- a/shared-bindings/displayio/Bitmap.h +++ b/shared-bindings/displayio/Bitmap.h @@ -41,5 +41,6 @@ uint16_t common_hal_displayio_bitmap_get_width(displayio_bitmap_t *self); uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self); void common_hal_displayio_bitmap_set_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y, uint32_t value); uint32_t common_hal_displayio_bitmap_get_pixel(displayio_bitmap_t *bitmap, int16_t x, int16_t y); +void common_hal_displayio_bitmap_fill(displayio_bitmap_t *bitmap, uint32_t value); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BITMAP_H diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 59971d25c..2b0165f2f 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -162,3 +162,35 @@ void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { self->dirty_area.x1 = 0; self->dirty_area.x2 = 0; } + +void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { + + for (uint32_t x=0; xwidth; x++) { + for (uint32_t y=0; yheight; y++) { + int32_t row_start = y * self->stride; + uint32_t bytes_per_value = self->bits_per_value / 8; + if (bytes_per_value < 1) { + uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); + uint32_t index = row_start + (x >> self->x_shift); + uint32_t word = self->data[index]; + word &= ~(self->bitmask << bit_position); + word |= (value & self->bitmask) << bit_position; + self->data[index] = word; + } else { + size_t* row = self->data + row_start; + if (bytes_per_value == 1) { + ((uint8_t*) row)[x] = value; + } else if (bytes_per_value == 2) { + ((uint16_t*) row)[x] = value; + } else if (bytes_per_value == 4) { + ((uint32_t*) row)[x] = value; + } + } + } + } + + self->dirty_area.x1 = 0; + self->dirty_area.x2 = self->width; + self->dirty_area.y1 = 0; + self->dirty_area.y2 = self->height; +} -- cgit v1.2.3 From dc7574684297cd3812fdb82967d0dfa7443af027 Mon Sep 17 00:00:00 2001 From: caternuson Date: Thu, 9 Apr 2020 08:59:26 -0700 Subject: add docstring, clean up --- shared-bindings/displayio/Bitmap.c | 4 ++-- shared-module/displayio/Bitmap.c | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 48d04c215..391f3e595 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -178,9 +178,9 @@ STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val return mp_const_none; } -//| .. method:: fill() +//| .. method:: fill(value) //| -//| Fills the bitmap. +//| Fills the bitmap with the supplied palette index value. //| STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 2b0165f2f..503c36073 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -164,11 +164,21 @@ void displayio_bitmap_finish_refresh(displayio_bitmap_t *self) { } void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) { + if (self->read_only) { + mp_raise_RuntimeError(translate("Read-only object")); + } + // Update the dirty area. + self->dirty_area.x1 = 0; + self->dirty_area.x2 = self->width; + self->dirty_area.y1 = 0; + self->dirty_area.y2 = self->height; + // Update our data + int32_t row_start; + uint32_t bytes_per_value = self->bits_per_value / 8; for (uint32_t x=0; xwidth; x++) { for (uint32_t y=0; yheight; y++) { - int32_t row_start = y * self->stride; - uint32_t bytes_per_value = self->bits_per_value / 8; + row_start = y * self->stride; if (bytes_per_value < 1) { uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); uint32_t index = row_start + (x >> self->x_shift); @@ -188,9 +198,4 @@ void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) } } } - - self->dirty_area.x1 = 0; - self->dirty_area.x2 = self->width; - self->dirty_area.y1 = 0; - self->dirty_area.y2 = self->height; } -- cgit v1.2.3 From a9fb34eb93ff19df1bcf6498d492a31fd00c2c96 Mon Sep 17 00:00:00 2001 From: caternuson Date: Mon, 13 Apr 2020 16:48:27 -0700 Subject: make packed word and copy it in --- shared-module/displayio/Bitmap.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) (limited to 'shared-module') diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 503c36073..8bcda6086 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -173,29 +173,13 @@ void common_hal_displayio_bitmap_fill(displayio_bitmap_t *self, uint32_t value) self->dirty_area.y1 = 0; self->dirty_area.y2 = self->height; - // Update our data - int32_t row_start; - uint32_t bytes_per_value = self->bits_per_value / 8; - for (uint32_t x=0; xwidth; x++) { - for (uint32_t y=0; yheight; y++) { - row_start = y * self->stride; - if (bytes_per_value < 1) { - uint32_t bit_position = (sizeof(size_t) * 8 - ((x & self->x_mask) + 1) * self->bits_per_value); - uint32_t index = row_start + (x >> self->x_shift); - uint32_t word = self->data[index]; - word &= ~(self->bitmask << bit_position); - word |= (value & self->bitmask) << bit_position; - self->data[index] = word; - } else { - size_t* row = self->data + row_start; - if (bytes_per_value == 1) { - ((uint8_t*) row)[x] = value; - } else if (bytes_per_value == 2) { - ((uint16_t*) row)[x] = value; - } else if (bytes_per_value == 4) { - ((uint32_t*) row)[x] = value; - } - } - } + // build the packed word + uint32_t word = 0; + for (uint8_t i=0; i<32 / self->bits_per_value; i++) { + word |= (value & self->bitmask) << (32 - ((i+1)*self->bits_per_value)); + } + // copy it in + for (uint32_t i=0; istride * self->height; i++) { + self->data[i] = word; } } -- cgit v1.2.3 From 6378d600c40d462836fd6599b9bdadf5e78df8f1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sat, 28 Mar 2020 10:34:18 -0500 Subject: displayio: implement, use allocate_display_or_raise --- shared-bindings/displayio/Display.c | 13 ++----------- shared-bindings/displayio/EPaperDisplay.c | 13 ++----------- shared-module/displayio/__init__.c | 18 ++++++++++++++++++ shared-module/displayio/__init__.h | 3 +++ 4 files changed, 25 insertions(+), 22 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 3ef7e74e9..4c6e525b2 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -152,17 +152,8 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); } - displayio_display_obj_t *self = NULL; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL || - displays[i].display.base.type == &mp_type_NoneType) { - self = &displays[i].display; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many displays")); - } + primary_display_t *disp = allocate_display_or_raise(); + displayio_display_obj_t *self = &disp->display;; self->base.type = &displayio_display_type; common_hal_displayio_display_construct( self, diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index 25a4a41e9..1459c1680 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -136,17 +136,8 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); } - displayio_epaperdisplay_obj_t *self = NULL; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].display.base.type == NULL || - displays[i].display.base.type == &mp_type_NoneType) { - self = &displays[i].epaper_display; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many displays")); - } + primary_display_t *disp = allocate_display_or_raise(); + displayio_epaperdisplay_obj_t *self = &disp->epaper_display;; mp_float_t refresh_time = mp_obj_get_float(args[ARG_refresh_time].u_obj); mp_float_t seconds_per_frame = mp_obj_get_float(args[ARG_seconds_per_frame].u_obj); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index efa61265e..fd58a0322 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -308,3 +308,21 @@ void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpos transformed->x1 = whole->x1 + (y1 - whole->y1); } } + +primary_display_t *allocate_display() { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t display_type = displays[i].display.base.type; + if (display_type == NULL || display_type == &mp_type_NoneType) { + return &displays[i]; + } + } + return NULL; + +primary_display_t *allocate_display_or_raise() { + primary_display_t *result = allocate_display(); + if (!result) { + mp_raise_RuntimeError(translate("Too many displays")); + } +} + +} diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index e78bc61ce..4e1297c8d 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -54,4 +54,7 @@ void displayio_background(void); void reset_displays(void); void displayio_gc_collect(void); +primary_display_t *allocate_display(void); +primary_display_t *allocate_display_or_raise(void); + #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H -- cgit v1.2.3 From 8cba145c90294a001ec5814fb501a7b96a055780 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 30 Mar 2020 10:47:14 -0500 Subject: displayio: implement, use allocate_new_display_bus_or_raise --- shared-bindings/displayio/FourWire.c | 13 +------------ shared-bindings/displayio/I2CDisplay.c | 13 +------------ shared-bindings/displayio/ParallelBus.c | 13 +------------ shared-module/displayio/__init__.c | 17 +++++++++++++++++ shared-module/displayio/__init__.h | 2 ++ 5 files changed, 22 insertions(+), 36 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 77329578a..1cd51b2e2 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -82,19 +82,8 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ mcu_pin_obj_t *chip_select = validate_obj_is_free_pin(args[ARG_chip_select].u_obj); mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); - displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].fourwire_bus.base.type == NULL || - displays[i].fourwire_bus.base.type == &mp_type_NoneType) { - self = &displays[i].fourwire_bus; - self->base.type = &displayio_fourwire_type; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many display busses")); - } + displayio_fourwire_obj_t* self = &allocate_display_bus_or_raise()->fourwire_bus; uint8_t polarity = args[ARG_polarity].u_int; if (polarity != 0 && polarity != 1) { diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c index 2e312aa14..dd3333f6d 100644 --- a/shared-bindings/displayio/I2CDisplay.c +++ b/shared-bindings/displayio/I2CDisplay.c @@ -71,19 +71,8 @@ STATIC mp_obj_t displayio_i2cdisplay_make_new(const mp_obj_type_t *type, size_t mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj); - displayio_i2cdisplay_obj_t* self = NULL; mp_obj_t i2c = args[ARG_i2c_bus].u_obj; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].i2cdisplay_bus.base.type == NULL || - displays[i].i2cdisplay_bus.base.type == &mp_type_NoneType) { - self = &displays[i].i2cdisplay_bus; - self->base.type = &displayio_i2cdisplay_type; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many display busses")); - } + displayio_i2cdisplay_obj_t* self = &allocate_display_bus_or_raise()->i2cdisplay_bus; common_hal_displayio_i2cdisplay_construct(self, MP_OBJ_TO_PTR(i2c), args[ARG_device_address].u_int, reset); diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c index b3a876f90..4d9ffb0a1 100644 --- a/shared-bindings/displayio/ParallelBus.c +++ b/shared-bindings/displayio/ParallelBus.c @@ -83,18 +83,7 @@ STATIC mp_obj_t displayio_parallelbus_make_new(const mp_obj_type_t *type, size_t mcu_pin_obj_t *read = validate_obj_is_free_pin(args[ARG_read].u_obj); mcu_pin_obj_t *reset = validate_obj_is_free_pin(args[ARG_reset].u_obj); - displayio_parallelbus_obj_t* self = NULL; - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].parallel_bus.base.type== NULL || - displays[i].parallel_bus.base.type == &mp_type_NoneType) { - self = &displays[i].parallel_bus; - self->base.type = &displayio_parallelbus_type; - break; - } - } - if (self == NULL) { - mp_raise_RuntimeError(translate("Too many display busses")); - } + displayio_parallelbus_obj_t* self = &allocate_display_bus_or_raise()->parallel_bus; common_hal_displayio_parallelbus_construct(self, data0, command, chip_select, write, read, reset); return self; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index fd58a0322..4844dfe60 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -326,3 +326,20 @@ primary_display_t *allocate_display_or_raise() { } } +primary_display_t *allocate_display_bus(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t display_type = displays[i].display.base.type; + if (display_type == NULL || display_type == &mp_type_NoneType) { + return &displays[i]; + } + } + return NULL; +} + +primary_display_t *allocate_display_bus_or_raise(void) { + primary_display_t *result = allocate_display_bus(); + if (result) { + return result; + } + mp_raise_RuntimeError(translate("Too many display busses")); +} diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 4e1297c8d..638c2091e 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -56,5 +56,7 @@ void displayio_gc_collect(void); primary_display_t *allocate_display(void); primary_display_t *allocate_display_or_raise(void); +primary_display_t *allocate_display_bus(void); +primary_display_t *allocate_display_bus_or_raise(void); #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO___INIT___H -- cgit v1.2.3 From 09dc46a98480350b157636ffff8b89470f595f6e Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 10 Mar 2020 13:12:01 -0500 Subject: Add Protomatter and FramebufferDisplay --- .gitmodules | 3 + lib/protomatter | 1 + .../atmel-samd/boards/hallowing_m0_express/board.c | 1 + .../atmel-samd/boards/hallowing_m4_express/board.c | 1 + .../boards/kicksat-sprite/mpconfigboard.mk | 2 + ports/atmel-samd/boards/monster_m4sk/board.c | 1 + ports/atmel-samd/boards/pewpew_m4/board.c | 1 + ports/atmel-samd/boards/pybadge/board.c | 1 + ports/atmel-samd/boards/pybadge_airlift/board.c | 1 + ports/atmel-samd/boards/pycubed/mpconfigboard.mk | 2 + ports/atmel-samd/boards/pygamer/board.c | 1 + ports/atmel-samd/boards/pygamer_advance/board.c | 1 + ports/atmel-samd/boards/pyportal/board.c | 1 + ports/atmel-samd/boards/pyportal_titano/board.c | 3 +- .../boards/robohatmm1_m4/mpconfigboard.mk | 2 + ports/atmel-samd/boards/ugame10/board.c | 1 + .../mpconfigboard.mk | 2 + .../boards/winterbloom_sol/mpconfigboard.mk | 2 + .../common-hal/_protomatter/Protomatter.c | 77 ++++ .../common-hal/_protomatter/Protomatter.h | 35 ++ .../atmel-samd/common-hal/_protomatter/__init__.c | 0 ports/atmel-samd/common-hal/microcontroller/Pin.c | 12 + ports/atmel-samd/common-hal/pulseio/PWMOut.c | 27 +- ports/atmel-samd/mpconfigport.mk | 12 + ports/atmel-samd/peripherals | 2 +- ports/atmel-samd/timer_handler.c | 7 + ports/atmel-samd/timer_handler.h | 5 + ports/nrf/boards/clue_nrf52840_express/board.c | 1 + ports/nrf/boards/ohs2020_badge/board.c | 1 + ports/stm/boards/meowbit_v121/board.c | 1 + py/circuitpy_defns.mk | 18 + py/circuitpy_mpconfig.h | 16 + py/circuitpy_mpconfig.mk | 11 + shared-bindings/_protomatter/Protomatter.c | 293 +++++++++++++ shared-bindings/_protomatter/Protomatter.h | 56 +++ shared-bindings/_protomatter/__init__.c | 55 +++ shared-bindings/displayio/Display.c | 9 +- shared-bindings/displayio/Display.h | 2 +- shared-bindings/framebufferio/FramebufferDisplay.c | 452 +++++++++++++++++++++ shared-bindings/framebufferio/FramebufferDisplay.h | 74 ++++ shared-bindings/framebufferio/__init__.c | 63 +++ shared-bindings/framebufferio/__init__.h | 0 shared-bindings/microcontroller/Pin.h | 6 + shared-module/_protomatter/Protomatter.c | 169 ++++++++ shared-module/_protomatter/Protomatter.h | 0 shared-module/_protomatter/__init__.c | 0 shared-module/_protomatter/__init__.h | 0 shared-module/_protomatter/allocator.h | 30 ++ shared-module/displayio/ColorConverter.c | 11 +- shared-module/displayio/Display.c | 4 +- shared-module/displayio/EPaperDisplay.c | 2 +- shared-module/displayio/Palette.h | 1 + shared-module/displayio/__init__.c | 41 +- shared-module/displayio/__init__.h | 10 + shared-module/displayio/display_core.c | 46 ++- shared-module/displayio/display_core.h | 2 +- shared-module/framebufferio/FramebufferDisplay.c | 339 ++++++++++++++++ shared-module/framebufferio/FramebufferDisplay.h | 82 ++++ shared-module/framebufferio/__init__.c | 0 shared-module/framebufferio/__init__.h | 0 tools/convert_release_notes.py | 3 + 61 files changed, 1953 insertions(+), 49 deletions(-) create mode 160000 lib/protomatter create mode 100644 ports/atmel-samd/common-hal/_protomatter/Protomatter.c create mode 100644 ports/atmel-samd/common-hal/_protomatter/Protomatter.h create mode 100644 ports/atmel-samd/common-hal/_protomatter/__init__.c create mode 100644 shared-bindings/_protomatter/Protomatter.c create mode 100644 shared-bindings/_protomatter/Protomatter.h create mode 100644 shared-bindings/_protomatter/__init__.c create mode 100644 shared-bindings/framebufferio/FramebufferDisplay.c create mode 100644 shared-bindings/framebufferio/FramebufferDisplay.h create mode 100644 shared-bindings/framebufferio/__init__.c create mode 100644 shared-bindings/framebufferio/__init__.h create mode 100644 shared-module/_protomatter/Protomatter.c create mode 100644 shared-module/_protomatter/Protomatter.h create mode 100644 shared-module/_protomatter/__init__.c create mode 100644 shared-module/_protomatter/__init__.h create mode 100644 shared-module/_protomatter/allocator.h create mode 100644 shared-module/framebufferio/FramebufferDisplay.c create mode 100644 shared-module/framebufferio/FramebufferDisplay.h create mode 100644 shared-module/framebufferio/__init__.c create mode 100644 shared-module/framebufferio/__init__.h (limited to 'shared-module') diff --git a/.gitmodules b/.gitmodules index 365d9ff72..ebff8ecb2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -119,3 +119,6 @@ [submodule "ports/stm/st_driver"] path = ports/stm/st_driver url = https://github.com/hathach/st_driver.git +[submodule "lib/protomatter"] + path = lib/protomatter + url = https://github.com/adafruit/Adafruit_Protomatter diff --git a/lib/protomatter b/lib/protomatter new file mode 160000 index 000000000..c3a3e3573 --- /dev/null +++ b/lib/protomatter @@ -0,0 +1 @@ +Subproject commit c3a3e35731d641cb5a21ae7319634afc419f5afe diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 0b44bd4bb..9a1db9ca9 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -97,6 +97,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index 5dbdd499a..3e4a04ae2 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -77,6 +77,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk index 5429bcf86..f7223790a 100644 --- a/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/kicksat-sprite/mpconfigboard.mk @@ -11,8 +11,10 @@ LONGINT_IMPL = MPZ # Not needed. CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_NETWORK = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_AUDIOMP3 = 0 diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 684639c30..55d6f80c9 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -78,6 +78,7 @@ void board_init(void) { false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 0f8936696..cf8439cf0 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -128,6 +128,7 @@ void board_init(void) { false, // pixels in byte share row. only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 257d72e30..ffddf0397 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -100,6 +100,7 @@ void board_init(void) { false, // pixels in byte share row. only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pybadge_airlift/board.c b/ports/atmel-samd/boards/pybadge_airlift/board.c index 7df245a72..8274d0ebe 100644 --- a/ports/atmel-samd/boards/pybadge_airlift/board.c +++ b/ports/atmel-samd/boards/pybadge_airlift/board.c @@ -78,6 +78,7 @@ void board_init(void) { false, // pixels in byte share row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk index 14e6883c0..c14a29615 100644 --- a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk @@ -15,7 +15,9 @@ LONGINT_IMPL = MPZ # Not needed. CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GAMEPAD = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 7c3ca6e33..c7f2f6e1d 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -100,6 +100,7 @@ void board_init(void) { false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pygamer_advance/board.c b/ports/atmel-samd/boards/pygamer_advance/board.c index 7fd3ebc5e..6053fedb0 100644 --- a/ports/atmel-samd/boards/pygamer_advance/board.c +++ b/ports/atmel-samd/boards/pygamer_advance/board.c @@ -78,6 +78,7 @@ void board_init(void) { false, // pixels in a byte share a row. Only valid for depths < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pyportal/board.c b/ports/atmel-samd/boards/pyportal/board.c index a86f0ee48..ed3006e3c 100644 --- a/ports/atmel-samd/boards/pyportal/board.c +++ b/ports/atmel-samd/boards/pyportal/board.c @@ -87,6 +87,7 @@ void board_init(void) { false, // pixels_in_byte_share_row (unused for depths > 8) 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/pyportal_titano/board.c b/ports/atmel-samd/boards/pyportal_titano/board.c index a9ded1760..40b7e8402 100644 --- a/ports/atmel-samd/boards/pyportal_titano/board.c +++ b/ports/atmel-samd/boards/pyportal_titano/board.c @@ -101,9 +101,10 @@ void board_init(void) { 0, // rotation 16, // Color depth false, // grayscale - false, // pixels_in_byte_share_row (unused for depths > 8) + false, // pixels_i|n_byte_share_row (unused for depths > 8) 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk index fd4f22230..57eb7f1b9 100644 --- a/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/robohatmm1_m4/mpconfigboard.mk @@ -17,7 +17,9 @@ LONGINT_IMPL = MPZ CIRCUITPY_AUDIOBUSIO = 0 # Make room for more stuff CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_PROTOMATTER = 0 # Include these Python libraries in firmware. #FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index 07814d558..38661950f 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -97,6 +97,7 @@ void board_init(void) { false, // pixels in byte share row. Only used with depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk index d91369f75..691c1c136 100644 --- a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk @@ -18,6 +18,7 @@ CIRCUITPY_AUDIOIO = 1 # Disable modules that are unusable on this special-purpose board. CIRCUITPY_BITBANGIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_AUDIOBUSIO = 0 @@ -27,6 +28,7 @@ CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_NETWORK = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_USB_HID = 0 CIRCUITPY_RTC = 0 diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk index 166eaad3f..ed97aef4c 100644 --- a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk @@ -21,10 +21,12 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_BLEIO = 0 CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GAMEPAD = 0 CIRCUITPY_I2CSLAVE = 0 CIRCUITPY_NETWORK = 0 CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_PROTOMATTER = 0 CIRCUITPY_PS2IO = 0 CIRCUITPY_USB_HID = 0 diff --git a/ports/atmel-samd/common-hal/_protomatter/Protomatter.c b/ports/atmel-samd/common-hal/_protomatter/Protomatter.c new file mode 100644 index 000000000..702de0e3d --- /dev/null +++ b/ports/atmel-samd/common-hal/_protomatter/Protomatter.c @@ -0,0 +1,77 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "common-hal/_protomatter/Protomatter.h" + +#include "samd/timers.h" +#include "timer_handler.h" + +void *common_hal_protomatter_timer_allocate() { + uint8_t timer_index = find_free_timer(); + if (timer_index == 0xff) { + return NULL; + } + timer_never_reset(timer_index, true); + return tc_insts[timer_index]; +} + +static uint8_t tc_index_from_ptr(void* ptr) { + for (uint8_t i = TC_INST_NUM; i > 0; i--) { + if (tc_insts[i] == ptr) { + return i; + } + } + return 0xff; +} + +void common_hal_protomatter_timer_enable(void* ptr) { + uint8_t timer_index = tc_index_from_ptr(ptr); + if (timer_index == 0xff) { + return; + } + set_timer_handler(true, timer_index, TC_HANDLER_PROTOMATTER); + turn_on_clocks(true, timer_index, 1); +} + +void common_hal_protomatter_timer_disable(void* ptr) { + uint8_t timer_index = tc_index_from_ptr(ptr); + if (timer_index == 0xff) { + return; + } + set_timer_handler(true, timer_index, TC_HANDLER_NO_INTERRUPT); +} + +void common_hal_protomatter_timer_free(void* ptr) { + uint8_t timer_index = tc_index_from_ptr(ptr); + if (timer_index == 0xff) { + return; + } + tc_set_enable(ptr, false); + tc_reset(ptr); + timer_reset_ok(timer_index, true); +} diff --git a/ports/atmel-samd/common-hal/_protomatter/Protomatter.h b/ports/atmel-samd/common-hal/_protomatter/Protomatter.h new file mode 100644 index 000000000..8185bed0e --- /dev/null +++ b/ports/atmel-samd/common-hal/_protomatter/Protomatter.h @@ -0,0 +1,35 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PROTOMATTER_PROTOMATTER_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PROTOMATTER_PROTOMATTER_H + +void *common_hal_protomatter_timer_allocate(void); +void common_hal_protomatter_timer_enable(void*); +void common_hal_protomatter_timer_disable(void*); +void common_hal_protomatter_timer_free(void*); + +#endif diff --git a/ports/atmel-samd/common-hal/_protomatter/__init__.c b/ports/atmel-samd/common-hal/_protomatter/__init__.c new file mode 100644 index 000000000..e69de29bb diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 9719ea5b1..cf78673b2 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -240,3 +240,15 @@ bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) { return pin_number_is_free(pin->number); } + +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin) { + return pin->number; +} + +void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) { + return claim_pin(pin); +} + +void common_hal_mcu_pin_reset_number(uint8_t pin_no) { + reset_pin_number(pin_no); +} diff --git a/ports/atmel-samd/common-hal/pulseio/PWMOut.c b/ports/atmel-samd/common-hal/pulseio/PWMOut.c index fef581584..1da0da844 100644 --- a/ports/atmel-samd/common-hal/pulseio/PWMOut.c +++ b/ports/atmel-samd/common-hal/pulseio/PWMOut.c @@ -61,22 +61,31 @@ uint8_t tcc_channels[5]; // Set by pwmout_reset() to {0xc0, 0xf0, 0xf8, 0xfc, static uint8_t never_reset_tc_or_tcc[TC_INST_NUM + TCC_INST_NUM]; -void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { - if (self->timer->is_tc) { - never_reset_tc_or_tcc[self->timer->index] += 1; +STATIC void timer_refcount(int index, bool is_tc, int increment) { + if (is_tc) { + never_reset_tc_or_tcc[index] += increment; } else { - never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] += 1; + never_reset_tc_or_tcc[TC_INST_NUM + index] += increment; } +} + +void timer_never_reset(int index, bool is_tc) { + timer_refcount(index, is_tc, 1); +} + +void timer_reset_ok(int index, bool is_tc) { + timer_refcount(index, is_tc, -1); +} + + +void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) { + timer_never_reset(self->timer->index, self->timer->is_tc); never_reset_pin_number(self->pin->number); } void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) { - if (self->timer->is_tc) { - never_reset_tc_or_tcc[self->timer->index] -= 1; - } else { - never_reset_tc_or_tcc[TC_INST_NUM + self->timer->index] -= 1; - } + timer_reset_ok(self->timer->index, self->timer->is_tc); } void pwmout_reset(void) { diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index c2408feae..61f7c206a 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -70,6 +70,18 @@ CIRCUITPY_ULAB = 1 endif endif +ifndef CIRCUITPY_PROTOMATTER +ifneq ($(CIRCUITPY_SMALL_BUILD),1) +CIRCUITPY_PROTOMATTER = 1 +endif +endif + +ifndef CIRCUITPY_FRAMEBUFFERIO +ifneq ($(CIRCUITPY_SMALL_BUILD),1) +CIRCUITPY_FRAMEBUFFERIO = 1 +endif +endif + endif # samd51 INTERNAL_LIBM = 1 diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index b89811f22..f528240c2 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit b89811f22a24ac350079ceaf0cdf0e62aa03f4f4 +Subproject commit f528240c2a4c2d7a39de786f1aa56895c12227b4 diff --git a/ports/atmel-samd/timer_handler.c b/ports/atmel-samd/timer_handler.c index 5d6de3093..598fad564 100644 --- a/ports/atmel-samd/timer_handler.c +++ b/ports/atmel-samd/timer_handler.c @@ -33,6 +33,8 @@ #include "shared-module/_pew/PewPew.h" #include "common-hal/frequencyio/FrequencyIn.h" +extern void _PM_IRQ_HANDLER(void); + static uint8_t tc_handler[TC_INST_NUM]; void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler) { @@ -62,6 +64,11 @@ void shared_timer_handler(bool is_tc, uint8_t index) { frequencyin_interrupt_handler(index); #endif break; + case TC_HANDLER_PROTOMATTER: + #if CIRCUITPY_PROTOMATTER + _PM_IRQ_HANDLER(); + #endif + break; default: break; } diff --git a/ports/atmel-samd/timer_handler.h b/ports/atmel-samd/timer_handler.h index 4a7adb58c..646cd54ec 100644 --- a/ports/atmel-samd/timer_handler.h +++ b/ports/atmel-samd/timer_handler.h @@ -30,8 +30,13 @@ #define TC_HANDLER_PULSEOUT 0x1 #define TC_HANDLER_PEW 0x2 #define TC_HANDLER_FREQUENCYIN 0x3 +#define TC_HANDLER_PROTOMATTER 0x4 void set_timer_handler(bool is_tc, uint8_t index, uint8_t timer_handler); void shared_timer_handler(bool is_tc, uint8_t index); +// implementation of these functions is in PWMOut.c +void timer_never_reset(int index, bool is_tc); +void timer_reset_ok(int index, bool is_tc); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_TIMER_HANDLER_H diff --git a/ports/nrf/boards/clue_nrf52840_express/board.c b/ports/nrf/boards/clue_nrf52840_express/board.c index e9f8d244e..2370a0aa1 100644 --- a/ports/nrf/boards/clue_nrf52840_express/board.c +++ b/ports/nrf/boards/clue_nrf52840_express/board.c @@ -77,6 +77,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/nrf/boards/ohs2020_badge/board.c b/ports/nrf/boards/ohs2020_badge/board.c index 88c68bcb8..bbb20cc6e 100644 --- a/ports/nrf/boards/ohs2020_badge/board.c +++ b/ports/nrf/boards/ohs2020_badge/board.c @@ -77,6 +77,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index 9e2d99bce..68eed2926 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -98,6 +98,7 @@ void board_init(void) { false, // Pixels in a byte share a row. Only used for depth < 8 1, // bytes per cell. Only valid for depths < 8 false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index f84d0b5b1..b6b0cacaf 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -142,6 +142,9 @@ endif ifeq ($(CIRCUITPY_DISPLAYIO),1) SRC_PATTERNS += displayio/% terminalio/% fontio/% endif +ifeq ($(CIRCUITPY_FRAMEBUFFERIO),1) +SRC_PATTERNS += framebufferio/% +endif ifeq ($(CIRCUITPY_FREQUENCYIO),1) SRC_PATTERNS += frequencyio/% endif @@ -178,6 +181,9 @@ endif ifeq ($(CIRCUITPY_PIXELBUF),1) SRC_PATTERNS += _pixelbuf/% endif +ifeq ($(CIRCUITPY_PROTOMATTER),1) +SRC_PATTERNS += _protomatter/% +endif ifeq ($(CIRCUITPY_PULSEIO),1) SRC_PATTERNS += pulseio/% endif @@ -242,6 +248,8 @@ SRC_COMMON_HAL_ALL = \ _bleio/PacketBuffer.c \ _bleio/Service.c \ _bleio/UUID.c \ + _protomatter/Protomatter.c \ + _protomatter/__init__.c \ analogio/AnalogIn.c \ analogio/AnalogOut.c \ analogio/__init__.c \ @@ -315,6 +323,8 @@ SRC_SHARED_MODULE_ALL = \ _bleio/ScanResults.c \ _pixelbuf/PixelBuf.c \ _pixelbuf/__init__.c \ + _protomatter/Protomatter.c \ + _protomatter/__init__.c \ _stage/Layer.c \ _stage/Text.c \ _stage/__init__.c \ @@ -348,6 +358,8 @@ SRC_SHARED_MODULE_ALL = \ displayio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ + framebufferio/FramebufferDisplay.c \ + framebufferio/__init__.c \ gamepad/GamePad.c \ gamepad/__init__.c \ gamepadshift/GamePadShift.c \ @@ -401,6 +413,12 @@ SRC_MOD += $(addprefix lib/mp3/src/, \ ) $(BUILD)/lib/mp3/src/buffers.o: CFLAGS += -include "py/misc.h" -D'MPDEC_ALLOCATOR(x)=m_malloc(x,0)' -D'MPDEC_FREE(x)=m_free(x)' endif +ifeq ($(CIRCUITPY_PROTOMATTER),1) +SRC_MOD += $(addprefix lib/protomatter/, \ + core.c \ +) +$(BUILD)/lib/protomatter/core.o: CFLAGS += -include "shared-module/_protomatter/allocator.h" -DCIRCUITPY -Wno-missing-braces +endif # All possible sources are listed here, and are filtered by SRC_PATTERNS. SRC_SHARED_MODULE_INTERNAL = \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 04e191264..06289258d 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -345,6 +345,13 @@ extern const struct _mp_obj_module_t terminalio_module; #define CIRCUITPY_DISPLAY_LIMIT (0) #endif +#if CIRCUITPY_FRAMEBUFFERIO +extern const struct _mp_obj_module_t framebufferio_module; +#define FRAMEBUFFERIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_framebufferio), (mp_obj_t)&framebufferio_module }, +#else +#define FRAMEBUFFERIO_MODULE +#endif + #if CIRCUITPY_FREQUENCYIO extern const struct _mp_obj_module_t frequencyio_module; #define FREQUENCYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_frequencyio), (mp_obj_t)&frequencyio_module }, @@ -454,6 +461,13 @@ extern const struct _mp_obj_module_t pixelbuf_module; #define PIXELBUF_MODULE #endif +#if CIRCUITPY_PROTOMATTER +extern const struct _mp_obj_module_t protomatter_module; +#define PROTOMATTER_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR__protomatter),(mp_obj_t)&protomatter_module }, +#else +#define PROTOMATTER_MODULE +#endif + #if CIRCUITPY_PULSEIO extern const struct _mp_obj_module_t pulseio_module; #define PULSEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, @@ -628,6 +642,7 @@ extern const struct _mp_obj_module_t ustack_module; FONTIO_MODULE \ TERMINALIO_MODULE \ ERRNO_MODULE \ + FRAMEBUFFERIO_MODULE \ FREQUENCYIO_MODULE \ GAMEPAD_MODULE \ GAMEPADSHIFT_MODULE \ @@ -643,6 +658,7 @@ extern const struct _mp_obj_module_t ustack_module; PEW_MODULE \ PIXELBUF_MODULE \ PS2IO_MODULE \ + PROTOMATTER_MODULE \ PULSEIO_MODULE \ RANDOM_MODULE \ RE_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 1a375efc6..ba94f9784 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -149,6 +149,11 @@ CIRCUITPY_DISPLAYIO = $(CIRCUITPY_FULL_BUILD) endif CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) +ifndef CIRCUITPY_FRAMEBUFFERIO +CIRCUITPY_FRAMEBUFFERIO = 0 +endif +CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO) + ifndef CIRCUITPY_FREQUENCYIO CIRCUITPY_FREQUENCYIO = $(CIRCUITPY_FULL_BUILD) endif @@ -210,6 +215,12 @@ CIRCUITPY_PIXELBUF = $(CIRCUITPY_FULL_BUILD) endif CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) +# Only for SAMD boards for the moment +ifndef CIRCUITPY_PROTOMATTER +CIRCUITPY_PROTOMATTER = 0 +endif +CFLAGS += -DCIRCUITPY_PROTOMATTER=$(CIRCUITPY_PROTOMATTER) + ifndef CIRCUITPY_PULSEIO CIRCUITPY_PULSEIO = $(CIRCUITPY_DEFAULT_BUILD) endif diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c new file mode 100644 index 000000000..8d0d223bb --- /dev/null +++ b/shared-bindings/_protomatter/Protomatter.c @@ -0,0 +1,293 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objarray.h" + +#include "common-hal/_protomatter/Protomatter.h" +#include "shared-bindings/_protomatter/Protomatter.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/framebufferio/__init__.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +//| .. currentmodule:: _protomatter +//| +//| :class:`protomatter` -- Driver for HUB75-style RGB LED matrices +//| ================================================================ +//| + +extern Protomatter_core *_PM_protoPtr; + +STATIC uint8_t validate_pin(mp_obj_t obj) { + mcu_pin_obj_t *result = validate_obj_is_free_pin(obj); + return common_hal_mcu_pin_number(result); +} + +STATIC void validate_pins(qstr what, uint8_t* pin_nos, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out) { + mp_int_t len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(seq)); + if (len > max_pins) { + mp_raise_ValueError_varg(translate("At most %d %q may be specified"), max_pins, what); + } + *count_out = len; + for (mp_int_t i=0; iprotomatter; + self->base.type = &protomatter_Protomatter_type; + + uint8_t rgb_count, addr_count; + uint8_t rgb_pins[MP_ARRAY_SIZE(self->rgb_pins)]; + uint8_t addr_pins[MP_ARRAY_SIZE(self->addr_pins)]; + uint8_t clock_pin = validate_pin(args[ARG_clock_pin].u_obj); + uint8_t latch_pin = validate_pin(args[ARG_latch_pin].u_obj); + uint8_t oe_pin = validate_pin(args[ARG_oe_pin].u_obj); + + validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); + validate_pins(MP_QSTR_addr_pins, addr_pins, MP_ARRAY_SIZE(self->addr_pins), args[ARG_addr_list].u_obj, &addr_count); + + 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); + framebuffer = mp_obj_new_bytearray_of_zeros(bufsize); + } + + common_hal_protomatter_protomatter_construct(self, + args[ARG_width].u_int, + args[ARG_bit_depth].u_int, + rgb_count, rgb_pins, + addr_count, addr_pins, + clock_pin, latch_pin, oe_pin, + args[ARG_doublebuffer].u_bool, + framebuffer, NULL); + + claim_pins_nr(args[ARG_rgb_list].u_obj); + claim_pins_nr(args[ARG_addr_list].u_obj); + claim_pin_nr(args[ARG_clock_pin].u_obj); + claim_pin_nr(args[ARG_oe_pin].u_obj); + claim_pin_nr(args[ARG_latch_pin].u_obj); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit +//| +//| Free the resources (pins, timers, etc.) associated with this +//| protomatter instance. After deinitialization, no further operations +//| may be performed. +//| +STATIC mp_obj_t protomatter_protomatter_deinit(mp_obj_t self_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + common_hal_protomatter_protomatter_deinit(self); + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_deinit_obj, protomatter_protomatter_deinit); + +static void check_for_deinit(protomatter_protomatter_obj_t *self) { + if (!self->core.rgbPins) { + raise_deinited_error(); + } +} + +//| .. attribute:: paused +//| +//| When paused, the matrix is not driven and all its LEDs are unlit. +//| +STATIC mp_obj_t protomatter_protomatter_get_paused(mp_obj_t self_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + return mp_obj_new_bool(self->paused); +} +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_paused_obj, protomatter_protomatter_get_paused); + +STATIC mp_obj_t protomatter_protomatter_set_paused(mp_obj_t self_in, mp_obj_t value_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + bool paused = mp_obj_is_true(value_in); + if (paused && !self->paused) { + _PM_stop(&self->core); + } else if (!paused && self->paused) { + _PM_resume(&self->core); + } + self->paused = paused; + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(protomatter_protomatter_set_paused_obj, protomatter_protomatter_set_paused); + +const mp_obj_property_t protomatter_protomatter_paused_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&protomatter_protomatter_get_paused_obj, + (mp_obj_t)&protomatter_protomatter_set_paused_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: write(buf) +//| +//| Transmits the color data in the buffer to the pixels so that they are shown. +//| +//| The data in the buffer must be in "RGB565" format. This means +//| that it is organized as a series of 16-bit numbers where the highest 5 +//| bits are interpreted as red, the next 6 as green, and the final 5 as +//| blue. The object can be any buffer, but `array.array` and `ulab.array` +//| objects are most often useful. +//| +STATIC mp_obj_t protomatter_protomatter_swapbuffers(mp_obj_t self_in) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + + _PM_convert_565(&self->core, self->bufinfo.buf, self->width); + _PM_swapbuffer_maybe(&self->core); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_swapbuffers_obj, protomatter_protomatter_swapbuffers); + +STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&protomatter_protomatter_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&protomatter_protomatter_paused_obj) }, + { MP_ROM_QSTR(MP_QSTR_swapbuffers), MP_ROM_PTR(&protomatter_protomatter_swapbuffers_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(protomatter_protomatter_locals_dict, protomatter_protomatter_locals_dict_table); + +STATIC void protomatter_protomatter_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + check_for_deinit(self); + + *bufinfo = self->bufinfo; +} + +STATIC void protomatter_protomatter_swapbuffers_void(mp_obj_t self_in) { + protomatter_protomatter_swapbuffers(self_in); +} + +STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { + protomatter_protomatter_deinit(self_in); +} + +STATIC void protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { + protomatter_protomatter_set_paused(self_in, mp_obj_new_bool(value <= 0)); +} + +STATIC const framebuffer_p_t protomatter_protomatter_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) + .get_bufinfo = protomatter_protomatter_get_bufinfo, + .set_brightness = protomatter_protomatter_set_brightness, + .swapbuffers = protomatter_protomatter_swapbuffers_void, + .deinit = protomatter_protomatter_deinit_void, +}; + +STATIC mp_int_t protomatter_protomatter_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; + // a readonly framebuffer would be unusual but not impossible + if((flags & MP_BUFFER_WRITE) && !(self->bufinfo.typecode & MP_OBJ_ARRAY_TYPECODE_FLAG_RW)) { + return 1; + } + *bufinfo = self->bufinfo; + return 0; +} + +const mp_obj_type_t protomatter_Protomatter_type = { + { &mp_type_type }, + .name = MP_QSTR_Protomatter, + .buffer_p = { .get_buffer = protomatter_protomatter_get_buffer, }, + .make_new = protomatter_protomatter_make_new, + .protocol = &protomatter_protomatter_proto, + .locals_dict = (mp_obj_dict_t*)&protomatter_protomatter_locals_dict, +}; diff --git a/shared-bindings/_protomatter/Protomatter.h b/shared-bindings/_protomatter/Protomatter.h new file mode 100644 index 000000000..cacc39a30 --- /dev/null +++ b/shared-bindings/_protomatter/Protomatter.h @@ -0,0 +1,56 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_PROTOMATTER_PROTOMATTER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_PROTOMATTER_PROTOMATTER_H + +#include "shared-module/_protomatter/Protomatter.h" +#include "lib/protomatter/core.h" + +extern const mp_obj_type_t protomatter_Protomatter_type; +typedef struct { + mp_obj_base_t base; + mp_obj_t framebuffer; + mp_buffer_info_t bufinfo; + Protomatter_core core; + void *timer; + uint16_t bufsize, width; + uint8_t rgb_pins[30]; + uint8_t addr_pins[10]; + uint8_t clock_pin, latch_pin, oe_pin; + uint8_t rgb_count, addr_count; + uint8_t bit_depth; + bool core_is_initialized; + bool paused; + bool doublebuffer; +} protomatter_protomatter_obj_t; + +void common_hal_protomatter_protomatter_construct(protomatter_protomatter_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_protomatter_protomatter_deinit(protomatter_protomatter_obj_t*); +void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t*); +void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer); + +#endif diff --git a/shared-bindings/_protomatter/__init__.c b/shared-bindings/_protomatter/__init__.c new file mode 100644 index 000000000..2281b15f1 --- /dev/null +++ b/shared-bindings/_protomatter/__init__.c @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/_protomatter/Protomatter.h" + +//| :mod:`_protomatter` --- Low-level routines for bitbanged LED matrices +//| ===================================================================== +//| +//| .. module:: _protomatter +//| :synopsis: Low-level routines for bitbanged LED matrices +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| Protomatter + +STATIC const mp_rom_map_elem_t protomatter_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__protomatter) }, + { MP_ROM_QSTR(MP_QSTR_Protomatter), MP_ROM_PTR(&protomatter_Protomatter_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(protomatter_module_globals, protomatter_module_globals_table); + +const mp_obj_module_t protomatter_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&protomatter_module_globals, +}; diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 4c6e525b2..a22b2add2 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -92,6 +92,7 @@ //| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. //| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. //| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param bool reverse_bytes_in_word: Reverses the order of bytes within a word when color_depth == 16 //| :param int set_column_command: Command used to set the start and end columns to update //| :param int set_row_command: Command used so set the start and end rows to update //| :param int write_ram_command: Command used to write pixels values into the update region. Ignored if data_as_commands is set. @@ -107,7 +108,7 @@ //| :param bool backlight_on_high: If True, pulling the backlight pin high turns the backlight on. //| STATIC mp_obj_t displayio_display_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_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high }; + enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -121,6 +122,7 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_reverse_bytes_in_word, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, @@ -159,7 +161,10 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a self, display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, - args[ARG_pixels_in_byte_share_row].u_bool, args[ARG_bytes_per_cell].u_bool, args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_pixels_in_byte_share_row].u_bool, + args[ARG_bytes_per_cell].u_bool, + args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_reverse_bytes_in_word].u_bool, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int, args[ARG_write_ram_command].u_int, args[ARG_set_vertical_scroll].u_int, diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h index 8c2e20262..e69c5b6b5 100644 --- a/shared-bindings/displayio/Display.h +++ b/shared-bindings/displayio/Display.h @@ -41,7 +41,7 @@ extern const mp_obj_type_t displayio_display_type; void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, - bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, + bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c new file mode 100644 index 000000000..9f1df8bfa --- /dev/null +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -0,0 +1,452 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/framebufferio/FramebufferDisplay.h" + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/translate.h" + +//| .. currentmodule:: framebufferio +//| +//| :class:`FramebufferDisplay` -- Manage updating a display with framebuffer in RAM +//| ================================================================================ +//| +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. +//| +//| .. class:: FramebufferDisplay(framebuffer, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, backlight_pin=None, brightness=1.0, auto_brightness=False, auto_refresh=True, native_frames_per_second=60) +//| +//| Create a Display object with the given framebuffer (a buffer, array, ulab.array, etc) +//| +//| :param framebuffer: The framebuffer that the display is connected to +//| :type framebuffer: any core object implementing the framebuffer protocol +//| :param callback: Function or bound method to call when the framebuffer has been updated. The callback receives one argument, the framebuffer object. +//| :param int width: Width in pixels +//| :param int height: Height in pixels +//| :param int colstart: The index if the first visible column +//| :param int rowstart: The index if the first visible row +//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) +//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays +//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) +//| :param bool grayscale: True if the display only shows a single color. +//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. +//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. +//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) +//| :param bool reverse_bytes_in_word: Reverses the order of bytes within a word when color_depth == 16 +//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight +//| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True. +//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. +//| :param bool auto_refresh: Automatically refresh the screen +//| :param int native_frames_per_second: Number of display refreshes per second +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_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_framebuffer, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, + { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_reverse_bytes_in_word, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, + }; + MP_STATIC_ASSERT( MP_ARRAY_SIZE(allowed_args) == NUM_ARGS ); + 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); + + mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; + + const mcu_pin_obj_t* backlight_pin = validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); + + mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + + mp_int_t rotation = args[ARG_rotation].u_int; + if (rotation % 90 != 0) { + mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); + } + + primary_display_t *disp = allocate_display_or_raise(); + framebufferio_framebufferdisplay_obj_t *self = &disp->framebuffer_display; + self->base.type = &framebufferio_framebufferdisplay_type; + common_hal_framebufferio_framebufferdisplay_construct( + self, + framebuffer, + args[ARG_width].u_int, args[ARG_height].u_int, + args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, + args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, + args[ARG_pixels_in_byte_share_row].u_bool, + args[ARG_bytes_per_cell].u_bool, + args[ARG_reverse_pixels_in_byte].u_bool, + args[ARG_reverse_bytes_in_word].u_bool, + MP_OBJ_TO_PTR(backlight_pin), + brightness, + args[ARG_auto_brightness].u_bool, + args[ARG_auto_refresh].u_bool, + args[ARG_native_frames_per_second].u_int + ); + + return self; +} + +// Helper to ensure we have the native super class instead of a subclass. +static framebufferio_framebufferdisplay_obj_t* native_display(mp_obj_t display_obj) { + mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &framebufferio_framebufferdisplay_type); + mp_obj_assert_native_inited(native_display); + return MP_OBJ_TO_PTR(native_display); +} + +//| .. method:: show(group) +//| +//| Switches to displaying the given group of layers. When group is None, the default +//| CircuitPython terminal will be shown. +//| +//| :param Group group: The group to show. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + displayio_group_t* group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + bool ok = common_hal_framebufferio_framebufferdisplay_show(self, group); + if (!ok) { + mp_raise_ValueError(translate("Group already used")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_show_obj, framebufferio_framebufferdisplay_obj_show); + +//| .. method:: refresh(*, target_frames_per_second=60, minimum_frames_per_second=1) +//| +//| When auto refresh is off, waits for the target frame rate and then refreshes the display, +//| returning True. If the call has taken too long since the last refresh call for the given +//| target frame rate, then the refresh returns False immediately without updating the screen to +//| hopefully help getting caught up. +//| +//| If the time since the last successful refresh is below the minimum frame rate, then an +//| exception will be raised. Set minimum_frames_per_second to 0 to disable. +//| +//| When auto refresh is on, updates the display immediately. (The display will also update +//| without calls to this.) +//| +//| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated. +//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_target_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 60} }, + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + }; + 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); + + framebufferio_framebufferdisplay_obj_t *self = native_display(pos_args[0]); + uint32_t maximum_ms_per_real_frame = 0xffffffff; + mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; + if (minimum_frames_per_second > 0) { + maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; + } + return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame)); +} +MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_refresh_obj, 1, framebufferio_framebufferdisplay_obj_refresh); + +//| .. attribute:: auto_refresh +//| +//| True when the display is refreshed automatically. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_auto_refresh(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_get_auto_refresh(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_refresh_obj, framebufferio_framebufferdisplay_obj_get_auto_refresh); + +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_refresh(mp_obj_t self_in, mp_obj_t auto_refresh) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + + common_hal_framebufferio_framebufferdisplay_set_auto_refresh(self, mp_obj_is_true(auto_refresh)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_auto_refresh_obj, framebufferio_framebufferdisplay_obj_set_auto_refresh); + +const mp_obj_property_t framebufferio_framebufferdisplay_auto_refresh_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_auto_refresh_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_auto_refresh_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: brightness +//| +//| The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When +//| `auto_brightness` is True, the value of `brightness` will change automatically. +//| If `brightness` is set, `auto_brightness` will be disabled and will be set to False. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_brightness(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + mp_float_t brightness = common_hal_framebufferio_framebufferdisplay_get_brightness(self); + if (brightness < 0) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_obj_new_float(brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_brightness_obj, framebufferio_framebufferdisplay_obj_get_brightness); + +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, false); + mp_float_t brightness = mp_obj_get_float(brightness_obj); + if (brightness < 0 || brightness > 1.0) { + mp_raise_ValueError(translate("Brightness must be 0-1.0")); + } + bool ok = common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); + if (!ok) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_brightness_obj, framebufferio_framebufferdisplay_obj_set_brightness); + +const mp_obj_property_t framebufferio_framebufferdisplay_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_brightness_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: auto_brightness +//| +//| True when the display brightness is adjusted automatically, based on an ambient +//| light sensor or other method. Note that some displays may have this set to True by default, +//| but not actually implement automatic brightness adjustment. `auto_brightness` is set to False +//| if `brightness` is set manually. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_auto_brightness(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_get_auto_brightness(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_brightness_obj, framebufferio_framebufferdisplay_obj_get_auto_brightness); + +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + + common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_auto_brightness_obj, framebufferio_framebufferdisplay_obj_set_auto_brightness); + +const mp_obj_property_t framebufferio_framebufferdisplay_auto_brightness_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_auto_brightness_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_auto_brightness_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: width +//| +//| Gets the width of the framebuffer +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_width(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_width_obj, framebufferio_framebufferdisplay_obj_get_width); + +const mp_obj_property_t framebufferio_framebufferdisplay_width_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_width_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: height +//| +//| Gets the height of the framebuffer +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_height(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_height_obj, framebufferio_framebufferdisplay_obj_get_height); + +const mp_obj_property_t framebufferio_framebufferdisplay_height_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_height_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: rotation +//| +//| The rotation of the display as an int in degrees. +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_rotation(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_framebufferio_framebufferdisplay_get_rotation(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_rotation_obj, framebufferio_framebufferdisplay_obj_get_rotation); +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_rotation(mp_obj_t self_in, mp_obj_t value) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + common_hal_framebufferio_framebufferdisplay_set_rotation(self, mp_obj_get_int(value)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_set_rotation_obj, framebufferio_framebufferdisplay_obj_set_rotation); + + +const mp_obj_property_t framebufferio_framebufferdisplay_rotation_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_rotation_obj, + (mp_obj_t)&framebufferio_framebufferdisplay_set_rotation_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: framebuffer +//| +//| The framebuffer being used by the display +//| +//| +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_get_framebuffer(mp_obj_t self_in) { + framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); + return common_hal_framebufferio_framebufferdisplay_get_framebuffer(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_framebuffer_obj, framebufferio_framebufferdisplay_obj_get_framebuffer); + +const mp_obj_property_t framebufferio_framebufferframebuffer_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&framebufferio_framebufferdisplay_get_framebuffer_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + + +//| .. method:: fill_row(y, buffer) +//| +//| Extract the pixels from a single row +//| +//| :param int y: The top edge of the area +//| :param bytearray buffer: The buffer in which to place the pixel data +STATIC mp_obj_t framebufferio_framebufferdisplay_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_y, ARG_buffer }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_y, MP_ARG_INT | MP_ARG_REQUIRED, {.u_int = -1} }, + { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + }; + 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); + framebufferio_framebufferdisplay_obj_t *self = native_display(pos_args[0]); + mp_int_t y = args[ARG_y].u_int; + mp_obj_t *result = args[ARG_buffer].u_obj; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(result, &bufinfo, MP_BUFFER_WRITE); + + if (bufinfo.typecode != BYTEARRAY_TYPECODE) { + mp_raise_ValueError(translate("Buffer is not a bytearray.")); + } + if (self->core.colorspace.depth != 16) { + mp_raise_ValueError(translate("Display must have a 16 bit colorspace.")); + } + + displayio_area_t area = { + .x1 = 0, + .y1 = y, + .x2 = self->core.width, + .y2 = y + 1 + }; + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + uint16_t buffer_size = self->core.width / pixels_per_word; + uint16_t pixels_per_buffer = displayio_area_size(&area); + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + + uint32_t *result_buffer = bufinfo.buf; + size_t result_buffer_size = bufinfo.len; + + if (result_buffer_size >= (buffer_size * 4)) { + volatile uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + + for (uint16_t k = 0; k < mask_length; k++) { + mask[k] = 0x00000000; + } + + displayio_display_core_fill_area(&self->core, &area, mask, result_buffer); + return result; + } else { + mp_raise_ValueError(translate("Buffer is too small")); + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_fill_row_obj, 1, framebufferio_framebufferdisplay_obj_fill_row); + +STATIC const mp_rom_map_elem_t framebufferio_framebufferdisplay_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&framebufferio_framebufferdisplay_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&framebufferio_framebufferdisplay_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_fill_row), MP_ROM_PTR(&framebufferio_framebufferdisplay_fill_row_obj) }, + + { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&framebufferio_framebufferdisplay_auto_refresh_obj) }, + + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&framebufferio_framebufferdisplay_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_auto_brightness), MP_ROM_PTR(&framebufferio_framebufferdisplay_auto_brightness_obj) }, + + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&framebufferio_framebufferdisplay_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&framebufferio_framebufferdisplay_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_rotation), MP_ROM_PTR(&framebufferio_framebufferdisplay_rotation_obj) }, + { MP_ROM_QSTR(MP_QSTR_framebuffer), MP_ROM_PTR(&framebufferio_framebufferframebuffer_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(framebufferio_framebufferdisplay_locals_dict, framebufferio_framebufferdisplay_locals_dict_table); + +const mp_obj_type_t framebufferio_framebufferdisplay_type = { + { &mp_type_type }, + .name = MP_QSTR_FramebufferDisplay, + .make_new = framebufferio_framebufferdisplay_make_new, + .locals_dict = (mp_obj_dict_t*)&framebufferio_framebufferdisplay_locals_dict, +}; diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h new file mode 100644 index 000000000..af0bd2c41 --- /dev/null +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -0,0 +1,74 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/framebufferio/FramebufferDisplay.h" +#include "shared-module/displayio/Group.h" + +extern const mp_obj_type_t framebufferio_framebufferdisplay_type; + +#define DELAY 0x80 + +#define NO_BRIGHTNESS_COMMAND 0x100 + +void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, + mp_obj_t framebuffer, uint16_t width, uint16_t height, + int16_t colstart, int16_t rowstart, + uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, + uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, + const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, + bool auto_refresh, uint16_t native_frames_per_second); + +bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t* self, + displayio_group_t* root_group); + +bool common_hal_framebufferio_framebufferdisplay_refresh(framebufferio_framebufferdisplay_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame); + +bool common_hal_framebufferio_framebufferdisplay_get_auto_refresh(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_auto_refresh(framebufferio_framebufferdisplay_obj_t* self, bool auto_refresh); + +uint16_t common_hal_framebufferio_framebufferdisplay_get_width(framebufferio_framebufferdisplay_obj_t* self); +uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_framebufferdisplay_obj_t* self); +uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation); + +bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); + +bool common_hal_framebufferio_framebufferdisplay_get_dither(framebufferio_framebufferdisplay_obj_t* self); +void common_hal_framebufferio_framebufferdisplay_set_dither(framebufferio_framebufferdisplay_obj_t* self, bool dither); + +mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self); +bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness); + +mp_obj_t common_hal_framebufferio_framebufferdisplay_framebuffer(framebufferio_framebufferdisplay_obj_t* self); + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_FRAMEBUFFERDISPLAY_H diff --git a/shared-bindings/framebufferio/__init__.c b/shared-bindings/framebufferio/__init__.c new file mode 100644 index 000000000..0f0823a25 --- /dev/null +++ b/shared-bindings/framebufferio/__init__.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "shared-bindings/framebufferio/__init__.h" +#include "shared-bindings/framebufferio/FramebufferDisplay.h" + +//| :mod:`framebufferio` --- Native framebuffer display driving +//| ========================================================================= +//| +//| .. module:: framebufferio +//| :synopsis: Native helpers for driving displays +//| :platform: SAMD51, nRF52 +//| +//| The `framebufferio` module contains classes to manage display output +//| including synchronizing with refresh rates and partial updating. +//| It is used in conjunction with classes from `displayio` to actually +//| place items on the display; and classes like `Protomatter` to actually +//| drive the display. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| FramebufferDisplay +//| + +#if CIRCUITPY_FRAMEBUFFERIO +static const mp_rom_map_elem_t framebufferio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebufferio) }, + { MP_ROM_QSTR(MP_QSTR_FramebufferDisplay), MP_ROM_PTR(&framebufferio_framebufferdisplay_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(framebufferio_module_globals, framebufferio_module_globals_table); +const mp_obj_module_t framebufferio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&framebufferio_module_globals, +}; +#endif + diff --git a/shared-bindings/framebufferio/__init__.h b/shared-bindings/framebufferio/__init__.h new file mode 100644 index 000000000..e69de29bb diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 4f29322a0..bb5256b55 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -43,5 +43,11 @@ void assert_pin_free(const mcu_pin_obj_t* pin); bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin); void common_hal_never_reset_pin(const mcu_pin_obj_t* pin); void common_hal_reset_pin(const mcu_pin_obj_t* pin); +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin); +void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin); +void common_hal_mcu_pin_claim_number(uint8_t pin_no); +void common_hal_mcu_pin_reset_number(uint8_t pin_no); + +#define COMMON_HAL_MCU_NO_PIN ((uint8_t)0xff) #endif // MICROPY_INCLUDED_SHARED_BINDINGS_MICROCONTROLLER_PIN_H diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c new file mode 100644 index 000000000..cbb60db6d --- /dev/null +++ b/shared-module/_protomatter/Protomatter.c @@ -0,0 +1,169 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Jeff Epler for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/gc.h" +#include "py/obj.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "common-hal/_protomatter/Protomatter.h" +#include "shared-module/_protomatter/allocator.h" +#include "shared-bindings/_protomatter/Protomatter.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +extern Protomatter_core *_PM_protoPtr; + +void common_hal_protomatter_protomatter_construct(protomatter_protomatter_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) { + self->width = width; + self->bit_depth = bit_depth; + self->rgb_count = rgb_count; + memcpy(self->rgb_pins, rgb_pins, rgb_count); + self->addr_count = addr_count; + memcpy(self->addr_pins, addr_pins, addr_count); + self->clock_pin = clock_pin; + self->oe_pin = oe_pin; + self->latch_pin = latch_pin; + self->doublebuffer = doublebuffer; + + self->timer = timer ? timer : common_hal_protomatter_timer_allocate(); + if (self->timer == NULL) { + mp_raise_ValueError(translate("No timer available")); + } + + self->width = width; + self->bufsize = 2 * width * rgb_count / 3 * (1 << addr_count); + + common_hal_protomatter_protomatter_reconstruct(self, framebuffer); +} + +void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer) { + if (framebuffer) { + self->framebuffer = framebuffer; + framebuffer = mp_obj_new_bytearray_of_zeros(self->bufsize); + mp_get_buffer_raise(self->framebuffer, &self->bufinfo, MP_BUFFER_READ); + if (mp_get_buffer(self->framebuffer, &self->bufinfo, MP_BUFFER_RW)) { + self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; + } else { + self->bufinfo.typecode = 'H'; + } + // verify that the matrix is big enough + mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize-1), false); + } else { + self->framebuffer = NULL; + self->bufinfo.buf = _PM_allocator_impl(self->bufsize); + self->bufinfo.len = self->bufsize; + self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW; + } + + ProtomatterStatus stat = _PM_init(&self->core, + self->width, self->bit_depth, + 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); + + if (stat == PROTOMATTER_OK) { + _PM_protoPtr = &self->core; + common_hal_mcu_disable_interrupts(); + common_hal_protomatter_timer_enable(self->timer); + stat = _PM_begin(&self->core); + _PM_convert_565(&self->core, self->bufinfo.buf, self->width); + common_hal_mcu_enable_interrupts(); + _PM_swapbuffer_maybe(&self->core); + } + + if (stat != PROTOMATTER_OK) { + // XXX this deinit() actually makes crashy-crashy + // can trigger it by sending inappropriate pins + common_hal_protomatter_protomatter_deinit(self); + switch (stat) { + case PROTOMATTER_ERR_PINS: + mp_raise_ValueError(translate("Invalid pin")); + break; + case PROTOMATTER_ERR_ARG: + mp_raise_ValueError(translate("Invalid argument")); + break; + case PROTOMATTER_ERR_MALLOC: /// should have already been signaled as NLR + default: + mp_raise_msg_varg(&mp_type_RuntimeError, + translate("Protomatter internal error #%d"), (int)stat); + break; + } + } + + self->paused = 0; + +} + +STATIC void free_pin(uint8_t *pin) { + if (*pin != COMMON_HAL_MCU_NO_PIN) { + common_hal_mcu_pin_reset_number(*pin); + } + *pin = COMMON_HAL_MCU_NO_PIN; +} + +STATIC void free_pin_seq(uint8_t *seq, int count) { + for (int i=0; itimer) { + common_hal_protomatter_timer_free(self->timer); + self->timer = 0; + } + + if (_PM_protoPtr == &self->core) { + _PM_protoPtr = NULL; + } + + free_pin_seq(self->rgb_pins, self->rgb_count); + free_pin_seq(self->addr_pins, self->addr_count); + free_pin(&self->clock_pin); + free_pin(&self->latch_pin); + free_pin(&self->oe_pin); + + if (self->core.rgbPins) { + _PM_free(&self->core); + } + + self->base.type = NULL; +} + +void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t* self) { + gc_collect_ptr(self->framebuffer); + gc_collect_ptr(self->core.rgbPins); + gc_collect_ptr(self->core.addr); + gc_collect_ptr(self->core.screenData); +} + diff --git a/shared-module/_protomatter/Protomatter.h b/shared-module/_protomatter/Protomatter.h new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/_protomatter/__init__.c b/shared-module/_protomatter/__init__.c new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/_protomatter/__init__.h b/shared-module/_protomatter/__init__.h new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h new file mode 100644 index 000000000..8d9d7ff96 --- /dev/null +++ b/shared-module/_protomatter/allocator.h @@ -0,0 +1,30 @@ +#ifndef MICROPY_INCLUDED_SHARED_MODULE_PROTOMATTER_ALLOCATOR_H +#define MICROPY_INCLUDED_SHARED_MODULE_PROTOMATTER_ALLOCATOR_H + +#include +#include "py/misc.h" +#include "supervisor/memory.h" + +#define _PM_ALLOCATOR _PM_allocator_impl +#define _PM_FREE _PM_free_impl + +static inline void *_PM_allocator_impl(size_t sz) { + supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); + if (allocation) { + return allocation->ptr; + } else { + return m_malloc(sz + sizeof(void*), true); + } +} + +static inline void _PM_free_impl(void *ptr_in) { + supervisor_allocation *allocation = allocation_from_ptr(ptr_in); + + if (allocation) { + free_memory(allocation); + } else { + m_free(ptr_in); + } +} + +#endif diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index a5d7f0b05..2c9fb6d78 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -47,9 +47,7 @@ uint16_t displayio_colorconverter_compute_rgb565(uint32_t color_rgb888) { uint32_t r5 = (color_rgb888 >> 19); uint32_t g6 = (color_rgb888 >> 10) & 0x3f; uint32_t b5 = (color_rgb888 >> 3) & 0x1f; - uint32_t packed = r5 << 11 | g6 << 5 | b5; - // swap bytes - return __builtin_bswap16(packed); + return r5 << 11 | g6 << 5 | b5; } uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888) { @@ -156,7 +154,12 @@ void displayio_colorconverter_convert(displayio_colorconverter_t *self, const _d } if (colorspace->depth == 16) { - output_color->pixel = displayio_colorconverter_compute_rgb565(pixel); + uint16_t packed = displayio_colorconverter_compute_rgb565(pixel); + if (colorspace->reverse_bytes_in_word) { + // swap bytes + packed = __builtin_bswap16(packed); + } + output_color->pixel = packed; output_color->opaque = true; return; } else if (colorspace->tricolor) { diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c index 2edded927..aaddbb471 100644 --- a/shared-module/displayio/Display.c +++ b/shared-module/displayio/Display.c @@ -46,7 +46,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, mp_obj_t bus, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, - uint8_t bytes_per_cell, bool reverse_pixels_in_byte, uint8_t set_column_command, + uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll, uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command, mp_float_t brightness, bool auto_brightness, @@ -60,7 +60,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self, ram_height = 0xff; } displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, - color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte); + color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte, reverse_bytes_in_word); self->set_column_command = set_column_command; self->set_row_command = set_row_command; diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c index 91d4bb7f9..5b4a8f916 100644 --- a/shared-module/displayio/EPaperDisplay.c +++ b/shared-module/displayio/EPaperDisplay.c @@ -58,7 +58,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t* self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color); } - displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true); + displayio_display_core_construct(&self->core, bus, width, height, ram_width, ram_height, colstart, rowstart, rotation, 1, true, true, 1, true, true); self->set_column_window_command = set_column_window_command; self->set_row_window_command = set_row_window_command; diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index 758fd43fc..da72f250f 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -41,6 +41,7 @@ typedef struct { bool tricolor; bool pixels_in_byte_share_row; bool reverse_pixels_in_byte; + bool reverse_bytes_in_word; bool dither; } _displayio_colorspace_t; diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 4844dfe60..225aa2008 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -47,6 +47,10 @@ void displayio_background(void) { } if (displays[i].display.base.type == &displayio_display_type) { displayio_display_background(&displays[i].display); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_background(&displays[i].framebuffer_display); +#endif } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { displayio_epaperdisplay_background(&displays[i].epaper_display); } @@ -67,6 +71,10 @@ void common_hal_displayio_release_displays(void) { release_display(&displays[i].display); } else if (display_type == &displayio_epaperdisplay_type) { release_epaperdisplay(&displays[i].epaper_display); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (display_type == &framebufferio_framebufferdisplay_type) { + release_framebufferdisplay(&displays[i].framebuffer_display); +#endif } displays[i].display.base.type = &mp_type_NoneType; } @@ -141,6 +149,11 @@ void reset_displays(void) { } } } +#if CIRCUITPY_PROTOMATTER + } else if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { + protomatter_protomatter_obj_t * pm = &displays[i].protomatter; + common_hal_protomatter_protomatter_reconstruct(pm, NULL); +#endif } else { // Not an active display bus. continue; @@ -155,12 +168,24 @@ void reset_displays(void) { } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { displayio_epaperdisplay_obj_t* display = &displays[i].epaper_display; common_hal_displayio_epaperdisplay_show(display, NULL); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_obj_t* display = &displays[i].framebuffer_display; + display->auto_refresh = true; + common_hal_framebufferio_framebufferdisplay_show(display, NULL); +#endif } } } void displayio_gc_collect(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { +#if CIRCUITPY_PROTOMATTER + if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { + protomatter_protomatter_collect_ptrs(&displays[i].protomatter); + } +#endif + if (displays[i].display.base.type == NULL) { continue; } @@ -169,6 +194,10 @@ void displayio_gc_collect(void) { // but this is more precise, and is the only field that needs marking. if (displays[i].display.base.type == &displayio_display_type) { displayio_display_collect_ptrs(&displays[i].display); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_collect_ptrs(&displays[i].framebuffer_display); +#endif } else if (displays[i].epaper_display.base.type == &displayio_epaperdisplay_type) { displayio_epaperdisplay_collect_ptrs(&displays[i].epaper_display); } @@ -309,7 +338,7 @@ void displayio_area_transform_within(bool mirror_x, bool mirror_y, bool transpos } } -primary_display_t *allocate_display() { +primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t display_type = displays[i].display.base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { @@ -317,14 +346,14 @@ primary_display_t *allocate_display() { } } return NULL; +} -primary_display_t *allocate_display_or_raise() { +primary_display_t *allocate_display_or_raise(void) { primary_display_t *result = allocate_display(); - if (!result) { - mp_raise_RuntimeError(translate("Too many displays")); + if (result) { + return result; } -} - + mp_raise_RuntimeError(translate("Too many displays")); } primary_display_t *allocate_display_bus(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 638c2091e..278a5e78f 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -29,20 +29,30 @@ #include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/EPaperDisplay.h" +#if CIRCUITPY_FRAMEBUFFERIO +#include "shared-bindings/framebufferio/FramebufferDisplay.h" +#endif #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/I2CDisplay.h" #include "shared-bindings/displayio/ParallelBus.h" +#include "shared-bindings/_protomatter/Protomatter.h" typedef struct { union { displayio_fourwire_obj_t fourwire_bus; displayio_i2cdisplay_obj_t i2cdisplay_bus; displayio_parallelbus_obj_t parallel_bus; +#if CIRCUITPY_PROTOMATTER + protomatter_protomatter_obj_t protomatter; +#endif }; union { displayio_display_obj_t display; displayio_epaperdisplay_obj_t epaper_display; +#if CIRCUITPY_FRAMEBUFFERIO + framebufferio_framebufferdisplay_obj_t framebuffer_display; +#endif }; } primary_display_t; diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c index 120b70f76..4cc7564d0 100644 --- a/shared-module/displayio/display_core.c +++ b/shared-module/displayio/display_core.c @@ -44,38 +44,42 @@ void displayio_display_core_construct(displayio_display_core_t* self, mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte) { + uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word) { self->colorspace.depth = color_depth; self->colorspace.grayscale = grayscale; self->colorspace.pixels_in_byte_share_row = pixels_in_byte_share_row; self->colorspace.bytes_per_cell = bytes_per_cell; self->colorspace.reverse_pixels_in_byte = reverse_pixels_in_byte; + self->colorspace.reverse_bytes_in_word = reverse_bytes_in_word; self->colorspace.dither = false; self->current_group = NULL; self->colstart = colstart; self->rowstart = rowstart; self->last_refresh = 0; - if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { - self->bus_reset = common_hal_displayio_parallelbus_reset; - self->bus_free = common_hal_displayio_parallelbus_bus_free; - self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; - self->send = common_hal_displayio_parallelbus_send; - self->end_transaction = common_hal_displayio_parallelbus_end_transaction; - } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { - self->bus_reset = common_hal_displayio_fourwire_reset; - self->bus_free = common_hal_displayio_fourwire_bus_free; - self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; - self->send = common_hal_displayio_fourwire_send; - self->end_transaction = common_hal_displayio_fourwire_end_transaction; - } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) { - self->bus_reset = common_hal_displayio_i2cdisplay_reset; - self->bus_free = common_hal_displayio_i2cdisplay_bus_free; - self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction; - self->send = common_hal_displayio_i2cdisplay_send; - self->end_transaction = common_hal_displayio_i2cdisplay_end_transaction; - } else { - mp_raise_ValueError(translate("Unsupported display bus type")); + // (framebufferdisplay already validated its 'bus' is a buffer-protocol object) + if (bus) { + if (MP_OBJ_IS_TYPE(bus, &displayio_parallelbus_type)) { + self->bus_reset = common_hal_displayio_parallelbus_reset; + self->bus_free = common_hal_displayio_parallelbus_bus_free; + self->begin_transaction = common_hal_displayio_parallelbus_begin_transaction; + self->send = common_hal_displayio_parallelbus_send; + self->end_transaction = common_hal_displayio_parallelbus_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_fourwire_type)) { + self->bus_reset = common_hal_displayio_fourwire_reset; + self->bus_free = common_hal_displayio_fourwire_bus_free; + self->begin_transaction = common_hal_displayio_fourwire_begin_transaction; + self->send = common_hal_displayio_fourwire_send; + self->end_transaction = common_hal_displayio_fourwire_end_transaction; + } else if (MP_OBJ_IS_TYPE(bus, &displayio_i2cdisplay_type)) { + self->bus_reset = common_hal_displayio_i2cdisplay_reset; + self->bus_free = common_hal_displayio_i2cdisplay_bus_free; + self->begin_transaction = common_hal_displayio_i2cdisplay_begin_transaction; + self->send = common_hal_displayio_i2cdisplay_send; + self->end_transaction = common_hal_displayio_i2cdisplay_end_transaction; + } else { + mp_raise_ValueError(translate("Unsupported display bus type")); + } } self->bus = bus; diff --git a/shared-module/displayio/display_core.h b/shared-module/displayio/display_core.h index 1c3d0f09c..e4fd62d4a 100644 --- a/shared-module/displayio/display_core.h +++ b/shared-module/displayio/display_core.h @@ -58,7 +58,7 @@ typedef struct { void displayio_display_core_construct(displayio_display_core_t* self, mp_obj_t bus, uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte); + uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word); bool displayio_display_core_show(displayio_display_core_t* self, displayio_group_t* root_group); diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c new file mode 100644 index 000000000..967316c21 --- /dev/null +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -0,0 +1,339 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/framebufferio/FramebufferDisplay.h" + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/display_core.h" +#include "supervisor/shared/display.h" +#include "supervisor/shared/tick.h" +#include "supervisor/usb.h" + +#include +#include + +#include "tick.h" + +void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, + mp_obj_t framebuffer, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, + uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, + uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, + const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, + bool auto_refresh, uint16_t native_frames_per_second) { + // Turn off auto-refresh as we init. + self->auto_refresh = false; + self->framebuffer = framebuffer; + self->framebuffer_protocol = mp_proto_get_or_throw(MP_QSTR_protocol_framebuffer, framebuffer); + + uint16_t ram_width = 0x100; + uint16_t ram_height = 0x100; + + displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, colstart, rowstart, rotation, + color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte, reverse_bytes_in_word); + + self->auto_brightness = auto_brightness; + self->first_manual_refresh = !auto_refresh; + + self->native_frames_per_second = native_frames_per_second; + self->native_ms_per_frame = 1000 / native_frames_per_second; + + supervisor_start_terminal(width, height); + + // Always set the backlight type in case we're reusing memory. + self->backlight_inout.base.type = &mp_type_NoneType; + if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { + pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + common_hal_never_reset_pin(backlight_pin); + } else { + self->backlight_pwm.base.type = &pulseio_pwmout_type; + common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); + } + } + if (!self->auto_brightness && (self->framebuffer_protocol->set_brightness != NULL || self->backlight_inout.base.type != &mp_type_NoneType)) { + common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); + } else { + self->current_brightness = -1.0; + } + + // Set the group after initialization otherwise we may send pixels while we delay in + // initialization. + common_hal_framebufferio_framebufferdisplay_show(self, &circuitpython_splash); + self->auto_refresh = auto_refresh; +} + +bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t* self, displayio_group_t* root_group) { + return displayio_display_core_show(&self->core, root_group); +} + +uint16_t common_hal_framebufferio_framebufferdisplay_get_width(framebufferio_framebufferdisplay_obj_t* self){ + return displayio_display_core_get_width(&self->core); +} + +uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_framebufferdisplay_obj_t* self){ + return displayio_display_core_get_height(&self->core); +} + +bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self) { + return self->auto_brightness; +} + +void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness) { + self->auto_brightness = auto_brightness; +} + +mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self) { + return self->current_brightness; +} + +bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness) { + self->updating_backlight = true; + bool ok = false; + if (self->framebuffer_protocol->set_brightness) { + self->framebuffer_protocol->set_brightness(self->framebuffer, brightness); + ok = true; + } else if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); + ok = true; + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); + ok = true; + } + self->updating_backlight = false; + if (ok) { + self->current_brightness = brightness; + } + return ok; +} + +mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebufferio_framebufferdisplay_obj_t* self) { + return self->framebuffer; +} + +STATIC const displayio_area_t* _get_refresh_areas(framebufferio_framebufferdisplay_obj_t *self) { + if (self->core.full_refresh) { + self->core.area.next = NULL; + return &self->core.area; + } else if (self->core.current_group != NULL) { + return displayio_group_get_refresh_areas(self->core.current_group, NULL); + } + return NULL; +} + +STATIC bool _refresh_area(framebufferio_framebufferdisplay_obj_t* self, const displayio_area_t* area) { + uint16_t buffer_size = 128; // In uint32_ts + + displayio_area_t clipped; + // Clip the area to the display by overlapping the areas. If there is no overlap then we're done. + if (!displayio_display_core_clip_area(&self->core, area, &clipped)) { + return true; + } + uint16_t subrectangles = 1; + uint16_t rows_per_buffer = displayio_area_height(&clipped); + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + uint16_t pixels_per_buffer = displayio_area_size(&clipped); + if (displayio_area_size(&clipped) > buffer_size * pixels_per_word) { + rows_per_buffer = buffer_size * pixels_per_word / displayio_area_width(&clipped); + if (rows_per_buffer == 0) { + rows_per_buffer = 1; + } + // If pixels are packed by column then ensure rows_per_buffer is on a byte boundary. + if (self->core.colorspace.depth < 8 && !self->core.colorspace.pixels_in_byte_share_row) { + uint8_t pixels_per_byte = 8 / self->core.colorspace.depth; + if (rows_per_buffer % pixels_per_byte != 0) { + rows_per_buffer -= rows_per_buffer % pixels_per_byte; + } + } + subrectangles = displayio_area_height(&clipped) / rows_per_buffer; + if (displayio_area_height(&clipped) % rows_per_buffer != 0) { + subrectangles++; + } + pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped); + buffer_size = pixels_per_buffer / pixels_per_word; + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + } + + // Allocated and shared as a uint32_t array so the compiler knows the + // alignment everywhere. + uint32_t buffer[buffer_size]; + uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + uint16_t remaining_rows = displayio_area_height(&clipped); + + for (uint16_t j = 0; j < subrectangles; j++) { + displayio_area_t subrectangle = { + .x1 = clipped.x1, + .y1 = clipped.y1 + rows_per_buffer * j, + .x2 = clipped.x2, + .y2 = clipped.y1 + rows_per_buffer * (j + 1) + }; + if (remaining_rows < rows_per_buffer) { + subrectangle.y2 = subrectangle.y1 + remaining_rows; + } + remaining_rows -= rows_per_buffer; + + memset(mask, 0, mask_length * sizeof(mask[0])); + memset(buffer, 0, buffer_size * sizeof(buffer[0])); + + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + + // COULDDO: this arithmetic only supports multiple-of-8 bpp + uint8_t *dest = self->bufinfo.buf + (subrectangle.y1 * self->core.width + subrectangle.x1) * (self->core.colorspace.depth / 8); + uint8_t *src = (uint8_t*)buffer; + size_t rowsize = (subrectangle.x2 - subrectangle.x1) * (self->core.colorspace.depth / 8); + size_t rowstride = self->core.width * (self->core.colorspace.depth/8); + for (uint16_t i = subrectangle.y1; i < subrectangle.y2; i++) { + memcpy(dest, src, rowsize); + dest += rowstride; + src += rowsize; + } + + // TODO(tannewt): Make refresh displays faster so we don't starve other + // background tasks. + usb_background(); + } + return true; +} + +STATIC void _refresh_display(framebufferio_framebufferdisplay_obj_t* self) { + displayio_display_core_start_refresh(&self->core); + self->framebuffer_protocol->get_bufinfo(self->framebuffer, &self->bufinfo); + const displayio_area_t* current_area = _get_refresh_areas(self); + while (current_area != NULL) { + _refresh_area(self, current_area); + current_area = current_area->next; + } + displayio_display_core_finish_refresh(&self->core); + self->framebuffer_protocol->swapbuffers(self->framebuffer); +} + +void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation){ + bool transposed = (self->core.rotation == 90 || self->core.rotation == 270); + bool will_transposed = (rotation == 90 || rotation == 270); + if(transposed != will_transposed) { + int tmp = self->core.width; + self->core.width = self->core.height; + self->core.height = tmp; + } + displayio_display_core_set_rotation(&self->core, rotation); + supervisor_stop_terminal(); + supervisor_start_terminal(self->core.width, self->core.height); + if (self->core.current_group != NULL) { + displayio_group_update_transform(self->core.current_group, &self->core.transform); + } +} + +uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_framebufferdisplay_obj_t* self){ + return self->core.rotation; +} + + +bool common_hal_framebufferio_framebufferdisplay_refresh(framebufferio_framebufferdisplay_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) { + if (!self->auto_refresh && !self->first_manual_refresh) { + uint64_t current_time = supervisor_ticks_ms64(); + uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; + // Test to see if the real frame time is below our minimum. + if (current_ms_since_real_refresh > maximum_ms_per_real_frame) { + mp_raise_RuntimeError(translate("Below minimum frame rate")); + } + uint32_t current_ms_since_last_call = current_time - self->last_refresh_call; + self->last_refresh_call = current_time; + // Skip the actual refresh to help catch up. + if (current_ms_since_last_call > target_ms_per_frame) { + return false; + } + uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame); + // We're ahead of the game so wait until we align with the frame rate. + while (supervisor_ticks_ms64() - self->last_refresh_call < remaining_time) { + RUN_BACKGROUND_TASKS; + } + } + self->first_manual_refresh = false; + _refresh_display(self); + return true; +} + +bool common_hal_framebufferio_framebufferdisplay_get_auto_refresh(framebufferio_framebufferdisplay_obj_t* self) { + return self->auto_refresh; +} + +void common_hal_framebufferio_framebufferdisplay_set_auto_refresh(framebufferio_framebufferdisplay_obj_t* self, + bool auto_refresh) { + self->first_manual_refresh = !auto_refresh; + self->auto_refresh = auto_refresh; +} + +STATIC void _update_backlight(framebufferio_framebufferdisplay_obj_t* self) { + if (!self->auto_brightness || self->updating_backlight) { + return; + } + if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) { + return; + } + // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target + // should account for ambient light when possible. + common_hal_framebufferio_framebufferdisplay_set_brightness(self, 1.0); + + self->last_backlight_refresh = supervisor_ticks_ms64(); +} + +void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self) { + _update_backlight(self); + + if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) { + _refresh_display(self); + } +} + +void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { + release_display_core(&self->core); + if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { + common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); + common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } + self->framebuffer_protocol->deinit(self->framebuffer); +} + +void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { + self->auto_refresh = true; + self->auto_brightness = true; + common_hal_framebufferio_framebufferdisplay_show(self, NULL); +} + +void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self) { + gc_collect_ptr(self->framebuffer); + displayio_display_core_collect_ptrs(&self->core); +} diff --git a/shared-module/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h new file mode 100644 index 000000000..a5c8607bb --- /dev/null +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H +#define MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H + +#include "py/obj.h" +#include "py/proto.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/pulseio/PWMOut.h" + +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/display_core.h" + +typedef struct { + mp_obj_base_t base; + displayio_display_core_t core; + union { + digitalio_digitalinout_obj_t backlight_inout; + pulseio_pwmout_obj_t backlight_pwm; + }; + mp_obj_t framebuffer; + const struct _framebuffer_p_t *framebuffer_protocol; + mp_buffer_info_t bufinfo; + uint64_t last_backlight_refresh; + uint64_t last_refresh_call; + mp_float_t current_brightness; + uint16_t native_frames_per_second; + uint16_t native_ms_per_frame; + bool auto_refresh; + bool first_manual_refresh; + bool auto_brightness; + bool updating_backlight; +} framebufferio_framebufferdisplay_obj_t; + +void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self); +void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self); +void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self); + +void framebufferio_framebufferdisplay_collect_ptrs(framebufferio_framebufferdisplay_obj_t* self); + +mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebufferio_framebufferdisplay_obj_t* self); + +typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo); +typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t); +typedef void (*framebuffer_deinit_fun)(mp_obj_t); +typedef void (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); + +typedef struct _framebuffer_p_t { + MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer + framebuffer_get_bufinfo_fun get_bufinfo; + framebuffer_swapbuffers_fun swapbuffers; + framebuffer_deinit_fun deinit; + framebuffer_set_brightness_fun set_brightness; +} framebuffer_p_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H diff --git a/shared-module/framebufferio/__init__.c b/shared-module/framebufferio/__init__.c new file mode 100644 index 000000000..e69de29bb diff --git a/shared-module/framebufferio/__init__.h b/shared-module/framebufferio/__init__.h new file mode 100644 index 000000000..e69de29bb diff --git a/tools/convert_release_notes.py b/tools/convert_release_notes.py index 87b7e444b..649184102 100644 --- a/tools/convert_release_notes.py +++ b/tools/convert_release_notes.py @@ -52,6 +52,9 @@ class AdafruitBBCodeRenderer: def double_emphasis(self, text): return "[b]{}[/b]".format(text) + def emphasis(self, text): + return "[b]{}[/b]".format(text) + bbcode = mistune.Markdown(renderer=AdafruitBBCodeRenderer()) print() -- cgit v1.2.3 From 3a94412cd35c39bf30f29cb2b79be3870709c809 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 1 Apr 2020 11:59:15 -0500 Subject: protomatter: more memory allocation fixes - bump supervisor alloc count by 4 (we actually use 5) - move reconstruct to after gc heap is reset - destroy protomatter object entirely if not used by a FramebufferDisplay - ensure previous supervisor allocations are released - zero out pointers so GC can collect them --- shared-module/_protomatter/Protomatter.c | 6 ++++++ shared-module/_protomatter/allocator.h | 4 +--- shared-module/displayio/__init__.c | 16 +++++++++++++++- supervisor/shared/display.c | 9 +++++++++ supervisor/shared/memory.c | 2 +- 5 files changed, 32 insertions(+), 5 deletions(-) (limited to 'shared-module') diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index cbb60db6d..bec9586f8 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -78,6 +78,11 @@ void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_ // verify that the matrix is big enough mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize-1), false); } else { + _PM_FREE(self->bufinfo.buf); + _PM_FREE(self->core.rgbPins); + _PM_FREE(self->core.addr); + _PM_FREE(self->core.screenData); + self->framebuffer = NULL; self->bufinfo.buf = _PM_allocator_impl(self->bufsize); self->bufinfo.len = self->bufsize; @@ -156,6 +161,7 @@ void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t* se if (self->core.rgbPins) { _PM_free(&self->core); } + memset(&self->core, 0, sizeof(self->core)); self->base.type = NULL; } diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 8d9d7ff96..9b7590df3 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -6,7 +6,7 @@ #include "supervisor/memory.h" #define _PM_ALLOCATOR _PM_allocator_impl -#define _PM_FREE _PM_free_impl +#define _PM_FREE(x) (_PM_free_impl((x)), (x)=NULL, (void)0) static inline void *_PM_allocator_impl(size_t sz) { supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); @@ -22,8 +22,6 @@ static inline void _PM_free_impl(void *ptr_in) { if (allocation) { free_memory(allocation); - } else { - m_free(ptr_in); } } diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 225aa2008..dfa3e7473 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -21,6 +21,18 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +STATIC bool any_display_uses_this_protomatter(protomatter_protomatter_obj_t* pm) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_obj_t* display = &displays[i].framebuffer_display; + if (display->framebuffer == pm) { + return true; + } + } + } + return false; +} + // Check for recursive calls to displayio_background. bool displayio_background_in_progress = false; @@ -152,7 +164,9 @@ void reset_displays(void) { #if CIRCUITPY_PROTOMATTER } else if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { protomatter_protomatter_obj_t * pm = &displays[i].protomatter; - common_hal_protomatter_protomatter_reconstruct(pm, NULL); + if(!any_display_uses_this_protomatter(pm)) { + common_hal_protomatter_protomatter_deinit(pm); + } #endif } else { // Not an active display bus. diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 855432d64..050ba6e19 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -29,6 +29,7 @@ #include #include "py/mpstate.h" +#include "shared-module/displayio/__init__.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/TileGrid.h" @@ -112,6 +113,14 @@ void supervisor_display_move_memory(void) { grid->inline_tiles = false; } MP_STATE_VM(terminal_tilegrid_tiles) = NULL; + #if CIRCUITPY_PROTOMATTER + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].protomatter.base.type == &protomatter_Protomatter_type) { + protomatter_protomatter_obj_t * pm = &displays[i].protomatter; + common_hal_protomatter_protomatter_reconstruct(pm, NULL); + } + } + #endif #endif } diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index 51037bd6d..d52334eb4 100755 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -31,7 +31,7 @@ #include "supervisor/shared/display.h" -#define CIRCUITPY_SUPERVISOR_ALLOC_COUNT 8 +#define CIRCUITPY_SUPERVISOR_ALLOC_COUNT (12) static supervisor_allocation allocations[CIRCUITPY_SUPERVISOR_ALLOC_COUNT]; // We use uint32_t* to ensure word (4 byte) alignment. -- cgit v1.2.3 From 1f3821220e396721ab83127f0965032639d613ba Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 1 Apr 2020 16:10:19 -0500 Subject: fix build for non-displayio & non-protomatter targets --- shared-module/displayio/__init__.c | 2 ++ supervisor/shared/display.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index dfa3e7473..21cbfa83a 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -21,6 +21,7 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +#if CIRCUITPY_PROTOMATTER STATIC bool any_display_uses_this_protomatter(protomatter_protomatter_obj_t* pm) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].framebuffer_display.base.type == &framebufferio_framebufferdisplay_type) { @@ -32,6 +33,7 @@ STATIC bool any_display_uses_this_protomatter(protomatter_protomatter_obj_t* pm) } return false; } +#endif // Check for recursive calls to displayio_background. bool displayio_background_in_progress = false; diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index 050ba6e19..cdf710d26 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -29,12 +29,15 @@ #include #include "py/mpstate.h" -#include "shared-module/displayio/__init__.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/displayio/TileGrid.h" #include "supervisor/memory.h" +#if CIRCUITPY_PROTOMATTER +#include "shared-module/displayio/__init__.h" +#endif + extern size_t blinka_bitmap_data[]; extern displayio_bitmap_t blinka_bitmap; extern displayio_group_t circuitpython_splash; -- cgit v1.2.3 From caea4e010fad5e17089fcfdd8dea13699c3727c1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:55:14 -0500 Subject: deinit: Work harder to ensure storage is released at deinit --- shared-module/_protomatter/Protomatter.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'shared-module') diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index bec9586f8..59dac3e6d 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -163,7 +163,14 @@ void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t* se } memset(&self->core, 0, sizeof(self->core)); + // If it was supervisor-allocated, it is supervisor-freed and the pointer + // is zeroed, otherwise the pointer is just zeroed + _PM_FREE(self->bufinfo.buf); self->base.type = NULL; + + // If a framebuffer was passed in to the constructor, NULL the reference + // here so that it will become GC'able + self->framebuffer = NULL; } void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t* self) { -- cgit v1.2.3 From a663a7dd30d2cfed78644dcaa6e5ef25566acd82 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:52:50 -0500 Subject: _protomatter: move get/set paused into shared-module --- shared-bindings/_protomatter/Protomatter.c | 11 +++-------- shared-bindings/_protomatter/Protomatter.h | 2 ++ shared-module/_protomatter/Protomatter.c | 12 ++++++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 3c790ff7d..b7b28630d 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -193,7 +193,7 @@ static void check_for_deinit(protomatter_protomatter_obj_t *self) { STATIC mp_obj_t protomatter_protomatter_get_paused(mp_obj_t self_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - return mp_obj_new_bool(self->paused); + return mp_obj_new_bool(common_hal_protomatter_protomatter_get_paused(self)); } MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_paused_obj, protomatter_protomatter_get_paused); @@ -201,12 +201,7 @@ STATIC mp_obj_t protomatter_protomatter_set_paused(mp_obj_t self_in, mp_obj_t va protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); bool paused = mp_obj_is_true(value_in); - if (paused && !self->paused) { - _PM_stop(&self->core); - } else if (!paused && self->paused) { - _PM_resume(&self->core); - } - self->paused = paused; + common_hal_protomatter_protomatter_set_paused(self, paused); return mp_const_none; } @@ -262,7 +257,7 @@ STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { } STATIC void protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { - protomatter_protomatter_set_paused(self_in, mp_obj_new_bool(value <= 0)); + common_hal_protomatter_protomatter_set_paused(self_in, value <= 0); } STATIC const framebuffer_p_t protomatter_protomatter_proto = { diff --git a/shared-bindings/_protomatter/Protomatter.h b/shared-bindings/_protomatter/Protomatter.h index cacc39a30..0a52c556f 100644 --- a/shared-bindings/_protomatter/Protomatter.h +++ b/shared-bindings/_protomatter/Protomatter.h @@ -52,5 +52,7 @@ void common_hal_protomatter_protomatter_construct(protomatter_protomatter_obj_t* void common_hal_protomatter_protomatter_deinit(protomatter_protomatter_obj_t*); void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t*); void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer); +void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t* self, bool paused); +bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self); #endif diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index 59dac3e6d..9f67bfad3 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -180,3 +180,15 @@ void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t* self) { gc_collect_ptr(self->core.screenData); } +void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t* self, bool paused) { + if (paused && !self->paused) { + _PM_stop(&self->core); + } else if (!paused && self->paused) { + _PM_resume(&self->core); + } + self->paused = paused; +} + +bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self) { + return self->paused; +} -- cgit v1.2.3 From baf04b7738bdcf234eecad9e03904c1cadc44f50 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 3 Apr 2020 10:59:06 -0500 Subject: FramebufferDisplay: remove probably not needed constructor arguments --- shared-bindings/framebufferio/FramebufferDisplay.c | 25 ++++------------------ shared-bindings/framebufferio/FramebufferDisplay.h | 5 ++--- shared-module/framebufferio/FramebufferDisplay.c | 10 ++++----- 3 files changed, 11 insertions(+), 29 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 9f1df8bfa..9b761dd2d 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -54,20 +54,12 @@ //| //| :param framebuffer: The framebuffer that the display is connected to //| :type framebuffer: any core object implementing the framebuffer protocol -//| :param callback: Function or bound method to call when the framebuffer has been updated. The callback receives one argument, the framebuffer object. //| :param int width: Width in pixels //| :param int height: Height in pixels -//| :param int colstart: The index if the first visible column -//| :param int rowstart: The index if the first visible row //| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) //| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays //| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) -//| :param bool grayscale: True if the display only shows a single color. -//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column. //| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row. -//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) -//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.) -//| :param bool reverse_bytes_in_word: Reverses the order of bytes within a word when color_depth == 16 //| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight //| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True. //| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism. @@ -75,20 +67,14 @@ //| :param int native_frames_per_second: Number of display refreshes per second //| STATIC mp_obj_t framebufferio_framebufferdisplay_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_framebuffer, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; + enum { ARG_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, { MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, - { MP_QSTR_colstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - { MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, - { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, - { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, - { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, - { MP_QSTR_reverse_bytes_in_word, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, @@ -117,12 +103,9 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t self, framebuffer, args[ARG_width].u_int, args[ARG_height].u_int, - args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, - args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool, - args[ARG_pixels_in_byte_share_row].u_bool, - args[ARG_bytes_per_cell].u_bool, - args[ARG_reverse_pixels_in_byte].u_bool, - args[ARG_reverse_bytes_in_word].u_bool, + rotation, + args[ARG_color_depth].u_int, + args[ARG_bytes_per_cell].u_int, MP_OBJ_TO_PTR(backlight_pin), brightness, args[ARG_auto_brightness].u_bool, diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index af0bd2c41..b63439e0c 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -40,9 +40,8 @@ extern const mp_obj_type_t framebufferio_framebufferdisplay_type; void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, mp_obj_t framebuffer, uint16_t width, uint16_t height, - int16_t colstart, int16_t rowstart, - uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, - uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, + uint16_t rotation, uint16_t color_depth, + uint8_t bytes_per_cell, const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second); diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index 967316c21..ec2fe7b31 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -42,9 +42,9 @@ #include "tick.h" void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t* self, - mp_obj_t framebuffer, uint16_t width, uint16_t height, int16_t colstart, int16_t rowstart, - uint16_t rotation, uint16_t color_depth, bool grayscale, bool pixels_in_byte_share_row, - uint8_t bytes_per_cell, bool reverse_pixels_in_byte, bool reverse_bytes_in_word, + mp_obj_t framebuffer, uint16_t width, uint16_t height, + uint16_t rotation, uint16_t color_depth, + uint8_t bytes_per_cell, const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second) { // Turn off auto-refresh as we init. @@ -55,8 +55,8 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu uint16_t ram_width = 0x100; uint16_t ram_height = 0x100; - displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, colstart, rowstart, rotation, - color_depth, grayscale, pixels_in_byte_share_row, bytes_per_cell, reverse_pixels_in_byte, reverse_bytes_in_word); + displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, 0, 0, rotation, + color_depth, false, false, bytes_per_cell, false, false); self->auto_brightness = auto_brightness; self->first_manual_refresh = !auto_refresh; -- cgit v1.2.3 From 0ca270172f36817c14790eb87053e3c326001822 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 7 Apr 2020 11:19:24 -0500 Subject: protomatter: allocator: Never supervisor-alloc while gc available This may have been contributing to fragmentation of the supervisor heap --- shared-module/_protomatter/allocator.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'shared-module') diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 9b7590df3..501a26098 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -2,6 +2,7 @@ #define MICROPY_INCLUDED_SHARED_MODULE_PROTOMATTER_ALLOCATOR_H #include +#include "py/gc.h" #include "py/misc.h" #include "supervisor/memory.h" @@ -9,11 +10,11 @@ #define _PM_FREE(x) (_PM_free_impl((x)), (x)=NULL, (void)0) static inline void *_PM_allocator_impl(size_t sz) { - supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); - if (allocation) { - return allocation->ptr; - } else { + if (gc_alloc_possible()) { return m_malloc(sz + sizeof(void*), true); + } else { + supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); + return allocation ? allocation->ptr : NULL; } } -- cgit v1.2.3 From 5dae23c0e787e38ea737f8333a1ad85a1de5184d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 7 Apr 2020 11:19:47 -0500 Subject: protomatter: release the protomatter object during release_displays() --- shared-module/displayio/__init__.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'shared-module') diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 21cbfa83a..cf1bc45d9 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -102,6 +102,10 @@ void common_hal_displayio_release_displays(void) { common_hal_displayio_i2cdisplay_deinit(&displays[i].i2cdisplay_bus); } else if (bus_type == &displayio_parallelbus_type) { common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); +#if CIRCUITPY_FRAMEBUFFERIO + } else if (bus_type == &protomatter_Protomatter_type) { + common_hal_protomatter_protomatter_deinit(&displays[i].protomatter); +#endif } displays[i].fourwire_bus.base.type = &mp_type_NoneType; } -- cgit v1.2.3 From e4c6b241a94c6828710faa00e1ac9188c26667eb Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 9 Apr 2020 09:11:55 -0500 Subject: protomatter: Use low end of supervisor heap Per @tannewt, this area "sees more churn", so it's probably the right choice here --- shared-module/_protomatter/allocator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-module') diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 501a26098..1ae127de2 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -13,7 +13,7 @@ static inline void *_PM_allocator_impl(size_t sz) { if (gc_alloc_possible()) { return m_malloc(sz + sizeof(void*), true); } else { - supervisor_allocation *allocation = allocate_memory(align32_size(sz), true); + supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); return allocation ? allocation->ptr : NULL; } } -- cgit v1.2.3 From ba20bc8b4322373ec9ed55ed9f299675ea2801f8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 10 Apr 2020 09:07:06 -0500 Subject: framebufferio: move backlight down to the underlying framebuffer --- shared-bindings/_protomatter/Protomatter.c | 3 +- shared-bindings/framebufferio/FramebufferDisplay.c | 17 ++---- shared-bindings/framebufferio/FramebufferDisplay.h | 3 +- shared-module/framebufferio/FramebufferDisplay.c | 65 +++++----------------- shared-module/framebufferio/FramebufferDisplay.h | 15 +++-- 5 files changed, 28 insertions(+), 75 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index f6ac19188..50480004c 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -317,8 +317,9 @@ STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { protomatter_protomatter_deinit(self_in); } -STATIC void protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { +STATIC bool protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { common_hal_protomatter_protomatter_set_paused(self_in, value <= 0); + return true; } STATIC const framebuffer_p_t protomatter_protomatter_proto = { diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 9b761dd2d..538d3afb4 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -67,7 +67,7 @@ //| :param int native_frames_per_second: Number of display refreshes per second //| STATIC mp_obj_t framebufferio_framebufferdisplay_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_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_backlight_pin, ARG_brightness, ARG_auto_brightness, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; + enum { ARG_framebuffer, ARG_width, ARG_height, ARG_rotation, ARG_color_depth, ARG_bytes_per_cell, ARG_auto_refresh, ARG_native_frames_per_second, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_framebuffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, }, @@ -75,9 +75,6 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t { MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, - { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, - { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_auto_refresh, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, }; @@ -87,10 +84,6 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t mp_obj_t framebuffer = args[ARG_framebuffer].u_obj; - const mcu_pin_obj_t* backlight_pin = validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj); - - mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); - mp_int_t rotation = args[ARG_rotation].u_int; if (rotation % 90 != 0) { mp_raise_ValueError(translate("Display rotation must be in 90 degree increments")); @@ -106,9 +99,6 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *t rotation, args[ARG_color_depth].u_int, args[ARG_bytes_per_cell].u_int, - MP_OBJ_TO_PTR(backlight_pin), - brightness, - args[ARG_auto_brightness].u_bool, args[ARG_auto_refresh].u_bool, args[ARG_native_frames_per_second].u_int ); @@ -260,7 +250,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(framebufferio_framebufferdisplay_get_auto_brightness_o STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); - common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + bool ok = common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, mp_obj_is_true(auto_brightness)); + if (!ok) { + mp_raise_RuntimeError(translate("Brightness not adjustable")); + } return mp_const_none; } diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index b63439e0c..56ef8abc4 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -42,7 +42,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu mp_obj_t framebuffer, uint16_t width, uint16_t height, uint16_t rotation, uint16_t color_depth, uint8_t bytes_per_cell, - const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second); bool common_hal_framebufferio_framebufferdisplay_show(framebufferio_framebufferdisplay_obj_t* self, @@ -59,7 +58,7 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_ void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_framebufferdisplay_obj_t* self, int rotation); bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self); -void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); +bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); bool common_hal_framebufferio_framebufferdisplay_get_dither(framebufferio_framebufferdisplay_obj_t* self); void common_hal_framebufferio_framebufferdisplay_set_dither(framebufferio_framebufferdisplay_obj_t* self, bool dither); diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index ec2fe7b31..bd0764e8e 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -45,7 +45,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu mp_obj_t framebuffer, uint16_t width, uint16_t height, uint16_t rotation, uint16_t color_depth, uint8_t bytes_per_cell, - const mcu_pin_obj_t* backlight_pin, mp_float_t brightness, bool auto_brightness, bool auto_refresh, uint16_t native_frames_per_second) { // Turn off auto-refresh as we init. self->auto_refresh = false; @@ -58,7 +57,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu displayio_display_core_construct(&self->core, NULL, width, height, ram_width, ram_height, 0, 0, rotation, color_depth, false, false, bytes_per_cell, false, false); - self->auto_brightness = auto_brightness; self->first_manual_refresh = !auto_refresh; self->native_frames_per_second = native_frames_per_second; @@ -66,25 +64,6 @@ void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebu supervisor_start_terminal(width, height); - // Always set the backlight type in case we're reusing memory. - self->backlight_inout.base.type = &mp_type_NoneType; - if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { - pwmout_result_t result = common_hal_pulseio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); - if (result != PWMOUT_OK) { - self->backlight_inout.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); - common_hal_never_reset_pin(backlight_pin); - } else { - self->backlight_pwm.base.type = &pulseio_pwmout_type; - common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm); - } - } - if (!self->auto_brightness && (self->framebuffer_protocol->set_brightness != NULL || self->backlight_inout.base.type != &mp_type_NoneType)) { - common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); - } else { - self->current_brightness = -1.0; - } - // Set the group after initialization otherwise we may send pixels while we delay in // initialization. common_hal_framebufferio_framebufferdisplay_show(self, &circuitpython_splash); @@ -104,33 +83,31 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_height(framebufferio_fr } bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self) { - return self->auto_brightness; + if (self->framebuffer_protocol->get_auto_brightness) { + return self->framebuffer_protocol->get_auto_brightness(self->framebuffer); + } + return true; } -void common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness) { - self->auto_brightness = auto_brightness; +bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness) { + if (self->framebuffer_protocol->set_auto_brightness) { + return self->framebuffer_protocol->set_auto_brightness(self->framebuffer, auto_brightness); + } + return false; } mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self) { - return self->current_brightness; + if (self->framebuffer_protocol->set_brightness) { + return self->framebuffer_protocol->get_brightness(self->framebuffer); + } + return -1; } bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness) { - self->updating_backlight = true; bool ok = false; if (self->framebuffer_protocol->set_brightness) { self->framebuffer_protocol->set_brightness(self->framebuffer, brightness); ok = true; - } else if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - common_hal_pulseio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t) (0xffff * brightness)); - ok = true; - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); - ok = true; - } - self->updating_backlight = false; - if (ok) { - self->current_brightness = brightness; } return ok; } @@ -295,17 +272,8 @@ void common_hal_framebufferio_framebufferdisplay_set_auto_refresh(framebufferio_ } STATIC void _update_backlight(framebufferio_framebufferdisplay_obj_t* self) { - if (!self->auto_brightness || self->updating_backlight) { - return; - } - if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) { - return; - } // TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target // should account for ambient light when possible. - common_hal_framebufferio_framebufferdisplay_set_brightness(self, 1.0); - - self->last_backlight_refresh = supervisor_ticks_ms64(); } void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self) { @@ -318,18 +286,11 @@ void framebufferio_framebufferdisplay_background(framebufferio_framebufferdispla void release_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { release_display_core(&self->core); - if (self->backlight_pwm.base.type == &pulseio_pwmout_type) { - common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm); - common_hal_pulseio_pwmout_deinit(&self->backlight_pwm); - } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { - common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); - } self->framebuffer_protocol->deinit(self->framebuffer); } void reset_framebufferdisplay(framebufferio_framebufferdisplay_obj_t* self) { self->auto_refresh = true; - self->auto_brightness = true; common_hal_framebufferio_framebufferdisplay_show(self, NULL); } diff --git a/shared-module/framebufferio/FramebufferDisplay.h b/shared-module/framebufferio/FramebufferDisplay.h index a5c8607bb..a7b91a522 100644 --- a/shared-module/framebufferio/FramebufferDisplay.h +++ b/shared-module/framebufferio/FramebufferDisplay.h @@ -40,22 +40,15 @@ typedef struct { mp_obj_base_t base; displayio_display_core_t core; - union { - digitalio_digitalinout_obj_t backlight_inout; - pulseio_pwmout_obj_t backlight_pwm; - }; mp_obj_t framebuffer; const struct _framebuffer_p_t *framebuffer_protocol; mp_buffer_info_t bufinfo; uint64_t last_backlight_refresh; uint64_t last_refresh_call; - mp_float_t current_brightness; uint16_t native_frames_per_second; uint16_t native_ms_per_frame; bool auto_refresh; bool first_manual_refresh; - bool auto_brightness; - bool updating_backlight; } framebufferio_framebufferdisplay_obj_t; void framebufferio_framebufferdisplay_background(framebufferio_framebufferdisplay_obj_t* self); @@ -69,14 +62,20 @@ mp_obj_t common_hal_framebufferio_framebufferdisplay_get_framebuffer(framebuffer typedef void (*framebuffer_get_bufinfo_fun)(mp_obj_t, mp_buffer_info_t *bufinfo); typedef void (*framebuffer_swapbuffers_fun)(mp_obj_t); typedef void (*framebuffer_deinit_fun)(mp_obj_t); -typedef void (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); +typedef bool (*framebuffer_set_brightness_fun)(mp_obj_t, mp_float_t); +typedef mp_float_t (*framebuffer_get_brightness_fun)(mp_obj_t); +typedef bool (*framebuffer_set_auto_brightness_fun)(mp_obj_t, bool); +typedef bool (*framebuffer_get_auto_brightness_fun)(mp_obj_t); typedef struct _framebuffer_p_t { MP_PROTOCOL_HEAD // MP_QSTR_protocol_framebuffer framebuffer_get_bufinfo_fun get_bufinfo; framebuffer_swapbuffers_fun swapbuffers; framebuffer_deinit_fun deinit; + framebuffer_get_brightness_fun get_brightness; framebuffer_set_brightness_fun set_brightness; + framebuffer_get_auto_brightness_fun get_auto_brightness; + framebuffer_set_auto_brightness_fun set_auto_brightness; } framebuffer_p_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_DISPLAYIO_FRAMEBUFFERDISPLAY_H -- cgit v1.2.3 From 880fff80e904ef4b173d551742b7acde56114f0c Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 13 Apr 2020 08:51:35 -0500 Subject: protomatter: Respond to review comments - rename oe_pin -> output_enable_pin - improve and reorganize docstrings - rename swapbuffers->refresh - rename "paused" -> "brightness", change semantics slightly - common_hal several functions - clarify why the common_hal routines can't be used directly in the protocol's function pointers - whitespace cleanups - remove prototypes for nonexistent functions --- shared-bindings/_protomatter/Protomatter.c | 108 +++++++++++---------- shared-bindings/_protomatter/Protomatter.h | 1 + shared-bindings/framebufferio/FramebufferDisplay.c | 2 +- shared-bindings/framebufferio/FramebufferDisplay.h | 3 - shared-module/_protomatter/Protomatter.c | 10 +- shared-module/_protomatter/allocator.h | 4 +- 6 files changed, 71 insertions(+), 57 deletions(-) (limited to 'shared-module') diff --git a/shared-bindings/_protomatter/Protomatter.c b/shared-bindings/_protomatter/Protomatter.c index 3b3fdae8c..cfc0ba6ed 100644 --- a/shared-bindings/_protomatter/Protomatter.c +++ b/shared-bindings/_protomatter/Protomatter.c @@ -135,7 +135,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| :class:`~_protomatter.Protomatter` displays an in-memory framebuffer to an LED matrix. //| -//| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, oe_pin, *, doublebuffer=True, framebuffer=None) +//| .. class:: Protomatter(width, bit_depth, rgb_pins, addr_pins, clock_pin, latch_pin, output_enable_pin, *, doublebuffer=True, framebuffer=None) //| //| Create a Protomatter object with the given attributes. The height of //| the display is determined by the number of rgb and address pins: @@ -153,12 +153,17 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| microcontroller board. For instance, the Feather M4 Express works //| together with the RGB Matrix Feather. //| -//| When specified as True, double buffering can reduce some flickering of -//| the matrix; however, this increases memory usage. +//| The framebuffer is in "RGB565" format. //| -//| The framebuffer is in "RGB565" format. If a framebuffer is not -//| passed in, one is allocated and initialized to all black. To update -//| the content, modify the framebuffer and call swapbuffers. +//| "RGB565" means that it is organized as a series of 16-bit numbers +//| where the highest 5 bits are interpreted as red, the next 6 as +//| green, and the final 5 as blue. The object can be any buffer, but +//| `array.array` and `ulab.array` objects are most often useful. +//| To update the content, modify the framebuffer and call refresh. +//| +//| If a framebuffer is not passed in, one is allocated and initialized +//| to all black. In any case, the framebuffer can be retrieved +//| by passing the protomatter object to memoryview(). //| //| If doublebuffer is False, some memory is saved, but the display may //| flicker during updates. @@ -166,10 +171,13 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| If a framebuffer is not passed in, one is allocated internally. To //| retrieve it, pass the protomatter object to memoryview(). //| +//| A Protomatter framebuffer is often used in conjunction with a +//| `framebufferio.FramebufferDisplay`. +//| STATIC mp_obj_t protomatter_protomatter_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_oe_pin, ARG_doublebuffer, ARG_framebuffer }; + ARG_clock_pin, ARG_latch_pin, ARG_output_enable_pin, ARG_doublebuffer, ARG_framebuffer }; static const mp_arg_t allowed_args[] = { { MP_QSTR_width, MP_ARG_INT | MP_ARG_REQUIRED }, { MP_QSTR_bit_depth, MP_ARG_INT | MP_ARG_REQUIRED }, @@ -177,7 +185,7 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size { MP_QSTR_addr_pins, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_clock_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_latch_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_oe_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_output_enable_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_doublebuffer, MP_ARG_BOOL, { .u_bool = true } }, { MP_QSTR_framebuffer, MP_ARG_OBJ, { .u_obj = mp_const_none } }, }; @@ -195,7 +203,7 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size uint8_t addr_pins[MP_ARRAY_SIZE(self->addr_pins)]; uint8_t clock_pin = validate_pin(args[ARG_clock_pin].u_obj); uint8_t latch_pin = validate_pin(args[ARG_latch_pin].u_obj); - uint8_t oe_pin = validate_pin(args[ARG_oe_pin].u_obj); + uint8_t output_enable_pin = validate_pin(args[ARG_output_enable_pin].u_obj); validate_pins(MP_QSTR_rgb_pins, rgb_pins, MP_ARRAY_SIZE(self->rgb_pins), args[ARG_rgb_list].u_obj, &rgb_count); validate_pins(MP_QSTR_addr_pins, addr_pins, MP_ARRAY_SIZE(self->addr_pins), args[ARG_addr_list].u_obj, &addr_count); @@ -214,14 +222,14 @@ STATIC mp_obj_t protomatter_protomatter_make_new(const mp_obj_type_t *type, size args[ARG_bit_depth].u_int, rgb_count, rgb_pins, addr_count, addr_pins, - clock_pin, latch_pin, oe_pin, + clock_pin, latch_pin, output_enable_pin, args[ARG_doublebuffer].u_bool, framebuffer, NULL); claim_and_never_reset_pins(args[ARG_rgb_list].u_obj); claim_and_never_reset_pins(args[ARG_addr_list].u_obj); claim_and_never_reset_pin(args[ARG_clock_pin].u_obj); - claim_and_never_reset_pin(args[ARG_oe_pin].u_obj); + claim_and_never_reset_pin(args[ARG_output_enable_pin].u_obj); claim_and_never_reset_pin(args[ARG_latch_pin].u_obj); return MP_OBJ_FROM_PTR(self); @@ -247,79 +255,80 @@ static void check_for_deinit(protomatter_protomatter_obj_t *self) { } } -//| .. attribute:: paused +//| .. attribute:: brightness //| -//| When paused, the matrix is not driven and all its LEDs are unlit. +//| In the current implementation, 0.0 turns the display off entirely +//| and any other value up to 1.0 turns the display on fully. //| -STATIC mp_obj_t protomatter_protomatter_get_paused(mp_obj_t self_in) { +STATIC mp_obj_t protomatter_protomatter_get_brightness(mp_obj_t self_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - return mp_obj_new_bool(common_hal_protomatter_protomatter_get_paused(self)); + return mp_obj_new_float(common_hal_protomatter_protomatter_get_paused(self)? 0.0f : 1.0f); } -MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_paused_obj, protomatter_protomatter_get_paused); +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_get_brightness_obj, protomatter_protomatter_get_brightness); -STATIC mp_obj_t protomatter_protomatter_set_paused(mp_obj_t self_in, mp_obj_t value_in) { +STATIC mp_obj_t protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_obj_t value_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - bool paused = mp_obj_is_true(value_in); - common_hal_protomatter_protomatter_set_paused(self, paused); + mp_float_t brightness = mp_obj_get_float(value_in); + if (brightness < 0.0f || brightness > 1.0f) { + mp_raise_ValueError(translate("Brightness must be 0-1.0")); + } + common_hal_protomatter_protomatter_set_paused(self_in, brightness <= 0); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(protomatter_protomatter_set_paused_obj, protomatter_protomatter_set_paused); +MP_DEFINE_CONST_FUN_OBJ_2(protomatter_protomatter_set_brightness_obj, protomatter_protomatter_set_brightness); -const mp_obj_property_t protomatter_protomatter_paused_obj = { +const mp_obj_property_t protomatter_protomatter_brightness_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&protomatter_protomatter_get_paused_obj, - (mp_obj_t)&protomatter_protomatter_set_paused_obj, + .proxy = {(mp_obj_t)&protomatter_protomatter_get_brightness_obj, + (mp_obj_t)&protomatter_protomatter_set_brightness_obj, (mp_obj_t)&mp_const_none_obj}, }; -//| .. method:: swapbuffers() -//| -//| Transmits the color data in the buffer to the pixels so that they are shown. +//| .. method:: refresh() //| -//| The data in the buffer must be in "RGB565" format. This means -//| that it is organized as a series of 16-bit numbers where the highest 5 -//| bits are interpreted as red, the next 6 as green, and the final 5 as -//| blue. The object can be any buffer, but `array.array` and `ulab.array` -//| objects are most often useful. +//| Transmits the color data in the buffer to the pixels so that +//| they are shown. //| -STATIC mp_obj_t protomatter_protomatter_swapbuffers(mp_obj_t self_in) { +STATIC mp_obj_t protomatter_protomatter_refresh(mp_obj_t self_in) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - - _PM_convert_565(&self->core, self->bufinfo.buf, self->width); - _PM_swapbuffer_maybe(&self->core); + common_hal_protomatter_protomatter_refresh(self); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_swapbuffers_obj, protomatter_protomatter_swapbuffers); +MP_DEFINE_CONST_FUN_OBJ_1(protomatter_protomatter_refresh_obj, protomatter_protomatter_refresh); STATIC const mp_rom_map_elem_t protomatter_protomatter_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&protomatter_protomatter_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&protomatter_protomatter_paused_obj) }, - { MP_ROM_QSTR(MP_QSTR_swapbuffers), MP_ROM_PTR(&protomatter_protomatter_swapbuffers_obj) }, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&protomatter_protomatter_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&protomatter_protomatter_refresh_obj) }, }; STATIC MP_DEFINE_CONST_DICT(protomatter_protomatter_locals_dict, protomatter_protomatter_locals_dict_table); STATIC void protomatter_protomatter_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { protomatter_protomatter_obj_t *self = (protomatter_protomatter_obj_t*)self_in; check_for_deinit(self); - + *bufinfo = self->bufinfo; } -// This version exists so that the return value of the function can be none, matching the protocol -STATIC void protomatter_protomatter_swapbuffers_void(mp_obj_t self_in) { - protomatter_protomatter_swapbuffers(self_in); +// These version exists so that the prototype matches the protocol, +// avoiding a type cast that can hide errors +STATIC void protomatter_protomatter_swapbuffers(mp_obj_t self_in) { + common_hal_protomatter_protomatter_refresh(self_in); +} + +STATIC void protomatter_protomatter_deinit_proto(mp_obj_t self_in) { + common_hal_protomatter_protomatter_deinit(self_in); } -// This version exists so that the return value of the function can be none, matching the protocol -STATIC void protomatter_protomatter_deinit_void(mp_obj_t self_in) { - protomatter_protomatter_deinit(self_in); +STATIC float protomatter_protomatter_get_brightness_proto(mp_obj_t self_in) { + return common_hal_protomatter_protomatter_get_paused(self_in) ? 0.0f : 1.0f; } -STATIC bool protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t value) { +STATIC bool protomatter_protomatter_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { common_hal_protomatter_protomatter_set_paused(self_in, value <= 0); return true; } @@ -327,9 +336,10 @@ STATIC bool protomatter_protomatter_set_brightness(mp_obj_t self_in, mp_float_t STATIC const framebuffer_p_t protomatter_protomatter_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) .get_bufinfo = protomatter_protomatter_get_bufinfo, - .set_brightness = protomatter_protomatter_set_brightness, - .swapbuffers = protomatter_protomatter_swapbuffers_void, - .deinit = protomatter_protomatter_deinit_void, + .set_brightness = protomatter_protomatter_set_brightness_proto, + .get_brightness = protomatter_protomatter_get_brightness_proto, + .swapbuffers = protomatter_protomatter_swapbuffers, + .deinit = protomatter_protomatter_deinit_proto, }; STATIC mp_int_t protomatter_protomatter_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { diff --git a/shared-bindings/_protomatter/Protomatter.h b/shared-bindings/_protomatter/Protomatter.h index 0a52c556f..9499da22c 100644 --- a/shared-bindings/_protomatter/Protomatter.h +++ b/shared-bindings/_protomatter/Protomatter.h @@ -54,5 +54,6 @@ void protomatter_protomatter_collect_ptrs(protomatter_protomatter_obj_t*); void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_t* self, mp_obj_t framebuffer); void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t* self, bool paused); bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self); +void common_hal_protomatter_protomatter_refresh(protomatter_protomatter_obj_t* self); #endif diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 538d3afb4..aa8fc1a63 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -216,7 +216,7 @@ STATIC mp_obj_t framebufferio_framebufferdisplay_obj_set_brightness(mp_obj_t sel framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); common_hal_framebufferio_framebufferdisplay_set_auto_brightness(self, false); mp_float_t brightness = mp_obj_get_float(brightness_obj); - if (brightness < 0 || brightness > 1.0) { + if (brightness < 0.0f || brightness > 1.0f) { mp_raise_ValueError(translate("Brightness must be 0-1.0")); } bool ok = common_hal_framebufferio_framebufferdisplay_set_brightness(self, brightness); diff --git a/shared-bindings/framebufferio/FramebufferDisplay.h b/shared-bindings/framebufferio/FramebufferDisplay.h index 56ef8abc4..b472088d2 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.h +++ b/shared-bindings/framebufferio/FramebufferDisplay.h @@ -60,9 +60,6 @@ void common_hal_framebufferio_framebufferdisplay_set_rotation(framebufferio_fram bool common_hal_framebufferio_framebufferdisplay_get_auto_brightness(framebufferio_framebufferdisplay_obj_t* self); bool common_hal_framebufferio_framebufferdisplay_set_auto_brightness(framebufferio_framebufferdisplay_obj_t* self, bool auto_brightness); -bool common_hal_framebufferio_framebufferdisplay_get_dither(framebufferio_framebufferdisplay_obj_t* self); -void common_hal_framebufferio_framebufferdisplay_set_dither(framebufferio_framebufferdisplay_obj_t* self, bool dither); - mp_float_t common_hal_framebufferio_framebufferdisplay_get_brightness(framebufferio_framebufferdisplay_obj_t* self); bool common_hal_framebufferio_framebufferdisplay_set_brightness(framebufferio_framebufferdisplay_obj_t* self, mp_float_t brightness); diff --git a/shared-module/_protomatter/Protomatter.c b/shared-module/_protomatter/Protomatter.c index 9f67bfad3..77ca63476 100644 --- a/shared-module/_protomatter/Protomatter.c +++ b/shared-module/_protomatter/Protomatter.c @@ -53,7 +53,7 @@ void common_hal_protomatter_protomatter_construct(protomatter_protomatter_obj_t self->oe_pin = oe_pin; self->latch_pin = latch_pin; self->doublebuffer = doublebuffer; - + self->timer = timer ? timer : common_hal_protomatter_timer_allocate(); if (self->timer == NULL) { mp_raise_ValueError(translate("No timer available")); @@ -90,7 +90,7 @@ void common_hal_protomatter_protomatter_reconstruct(protomatter_protomatter_obj_ } ProtomatterStatus stat = _PM_init(&self->core, - self->width, self->bit_depth, + self->width, self->bit_depth, self->rgb_count/6, self->rgb_pins, self->addr_count, self->addr_pins, self->clock_pin, self->latch_pin, self->oe_pin, @@ -192,3 +192,9 @@ void common_hal_protomatter_protomatter_set_paused(protomatter_protomatter_obj_t bool common_hal_protomatter_protomatter_get_paused(protomatter_protomatter_obj_t* self) { return self->paused; } + +void common_hal_protomatter_protomatter_refresh(protomatter_protomatter_obj_t* self) { + _PM_convert_565(&self->core, self->bufinfo.buf, self->width); + _PM_swapbuffer_maybe(&self->core); +} + diff --git a/shared-module/_protomatter/allocator.h b/shared-module/_protomatter/allocator.h index 1ae127de2..b7f517ce5 100644 --- a/shared-module/_protomatter/allocator.h +++ b/shared-module/_protomatter/allocator.h @@ -13,14 +13,14 @@ static inline void *_PM_allocator_impl(size_t sz) { if (gc_alloc_possible()) { return m_malloc(sz + sizeof(void*), true); } else { - supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); + supervisor_allocation *allocation = allocate_memory(align32_size(sz), false); return allocation ? allocation->ptr : NULL; } } static inline void _PM_free_impl(void *ptr_in) { supervisor_allocation *allocation = allocation_from_ptr(ptr_in); - + if (allocation) { free_memory(allocation); } -- cgit v1.2.3 From d8362ef654d86d29561db2cbcc2a20ab488316a8 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Tue, 14 Apr 2020 17:34:53 -0500 Subject: displayio: swap colors in palettes too .. change the in-rom palette to be in RGB565 order --- shared-module/displayio/Palette.c | 7 ++++++- supervisor/shared/display.c | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'shared-module') diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index 3bce86f48..1ef03aab4 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -83,7 +83,12 @@ bool displayio_palette_get_color(displayio_palette_t *self, const _displayio_col } else if (colorspace->grayscale) { *color = self->colors[palette_index].luma >> (8 - colorspace->depth); } else { - *color = self->colors[palette_index].rgb565; + uint16_t packed = self->colors[palette_index].rgb565; + if (colorspace->reverse_bytes_in_word) { + // swap bytes + packed = __builtin_bswap16(packed); + } + *color = packed; } return true; diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index cdf710d26..95926bc9c 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -169,28 +169,28 @@ _displayio_color_t blinka_colors[7] = { }, { .rgb888 = 0x8428bc, - .rgb565 = 0x7889, + .rgb565 = 0x8978, .luma = 0xff, // We cheat the luma here. It is actually 0x60 .hue = 184, .chroma = 148 }, { .rgb888 = 0xff89bc, - .rgb565 = 0xB8FC, + .rgb565 = 0xFCB8, .luma = 0xb5, .hue = 222, .chroma = 118 }, { .rgb888 = 0x7beffe, - .rgb565 = 0x9F86, + .rgb565 = 0x869F, .luma = 0xe0, .hue = 124, .chroma = 131 }, { .rgb888 = 0x51395f, - .rgb565 = 0x0D5A, + .rgb565 = 0x5A0D, .luma = 0x47, .hue = 185, .chroma = 38 @@ -203,7 +203,7 @@ _displayio_color_t blinka_colors[7] = { }, { .rgb888 = 0x0736a0, - .rgb565 = 0xf501, + .rgb565 = 0x01f5, .luma = 0x44, .hue = 147, .chroma = 153 -- cgit v1.2.3