diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 54a9a072bd6d1..2afcf0c45987c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -1084,10 +1084,6 @@ msgstr "" msgid "I2SOut not available" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "IOs 0, 2 & 4 do not support internal pullup in sleep" -msgstr "" - #: shared-bindings/aesio/aes.c #, c-format msgid "IV must be %d bytes long" @@ -1601,6 +1597,7 @@ msgstr "" msgid "Not a valid IP string" msgstr "" +#: ports/nrf/common-hal/_bleio/PacketBuffer.c #: ports/nrf/common-hal/_bleio/__init__.c #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "Not connected" @@ -2563,6 +2560,10 @@ msgstr "" msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" +#: shared-bindings/capsuleio/__init__.c +msgid "can only save a string or None in the time capsule" +msgstr "" + #: py/persistentcode.c msgid "can only save bytecode" msgstr "" @@ -3253,10 +3254,6 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "io must be rtc io" -msgstr "" - #: py/objtype.c msgid "issubclass() arg 1 must be a class" msgstr "" @@ -3716,6 +3713,7 @@ msgstr "" #: ports/esp32s2/boards/adafruit_funhouse/mpconfigboard.h #: ports/esp32s2/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.h #: ports/esp32s2/boards/adafruit_metro_esp32s2/mpconfigboard.h +#: ports/esp32s2/boards/artisense_rd00/mpconfigboard.h #: ports/esp32s2/boards/electroniccats_bastwifi/mpconfigboard.h #: ports/esp32s2/boards/espressif_kaluga_1/mpconfigboard.h #: ports/esp32s2/boards/espressif_saola_1_wroom/mpconfigboard.h @@ -3989,6 +3987,10 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" +#: shared-bindings/capsuleio/__init__.c +msgid "too long to store in time capsule" +msgstr "" + #: shared-module/struct/__init__.c msgid "too many arguments provided with the given format" msgstr "" @@ -4014,10 +4016,6 @@ msgstr "" msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "trigger level must be 0 or 1" -msgstr "" - #: py/obj.c msgid "tuple/list has wrong length" msgstr "" @@ -4152,10 +4150,6 @@ msgstr "" msgid "value_count must be > 0" msgstr "" -#: ports/esp32s2/common-hal/alarm/pin/__init__.c -msgid "wakeup conflict" -msgstr "" - #: ports/esp32s2/common-hal/watchdog/WatchDogTimer.c msgid "watchdog not initialized" msgstr "" diff --git a/locale/es.po b/locale/es.po index dca1a5a216b7d..bbbbd5ad4e454 100644 --- a/locale/es.po +++ b/locale/es.po @@ -1436,6 +1436,12 @@ msgstr "Valor máximo de x cuando se refleja es %d" msgid "Messages limited to 8 bytes" msgstr "Mensajes limitados a 8 bytes" +#: shared-bindings/capsuleio/__init__.c +msgid "too long to store in time capsule" +msgstr "demasiado largo para poner en la cápsula del tiempo" +msgid "can only save a string or None in the time capsule" +msgstr "sólo puedes guardar None o cadenas" + #: shared-bindings/audiobusio/PDMIn.c msgid "Microphone startup delay must be in range 0.0 to 1.0" msgstr "Micrófono demora de inicio debe estar en el rango 0.0 a 1.0" diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk index 544be70be4a91..d02fd70b611ef 100644 --- a/ports/nrf/mpconfigport.mk +++ b/ports/nrf/mpconfigport.mk @@ -46,6 +46,8 @@ CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_COUNTIO = 0 CIRCUITPY_WATCHDOG ?= 1 +CIRCUITPY_CAPSULEIO ?= 1 + # nRF52840-specific ifeq ($(MCU_CHIP),nrf52840) diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 0eedfe5249e22..be2dd4edba484 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -163,6 +163,9 @@ endif ifeq ($(CIRCUITPY_CANIO),1) SRC_PATTERNS += canio/% endif +ifeq ($(CIRCUITPY_CAPSULEIO),1) +SRC_PATTERNS += capsuleio/% +endif ifeq ($(CIRCUITPY_COUNTIO),1) SRC_PATTERNS += countio/% endif @@ -485,6 +488,7 @@ SRC_SHARED_MODULE_ALL = \ canio/Match.c \ canio/Message.c \ canio/RemoteTransmissionRequest.c \ + capsuleio/__init__.c \ displayio/Bitmap.c \ displayio/ColorConverter.c \ displayio/Display.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index eedda7ad73ec8..9624d8b33141c 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -377,6 +377,13 @@ extern const struct _mp_obj_module_t canio_module; #define CANIO_MODULE #endif +#if CIRCUITPY_CAPSULEIO +extern const struct _mp_obj_module_t capsuleio_module; +#define CAPSULEIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_capsuleio), (mp_obj_t)&capsuleio_module }, +#else +#define CAPSULEIO_MODULE +#endif + #if CIRCUITPY_COUNTIO extern const struct _mp_obj_module_t countio_module; #define COUNTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_countio), (mp_obj_t)&countio_module }, @@ -850,6 +857,7 @@ extern const struct _mp_obj_module_t msgpack_module; BUSIO_MODULE \ CAMERA_MODULE \ CANIO_MODULE \ + CAPSULEIO_MODULE\ COUNTIO_MODULE \ DIGITALIO_MODULE \ DISPLAYIO_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 51b590dcf30ed..082719cc493de 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -127,6 +127,9 @@ CFLAGS += -DCIRCUITPY_CAMERA=$(CIRCUITPY_CAMERA) CIRCUITPY_CANIO ?= 0 CFLAGS += -DCIRCUITPY_CANIO=$(CIRCUITPY_CANIO) +CIRCUITPY_CAPSULEIO ?= 1 +CFLAGS += -DCIRCUITPY_CAPSULEIO=$(CIRCUITPY_CAPSULEIO) + CIRCUITPY_DIGITALIO ?= 1 CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) diff --git a/shared-bindings/capsuleio/__init__.c b/shared-bindings/capsuleio/__init__.c new file mode 100644 index 0000000000000..667b268f3cc38 --- /dev/null +++ b/shared-bindings/capsuleio/__init__.c @@ -0,0 +1,65 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jonah Yolles-Murphy (TG-Techie) + * + * 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. + */ + +// TODO: add description of module + +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/capsuleio/__init__.h" + +// for now only string and none can be saved. in the future it may be tuples, floats, ints (maybe) +STATIC mp_obj_t capsule_bury(mp_obj_t obj) { + capsule_result_t result = capsuleio_bury_obj(obj); + switch (result) { + case CAPSULEIO_STRING_TO_LONG: + mp_raise_ValueError(translate("too long to store in time capsule")); + break; // is this needed? the above is noreturn + case CAPSULEIO_TYPE_CANNOT_BE_BURIED: + mp_raise_TypeError(translate("can only save a string or None in the time capsule")); + break; // is this needed? the above is noreturn + case CAPSULEIO_OK: + default: + return mp_const_none; + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(capsuleio_bury_fnobj, capsule_bury); +// this function requires no runtime wrapper +MP_DEFINE_CONST_FUN_OBJ_0(capsuleio_unearth_fnobj, capsuleio_unearth_new_obj); + +STATIC const mp_rom_map_elem_t mp_module_capsuleio_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_capsuleio) }, + { MP_ROM_QSTR(MP_QSTR_bury), MP_ROM_PTR(&capsuleio_bury_fnobj) }, + { MP_ROM_QSTR(MP_QSTR_unearth), MP_ROM_PTR(&capsuleio_unearth_fnobj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(mp_module_capsuleio_globals, mp_module_capsuleio_globals_table); + + +const mp_obj_module_t capsuleio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mp_module_capsuleio_globals, +}; diff --git a/shared-bindings/capsuleio/__init__.h b/shared-bindings/capsuleio/__init__.h new file mode 100644 index 0000000000000..76227d99de6c4 --- /dev/null +++ b/shared-bindings/capsuleio/__init__.h @@ -0,0 +1,33 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jonah Yolles-Murphy (TG-Techie) + * + * 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_CAPSULEIO_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_CAPSULEIO_H + +#include "shared-module/capsuleio/__init__.h" + + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_CAPSULEIO_H diff --git a/shared-module/capsuleio/__init__.c b/shared-module/capsuleio/__init__.c new file mode 100644 index 0000000000000..450c34855a8ee --- /dev/null +++ b/shared-module/capsuleio/__init__.c @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jonah Yolles-Murphy (TG-Techie) + * + * 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/capsuleio/__init__.h" +#include "py/objstr.h" +#include + + +// the time capsule memory reservation +capsuleio_capsule_t capsuleio_capsule; + +STATIC bool capsuleio_bury_string(const byte *data, size_t length) { + // the only fail mode is the string is too long + // make sure the data will fit + if (length > CIRCUITPY_CAPSULEIO_AMOUNT_BYTES) { + return false; + } else { + // set the type of the data stored + capsuleio_capsule.kind = CAPSULEIO_STRING; + // copy the string data in + memcpy(&capsuleio_capsule.data, data, length); + // write the null byte + capsuleio_capsule.data[length] = 0; + return true; + } +} + +STATIC void capsuleio_bury_none(void) { + capsuleio_capsule.kind = CAPSULEIO_NONE; + memset(&capsuleio_capsule.data, 0, CIRCUITPY_CAPSULEIO_AMOUNT_BYTES); + return; +} + +mp_obj_t capsuleio_unearth_new_obj(void) { + switch (capsuleio_capsule.kind) { + case CAPSULEIO_NONE: + return mp_const_none; + case CAPSULEIO_STRING: + return mp_obj_new_str_copy( + &mp_type_str, + (const byte *)&capsuleio_capsule.data, + strlen((const char *)&capsuleio_capsule.data)); + default: + // this should never be reached, but just in case + return mp_const_none; + } +} + +capsule_result_t capsuleio_bury_obj(mp_obj_t obj) { + if (obj == mp_const_none) { + capsuleio_bury_none(); + return CAPSULEIO_OK; + } else if (MP_OBJ_IS_STR(obj)) { + GET_STR_DATA_LEN(obj, data, length); // defines locals data and length + bool bury_worked = capsuleio_bury_string(data, length); + if (!bury_worked) { + return CAPSULEIO_STRING_TO_LONG; + } else { + return CAPSULEIO_OK; + } + } else { + return CAPSULEIO_TYPE_CANNOT_BE_BURIED; + } +} diff --git a/shared-module/capsuleio/__init__.h b/shared-module/capsuleio/__init__.h new file mode 100644 index 0000000000000..6385b977d3275 --- /dev/null +++ b/shared-module/capsuleio/__init__.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jonah Yolles-Murphy (TG-Techie) + * + * 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_CAPSULEIO_H +#define MICROPY_INCLUDED_SHARED_MODULE_CAPSULEIO_H + +#include "py/obj.h" +#include "py/proto.h" +#include "py/objstr.h" + +// TODO(tg-techie): make this settable on a per-board basis +// this is the number of bytes allocated globally for storing capsuleio objects +#define CIRCUITPY_CAPSULEIO_AMOUNT_BYTES 1024 + +typedef enum { + CAPSULEIO_OK, + CAPSULEIO_STRING_TO_LONG, + CAPSULEIO_TYPE_CANNOT_BE_BURIED, +} capsule_result_t; + +// yes this is a manual tagged union +// couldn't figure out a way to make void feilds in unions +typedef enum { + CAPSULEIO_NONE = 0, // the none kind must be zero + CAPSULEIO_STRING, +} capsule_type_kind_t; + +typedef struct { + capsule_type_kind_t kind; + // a run-time tag to keep track of the stored type + byte data[CIRCUITPY_CAPSULEIO_AMOUNT_BYTES]; + // the stored data + const byte _null_terminator; + // this *shouldn't* ever be overwritten, so be careful +} capsuleio_capsule_t; + +extern capsuleio_capsule_t capsuleio_capsule; + +mp_obj_t capsuleio_unearth_new_obj(void); +capsule_result_t capsuleio_bury_obj(mp_obj_t obj); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_CAPSULEIO_H