From 5232e3f6c3280724a6d242f9ebacd2d63e496d29 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:35:48 +0530 Subject: [PATCH] add coproc module --- locale/circuitpython.pot | 17 +- ports/espressif/CMakeLists.txt | 2 +- ports/espressif/Makefile | 5 + ports/espressif/common-hal/coproc/Coproc.c | 52 +++++ ports/espressif/common-hal/coproc/Coproc.h | 40 ++++ .../common-hal/coproc/CoprocMemory.c | 52 +++++ .../common-hal/coproc/CoprocMemory.h | 38 ++++ ports/espressif/common-hal/coproc/__init__.c | 69 +++++++ .../esp-idf-config/sdkconfig-esp32s2.defaults | 7 +- .../esp-idf-config/sdkconfig-esp32s3.defaults | 8 +- ports/espressif/mpconfigport.mk | 3 + py/circuitpy_defns.mk | 6 + py/circuitpy_mpconfig.mk | 3 + shared-bindings/coproc/Coproc.c | 110 +++++++++++ shared-bindings/coproc/Coproc.h | 40 ++++ shared-bindings/coproc/CoprocMemory.c | 184 ++++++++++++++++++ shared-bindings/coproc/CoprocMemory.h | 39 ++++ shared-bindings/coproc/__init__.c | 115 +++++++++++ shared-bindings/coproc/__init__.h | 37 ++++ 19 files changed, 815 insertions(+), 12 deletions(-) create mode 100644 ports/espressif/common-hal/coproc/Coproc.c create mode 100644 ports/espressif/common-hal/coproc/Coproc.h create mode 100644 ports/espressif/common-hal/coproc/CoprocMemory.c create mode 100644 ports/espressif/common-hal/coproc/CoprocMemory.h create mode 100644 ports/espressif/common-hal/coproc/__init__.c create mode 100644 shared-bindings/coproc/Coproc.c create mode 100644 shared-bindings/coproc/Coproc.h create mode 100644 shared-bindings/coproc/CoprocMemory.c create mode 100644 shared-bindings/coproc/CoprocMemory.h create mode 100644 shared-bindings/coproc/__init__.c create mode 100644 shared-bindings/coproc/__init__.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 6c5e5ee585..2208ff25b1 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -507,7 +507,8 @@ msgstr "" msgid "Array must contain halfwords (type 'H')" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/coproc/CoprocMemory.c +#: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "" @@ -913,6 +914,7 @@ msgstr "" #: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c #: shared-bindings/alarm/__init__.c shared-bindings/busio/SPI.c +#: shared-bindings/coproc/Coproc.c shared-bindings/coproc/__init__.c #: shared-bindings/microcontroller/Pin.c #: shared-bindings/neopixel_write/__init__.c msgid "Expected a %q" @@ -1012,6 +1014,7 @@ msgstr "" msgid "Firmware is invalid" msgstr "" +#: ports/espressif/common-hal/coproc/__init__.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" msgstr "" @@ -1915,7 +1918,8 @@ msgstr "" msgid "Sleep Memory not available" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/coproc/CoprocMemory.c +#: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -2159,6 +2163,10 @@ msgstr "" msgid "Unable to start mDNS query" msgstr "" +#: shared-bindings/coproc/CoprocMemory.c +msgid "Unable to write" +msgstr "" + #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." msgstr "" @@ -2407,7 +2415,7 @@ msgid "array has too many dimensions" msgstr "" #: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/coproc/CoprocMemory.c shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -3682,7 +3690,8 @@ msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/coproc/CoprocMemory.c +#: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" diff --git a/ports/espressif/CMakeLists.txt b/ports/espressif/CMakeLists.txt index d05af27539..ea4de9f343 100644 --- a/ports/espressif/CMakeLists.txt +++ b/ports/espressif/CMakeLists.txt @@ -6,7 +6,7 @@ set(ENV{IDF_PATH} ${CMAKE_SOURCE_DIR}/esp-idf) # The component list here determines what options we get in menuconfig and what the ninja file # can build. -set(COMPONENTS esptool_py soc driver log main esp-tls mbedtls mdns esp_event esp_adc_cal esp_netif esp_wifi lwip wpa_supplicant freertos bt usb) +set(COMPONENTS esptool_py soc driver log main esp-tls mbedtls mdns esp_event esp_adc_cal esp_netif esp_wifi lwip ulp wpa_supplicant freertos bt usb) if("${CIRCUITPY_ESP32_CAMERA}") message("Including esp32-camera") diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index 82d068f136..ebf636bb39 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -135,6 +135,8 @@ INC += \ -isystem esp-idf/components/soc/include \ -isystem esp-idf/components/soc/$(IDF_TARGET)/include \ -isystem esp-idf/components/spi_flash/include \ + -isystem esp-idf/components/ulp/include \ + -isystem esp-idf/components/ulp/ulp_riscv/include \ -isystem esp-idf/components/$(IDF_TARGET_ARCH)/include \ -isystem esp-idf/components/$(IDF_TARGET_ARCH)/$(IDF_TARGET)/include @@ -399,6 +401,9 @@ ifneq ($(CIRCUITPY_BLEIO),0) BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libbtbb.a \ esp-idf/components/bt/controller/lib_esp32c3_family/$(IDF_TARGET)/libbtdm_app.a endif +ifneq ($(CIRCUITPY_COPROC),0) + ESP_IDF_COMPONENTS_LINK += ulp +endif ESP_IDF_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a) diff --git a/ports/espressif/common-hal/coproc/Coproc.c b/ports/espressif/common-hal/coproc/Coproc.c new file mode 100644 index 0000000000..1216b5dde3 --- /dev/null +++ b/ports/espressif/common-hal/coproc/Coproc.c @@ -0,0 +1,52 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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/coproc/Coproc.h" +#include "shared-bindings/coproc/CoprocMemory.h" + +void common_hal_coproc_coproc_construct(coproc_coproc_obj_t *self, + const uint8_t *buf, const size_t buf_len, coproc_memory_obj_t *coproc_memory) { + // set CoprocMemory object + self->coproc_memory = coproc_memory; + + // load buffer + self->buf_len = buf_len; + self->buf = (uint8_t *)m_malloc(self->buf_len, false); + memcpy(self->buf, buf, self->buf_len); +} + +bool common_hal_coproc_coproc_deinited(coproc_coproc_obj_t *self) { + return self->buf == NULL; +} + +void common_hal_coproc_coproc_deinit(coproc_coproc_obj_t *self) { + if (common_hal_coproc_coproc_deinited(self)) { + return; + } + m_free(self->buf); + self->buf = NULL; + self->coproc_memory = NULL; +} diff --git a/ports/espressif/common-hal/coproc/Coproc.h b/ports/espressif/common-hal/coproc/Coproc.h new file mode 100644 index 0000000000..19082871cc --- /dev/null +++ b/ports/espressif/common-hal/coproc/Coproc.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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_ESPRESSIF_COMMON_HAL_COPROC_COPROC_H +#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROC_H + +#include "py/obj.h" +#include "common-hal/coproc/CoprocMemory.h" + +typedef struct { + mp_obj_base_t base; + uint8_t *buf; + size_t buf_len; + coproc_memory_obj_t *coproc_memory; +} coproc_coproc_obj_t; + +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROC_H diff --git a/ports/espressif/common-hal/coproc/CoprocMemory.c b/ports/espressif/common-hal/coproc/CoprocMemory.c new file mode 100644 index 0000000000..ca9a82dbcf --- /dev/null +++ b/ports/espressif/common-hal/coproc/CoprocMemory.c @@ -0,0 +1,52 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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/coproc/CoprocMemory.h" + +uint32_t common_hal_coproc_memory_get_length(coproc_memory_obj_t *self) { + return self->len; +} + +bool common_hal_coproc_memory_set_bytes(coproc_memory_obj_t *self, + uint32_t start_index, const uint8_t *values, uint32_t len) { + + if (start_index + len > self->len) { + return false; + } + + memcpy((uint8_t *)(self->address + start_index), values, len); + return true; +} + +void common_hal_coproc_memory_get_bytes(coproc_memory_obj_t *self, + uint32_t start_index, uint8_t *values, uint32_t len) { + + if (start_index + len > self->len) { + return; + } + + memcpy(values, (uint8_t *)(self->address + start_index), len); +} diff --git a/ports/espressif/common-hal/coproc/CoprocMemory.h b/ports/espressif/common-hal/coproc/CoprocMemory.h new file mode 100644 index 0000000000..c4aa088394 --- /dev/null +++ b/ports/espressif/common-hal/coproc/CoprocMemory.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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_ESPRESSIF_COMMON_HAL_COPROC_COPROCMEMORY_H +#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROCMEMORY_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint32_t address; + uint16_t len; +} coproc_memory_obj_t; + +#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROCMEMORY_H diff --git a/ports/espressif/common-hal/coproc/__init__.c b/ports/espressif/common-hal/coproc/__init__.c new file mode 100644 index 0000000000..3f53cca5d4 --- /dev/null +++ b/ports/espressif/common-hal/coproc/__init__.c @@ -0,0 +1,69 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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/coproc/__init__.h" + +#include "py/runtime.h" + +#if defined(CONFIG_IDF_TARGET_ESP32S2) +#include "esp32s2/ulp.h" +#include "esp32s2/ulp_riscv.h" +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +#include "esp32s3/ulp.h" +#include "esp32s3/ulp_riscv.h" +#endif + +// To-do idf v5.0: remove following include +#include "soc/rtc_cntl_reg.h" + +void common_hal_coproc_run(coproc_coproc_obj_t *self) { + if (ulp_riscv_load_binary(self->buf, self->buf_len) != ESP_OK) { + mp_raise_RuntimeError(translate("Firmware is too big")); + } + m_free(self->buf); + self->buf = (uint8_t *)RTC_SLOW_MEM; + ulp_riscv_run(); +} + +void common_hal_coproc_halt(coproc_coproc_obj_t *self) { + self->buf = (uint8_t *)m_malloc(self->buf_len, false); + memcpy(self->buf, (uint8_t *)RTC_SLOW_MEM, self->buf_len); + + // To-do idf v5.0: use following functions + // ulp_riscv_timer_stop(); + // ulp_riscv_halt(); + + // stop the ulp timer + CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + // suspends the ulp operation + SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE); + // Resets the processor + SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); +} + +mp_obj_t common_hal_coproc_memory(coproc_coproc_obj_t *self) { + return (self->coproc_memory) ? MP_OBJ_FROM_PTR(self->coproc_memory) : mp_const_none; +} diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults index ac3e909dfc..d96a6c5366 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults @@ -41,8 +41,9 @@ CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y # CONFIG_ESP32S2_TRAX is not set CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S2_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=4096 +CONFIG_ESP32S2_ULP_COPROC_RISCV=y CONFIG_ESP32S2_DEBUG_OCDAWARE=y # CONFIG_ESP32S2_DEBUG_STUBS_ENABLE is not set CONFIG_ESP32S2_BROWNOUT_DET=y @@ -65,7 +66,7 @@ CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 # CONFIG_ESP32S2_NO_BLOBS is not set # CONFIG_ESP32S2_KEEP_USB_ALIVE is not set -# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM=y # CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set # # MAC Config diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults index ce0d9f8d62..30a71c6a44 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults @@ -67,8 +67,9 @@ CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 # CONFIG_ESP32S3_TRAX is not set CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S3_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S3_ULP_COPROC_ENABLED=y +CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=4096 +CONFIG_ESP32S3_ULP_COPROC_RISCV=y CONFIG_ESP32S3_BROWNOUT_DET=y CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y # CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set @@ -88,7 +89,7 @@ CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y # CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 -# CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set +CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM=y # CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set # end of ESP32S3-Specific @@ -218,4 +219,3 @@ CONFIG_CAMERA_DMA_BUFFER_SIZE_MAX=32768 # CONFIG_CAMERA_CONVERTER_ENABLED is not set # end of Camera configuration # end of Component config - diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index 9ac4408ef7..404f47cfe9 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -19,6 +19,7 @@ CIRCUITPY_AUDIOIO ?= 0 CIRCUITPY_AUDIOMIXER ?= 1 CIRCUITPY_CANIO ?= 1 CIRCUITPY_COUNTIO ?= 1 +CIRCUITPY_COPROC ?= 1 CIRCUITPY_DUALBANK ?= 1 CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_FREQUENCYIO ?= 1 @@ -38,6 +39,7 @@ CIRCUITPY_ESPIDF ?= 1 ifeq ($(IDF_TARGET),esp32) CIRCUITPY_BLEIO = 0 CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_COPROC = 0 CIRCUITPY_PARALLELDISPLAY = 0 # Protomatter needs to support ESP32. CIRCUITPY_RGBMATRIX = 0 @@ -52,6 +54,7 @@ CIRCUITPY_AUDIOBUSIO = 0 CIRCUITPY_BLEIO = 1 CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_COUNTIO = 0 +CIRCUITPY_COPROC = 0 CIRCUITPY_DUALBANK = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_PARALLELDISPLAY = 0 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index b5c8047f99..21a3ec2e1e 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -167,6 +167,9 @@ endif ifeq ($(CIRCUITPY_CANIO),1) SRC_PATTERNS += canio/% endif +ifeq ($(CIRCUITPY_COPROC),1) +SRC_PATTERNS += coproc/% +endif ifeq ($(CIRCUITPY_COUNTIO),1) SRC_PATTERNS += countio/% endif @@ -419,6 +422,9 @@ SRC_COMMON_HAL_ALL = \ canio/CAN.c \ canio/Listener.c \ canio/__init__.c \ + coproc/__init__.c \ + coproc/Coproc.c \ + coproc/CoprocMemory.c \ countio/Counter.c \ countio/__init__.c \ digitalio/DigitalInOut.c \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 09818956ea..fbf0b587b7 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -178,6 +178,9 @@ CFLAGS += -DCIRCUITPY_CYW43=$(CIRCUITPY_CYW43) CIRCUITPY_DIGITALIO ?= 1 CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) +CIRCUITPY_COPROC ?= 0 +CFLAGS += -DCIRCUITPY_COPROC=$(CIRCUITPY_COPROC) + CIRCUITPY_COUNTIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) diff --git a/shared-bindings/coproc/Coproc.c b/shared-bindings/coproc/Coproc.c new file mode 100644 index 0000000000..85595578c8 --- /dev/null +++ b/shared-bindings/coproc/Coproc.c @@ -0,0 +1,110 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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/runtime/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/coproc/Coproc.h" +#include "shared-bindings/coproc/CoprocMemory.h" + +STATIC coproc_memory_obj_t *get_coproc_memory_obj(mp_obj_t *self_in) { + if (!mp_obj_is_type(*self_in, &coproc_memory_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), MP_QSTR_CoprocMemory); + } + return MP_OBJ_TO_PTR(*self_in); +} + +//| class Coproc: +//| def __init__(self, buffer: ReadableBuffer, memory: CoprocMemory) -> None: +//| """Loads the program binary into memory. +//| +//| :param buffer: The program binary to run on the core/co-processor +//| :param memory: The `CoprocMemory` object used to access shared memory""" +STATIC mp_obj_t coproc_coproc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_buffer, ARG_memory }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_memory, MP_ARG_OBJ, { .u_obj = mp_const_none } }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + coproc_coproc_obj_t *self = m_new_obj(coproc_coproc_obj_t); + self->base.type = &coproc_coproc_type; + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + + coproc_memory_obj_t *coproc_memory = (args[ARG_memory].u_obj == mp_const_none) ? NULL : get_coproc_memory_obj(&args[ARG_memory].u_obj); + + common_hal_coproc_coproc_construct(self, bufinfo.buf, bufinfo.len, coproc_memory); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Releases control of the underlying hardware so other classes can use it.""" +//| ... +STATIC mp_obj_t coproc_coproc_obj_deinit(mp_obj_t self_in) { + coproc_coproc_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_coproc_coproc_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(coproc_coproc_deinit_obj, coproc_coproc_obj_deinit); + +//| def __enter__(self) -> Coproc: +//| """No-op used in Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Close the request.""" +//| ... +//| +STATIC mp_obj_t coproc_coproc_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + mp_check_self(mp_obj_is_type(args[0], &coproc_coproc_type)); + return coproc_coproc_obj_deinit(args[0]); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(coproc_coproc___exit___obj, 4, 4, coproc_coproc_obj___exit__); + +STATIC const mp_rom_map_elem_t coproc_coproc_locals_dict_table[] = { + // context managers + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&coproc_coproc___exit___obj) }, + + // functions + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&coproc_coproc_deinit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(coproc_coproc_locals_dict, coproc_coproc_locals_dict_table); + +const mp_obj_type_t coproc_coproc_type = { + { &mp_type_type }, + .name = MP_QSTR_Coproc, + .make_new = coproc_coproc_make_new, + .locals_dict = (mp_obj_dict_t *)&coproc_coproc_locals_dict, +}; diff --git a/shared-bindings/coproc/Coproc.h b/shared-bindings/coproc/Coproc.h new file mode 100644 index 0000000000..fbf9bd9ae0 --- /dev/null +++ b/shared-bindings/coproc/Coproc.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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_COPROC_COPROC_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_COPROC_COPROC_H + +#include "common-hal/coproc/Coproc.h" + +extern const mp_obj_type_t coproc_coproc_type; + +extern void common_hal_coproc_coproc_construct(coproc_coproc_obj_t *self, + const uint8_t *buf, const size_t buf_len, coproc_memory_obj_t *coproc_memory); + +extern void common_hal_coproc_coproc_deinit(coproc_coproc_obj_t *self); +extern bool common_hal_coproc_coproc_deinited(coproc_coproc_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_COPROC_COPROC_H diff --git a/shared-bindings/coproc/CoprocMemory.c b/shared-bindings/coproc/CoprocMemory.c new file mode 100644 index 0000000000..0d49a2f008 --- /dev/null +++ b/shared-bindings/coproc/CoprocMemory.c @@ -0,0 +1,184 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" + +#include "shared-bindings/coproc/CoprocMemory.h" +#include "supervisor/shared/translate/translate.h" + +//| class CoprocMemory: +//| def __init__(self, address: int, length: int) -> None: +//| """Initialize coproc shared memory. +//| +//| :param address: address of shared memory +//| :param length: length of shared memory""" +STATIC mp_obj_t coproc_memory_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_address, ARG_length }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_length, MP_ARG_REQUIRED | MP_ARG_INT }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + coproc_memory_obj_t *self = m_new_obj(coproc_memory_obj_t); + self->base.type = &coproc_memory_type; + self->address = args[ARG_address].u_int; + self->len = args[ARG_length].u_int; + + return MP_OBJ_FROM_PTR(self); +} + +//| def __bool__(self) -> bool: +//| """``coproc_memory`` is ``True`` if its length is greater than zero. +//| This is an easy way to check for its existence. +//| """ +//| ... +//| def __len__(self) -> int: +//| """Return the length. This is used by (`len`)""" +//| ... +STATIC mp_obj_t coproc_memory_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + coproc_memory_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint16_t len = common_hal_coproc_memory_get_length(self); + switch (op) { + case MP_UNARY_OP_BOOL: + return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: + return MP_OBJ_NEW_SMALL_INT(len); + default: + return MP_OBJ_NULL; // op not supported + } +} + +STATIC const mp_rom_map_elem_t coproc_memory_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(coproc_memory_locals_dict, coproc_memory_locals_dict_table); + +//| @overload +//| def __getitem__(self, index: slice) -> bytearray: ... +//| @overload +//| def __getitem__(self, index: int) -> int: +//| """Returns the value at the given index.""" +//| ... +//| @overload +//| def __setitem__(self, index: slice, value: ReadableBuffer) -> None: ... +//| @overload +//| def __setitem__(self, index: int, value: int) -> None: +//| """Set the value at the given index.""" +//| ... +//| +STATIC mp_obj_t coproc_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + if (value == MP_OBJ_NULL) { + // delete item + // slice deletion + return MP_OBJ_NULL; // op not supported + } else { + coproc_memory_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (0) { + #if MICROPY_PY_BUILTINS_SLICE + } else if (mp_obj_is_type(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + if (!mp_seq_get_fast_slice_indexes(common_hal_coproc_memory_get_length(self), index_in, &slice)) { + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); + } + if (value != MP_OBJ_SENTINEL) { + #if MICROPY_PY_ARRAY_SLICE_ASSIGN + // Assign + size_t src_len = slice.stop - slice.start; + uint8_t *src_items; + if (mp_obj_is_type(value, &mp_type_array) || + mp_obj_is_type(value, &mp_type_bytearray) || + mp_obj_is_type(value, &mp_type_memoryview) || + mp_obj_is_type(value, &mp_type_bytes)) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len != src_len) { + mp_raise_ValueError(translate("Slice and value different lengths.")); + } + src_len = bufinfo.len; + src_items = bufinfo.buf; + if (1 != mp_binary_get_size('@', bufinfo.typecode, NULL)) { + mp_raise_ValueError(translate("Array values should be single bytes.")); + } + } else { + mp_raise_NotImplementedError(translate("array/bytes required on right side")); + } + + if (!common_hal_coproc_memory_set_bytes(self, slice.start, src_items, src_len)) { + mp_raise_RuntimeError(translate("Unable to write")); + } + return mp_const_none; + #else + return MP_OBJ_NULL; // op not supported + #endif + } else { + // Read slice. + size_t len = slice.stop - slice.start; + uint8_t *items = m_new(uint8_t, len); + common_hal_coproc_memory_get_bytes(self, slice.start, items, len); + return mp_obj_new_bytearray_by_ref(len, items); + } + #endif + } else { + // Single index rather than slice. + size_t index = mp_get_index(self->base.type, common_hal_coproc_memory_get_length(self), + index_in, false); + if (value == MP_OBJ_SENTINEL) { + // load + uint8_t value_out; + common_hal_coproc_memory_get_bytes(self, index, &value_out, 1); + return MP_OBJ_NEW_SMALL_INT(value_out); + } else { + // store + mp_int_t byte_value = mp_obj_get_int(value); + mp_arg_validate_int_range(byte_value, 0, 255, MP_QSTR_bytes); + + uint8_t short_value = byte_value; + if (!common_hal_coproc_memory_set_bytes(self, index, &short_value, 1)) { + mp_raise_RuntimeError(translate("Unable to write")); + } + return mp_const_none; + } + } + } +} + +const mp_obj_type_t coproc_memory_type = { + { &mp_type_type }, + .name = MP_QSTR_CoprocMemory, + .flags = MP_TYPE_FLAG_EXTENDED, + .make_new = coproc_memory_make_new, + .locals_dict = (mp_obj_t)&coproc_memory_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .subscr = coproc_memory_subscr, + .unary_op = coproc_memory_unary_op, + ), +}; diff --git a/shared-bindings/coproc/CoprocMemory.h b/shared-bindings/coproc/CoprocMemory.h new file mode 100644 index 0000000000..fdbb2fa0fa --- /dev/null +++ b/shared-bindings/coproc/CoprocMemory.h @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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_COPROC_COPROCMEMORY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_COPROC_COPROCMEMORY_H + +#include "common-hal/coproc/CoprocMemory.h" + +extern const mp_obj_type_t coproc_memory_type; + +uint32_t common_hal_coproc_memory_get_length(coproc_memory_obj_t *self); + +bool common_hal_coproc_memory_set_bytes(coproc_memory_obj_t *self, uint32_t start_index, const uint8_t *values, uint32_t len); +void common_hal_coproc_memory_get_bytes(coproc_memory_obj_t *self, uint32_t start_index, uint8_t *values, uint32_t len); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_COPROC_COPROCMEMORY_H diff --git a/shared-bindings/coproc/__init__.c b/shared-bindings/coproc/__init__.c new file mode 100644 index 0000000000..06b196d8be --- /dev/null +++ b/shared-bindings/coproc/__init__.c @@ -0,0 +1,115 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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/util.h" +#include "shared-bindings/coproc/__init__.h" +#include "shared-bindings/coproc/Coproc.h" +#include "shared-bindings/coproc/CoprocMemory.h" + +#include "py/runtime.h" + +//| """COPROC Module +//| +//| The `coproc` module adds ability to load and run +//| programs on a co-processor or a different cpu core. +//| +//| .. code-block:: python +//| +//| import coproc +//| +//| shared_mem = coproc.CoprocMemory(address=0x500007fc, length=1024) +//| +//| with open("program.bin", "rb") as f: +//| program = coproc.Coproc(buffer=f.read(), memory=shared_mem) +//| +//| coproc.run(program) +//| print(coproc.memory(program)[0]) +//| # coproc.halt(program) +//| """ +//| ... +//| + +STATIC coproc_coproc_obj_t *get_coproc_obj(mp_obj_t *self_in) { + if (!mp_obj_is_type(*self_in, &coproc_coproc_type)) { + mp_raise_TypeError_varg(translate("Expected a %q"), MP_QSTR_Coproc); + } + coproc_coproc_obj_t *self = MP_OBJ_TO_PTR(*self_in); + if (common_hal_coproc_coproc_deinited(self)) { + raise_deinited_error(); + } + return self; +} + +//| def run(*coproc: Coproc) -> None: +//| """Runs the loaded program.""" +//| ... +//| +STATIC mp_obj_t coproc_run(mp_obj_t self_in) { + common_hal_coproc_run(get_coproc_obj(&self_in)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(coproc_run_obj, coproc_run); + +//| def halt(*coproc: Coproc) -> None: +//| """Halts the loaded program.""" +//| ... +//| +STATIC mp_obj_t coproc_halt(mp_obj_t self_in) { + common_hal_coproc_halt(get_coproc_obj(&self_in)); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(coproc_halt_obj, coproc_halt); + +//| def memory(*coproc: Coproc) -> CoprocMemory: +//| """Returns the shared memory as a bytearray.""" +//| ... +//| +STATIC mp_obj_t coproc_memory(mp_obj_t self_in) { + return common_hal_coproc_memory(get_coproc_obj(&self_in)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(coproc_memory_obj, coproc_memory); + +STATIC const mp_rom_map_elem_t coproc_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_coproc) }, + + // module functions + { MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&coproc_run_obj) }, + { MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&coproc_halt_obj) }, + { MP_ROM_QSTR(MP_QSTR_memory), MP_ROM_PTR(&coproc_memory_obj) }, + + // module classes + { MP_ROM_QSTR(MP_QSTR_Coproc), MP_OBJ_FROM_PTR(&coproc_coproc_type) }, + { MP_ROM_QSTR(MP_QSTR_CoprocMemory), MP_OBJ_FROM_PTR(&coproc_memory_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(coproc_module_globals, coproc_module_globals_table); + +const mp_obj_module_t coproc_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&coproc_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_coproc, coproc_module, CIRCUITPY_COPROC); diff --git a/shared-bindings/coproc/__init__.h b/shared-bindings/coproc/__init__.h new file mode 100644 index 0000000000..6f2b2a56ae --- /dev/null +++ b/shared-bindings/coproc/__init__.h @@ -0,0 +1,37 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 microDev + * + * 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_COPROC___INIT___H +#define MICROPY_INCLUDED_SHARED_BINDINGS_COPROC___INIT___H + +#include "py/obj.h" +#include "common-hal/coproc/Coproc.h" + +extern void common_hal_coproc_run(coproc_coproc_obj_t *self); +extern void common_hal_coproc_halt(coproc_coproc_obj_t *self); +extern mp_obj_t common_hal_coproc_memory(coproc_coproc_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_COPROC___INIT___H