Merge pull request #7359 from tannewt/rework_coproc_api
Rework the coproc API
This commit is contained in:
commit
2a1bb72797
|
@ -100,6 +100,7 @@ msgstr ""
|
|||
msgid "%q failure: %d"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/espulp/ULP.c
|
||||
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
|
||||
#: shared-bindings/digitalio/DigitalInOut.c
|
||||
#: shared-bindings/microcontroller/Pin.c
|
||||
|
@ -180,7 +181,6 @@ msgstr ""
|
|||
|
||||
#: ports/atmel-samd/common-hal/pulseio/PulseIn.c
|
||||
#: ports/cxd56/common-hal/pulseio/PulseIn.c
|
||||
#: ports/espressif/common-hal/coproc/Coproc.c
|
||||
#: ports/nrf/common-hal/pulseio/PulseIn.c
|
||||
#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c
|
||||
#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c
|
||||
|
@ -393,6 +393,10 @@ msgstr ""
|
|||
msgid "Address must be %d bytes long"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/memorymap/AddressRange.c
|
||||
msgid "Address range not allowed"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/canio/CAN.c
|
||||
msgid "All CAN peripherals are in use"
|
||||
msgstr ""
|
||||
|
@ -473,7 +477,7 @@ msgstr ""
|
|||
msgid "Already have all-matches listener"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/coproc/__init__.c
|
||||
#: ports/espressif/common-hal/espulp/ULP.c
|
||||
#: shared-module/memorymonitor/AllocationAlarm.c
|
||||
#: shared-module/memorymonitor/AllocationSize.c
|
||||
msgid "Already running"
|
||||
|
@ -497,7 +501,7 @@ msgstr ""
|
|||
msgid "Array must contain halfwords (type 'H')"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/alarm/SleepMemory.c shared-bindings/coproc/CoprocMemory.c
|
||||
#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c
|
||||
#: shared-bindings/nvm/ByteArray.c
|
||||
msgid "Array values should be single bytes."
|
||||
msgstr ""
|
||||
|
@ -914,10 +918,10 @@ msgstr ""
|
|||
msgid "Error: Failure to bind"
|
||||
msgstr ""
|
||||
|
||||
#: py/enum.c shared-bindings/_bleio/__init__.c shared-bindings/aesio/aes.c
|
||||
#: shared-bindings/alarm/__init__.c shared-bindings/alarm/coproc/CoprocAlarm.c
|
||||
#: shared-bindings/busio/SPI.c shared-bindings/coproc/Coproc.c
|
||||
#: shared-bindings/coproc/__init__.c shared-bindings/microcontroller/Pin.c
|
||||
#: ports/espressif/bindings/espulp/ULP.c 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/microcontroller/Pin.c
|
||||
#: shared-bindings/neopixel_write/__init__.c
|
||||
msgid "Expected a %q"
|
||||
msgstr ""
|
||||
|
@ -1020,7 +1024,6 @@ msgstr ""
|
|||
msgid "Firmware is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/coproc/Coproc.c
|
||||
#: ports/espressif/common-hal/dualbank/__init__.c
|
||||
msgid "Firmware is too big"
|
||||
msgstr ""
|
||||
|
@ -1628,11 +1631,14 @@ msgid ""
|
|||
"%d bpp given"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/alarm/coproc/CoprocAlarm.c
|
||||
#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c
|
||||
msgid "Only one %q can be set in deep sleep."
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/espulp/ULPAlarm.c
|
||||
msgid "Only one %q can be set."
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/i2ctarget/I2CTarget.c
|
||||
#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c
|
||||
msgid "Only one address is allowed"
|
||||
|
@ -1748,6 +1754,10 @@ msgid ""
|
|||
"constructor"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/espulp/ULP.c
|
||||
msgid "Pins 21+ not supported from ULP"
|
||||
msgstr ""
|
||||
|
||||
#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c
|
||||
msgid "Pins must be sequential"
|
||||
msgstr ""
|
||||
|
@ -1792,6 +1802,10 @@ msgstr ""
|
|||
msgid "Program size invalid"
|
||||
msgstr ""
|
||||
|
||||
#: ports/espressif/common-hal/espulp/ULP.c
|
||||
msgid "Program too long"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/digitalio/DigitalInOut.c
|
||||
msgid "Pull not used when direction is output."
|
||||
msgstr ""
|
||||
|
@ -1936,7 +1950,7 @@ msgstr ""
|
|||
msgid "Sleep Memory not available"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/alarm/SleepMemory.c shared-bindings/coproc/CoprocMemory.c
|
||||
#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c
|
||||
#: shared-bindings/nvm/ByteArray.c
|
||||
msgid "Slice and value different lengths."
|
||||
msgstr ""
|
||||
|
@ -2210,8 +2224,8 @@ msgstr ""
|
|||
msgid "Unable to start mDNS query"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/coproc/CoprocMemory.c
|
||||
msgid "Unable to write"
|
||||
#: shared-bindings/memorymap/AddressRange.c
|
||||
msgid "Unable to write to address."
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/nvm/ByteArray.c
|
||||
|
@ -2467,7 +2481,7 @@ msgid "array has too many dimensions"
|
|||
msgstr ""
|
||||
|
||||
#: py/objarray.c shared-bindings/alarm/SleepMemory.c
|
||||
#: shared-bindings/coproc/CoprocMemory.c shared-bindings/nvm/ByteArray.c
|
||||
#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c
|
||||
msgid "array/bytes required on right side"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3725,7 +3739,7 @@ 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/coproc/CoprocMemory.c
|
||||
#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c
|
||||
#: shared-bindings/nvm/ByteArray.c
|
||||
msgid "only slices with step=1 (aka None) are supported"
|
||||
msgstr ""
|
||||
|
|
|
@ -100,8 +100,6 @@ 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
|
||||
|
||||
|
@ -261,6 +259,15 @@ CFLAGS += -isystem esp32-camera/driver/include
|
|||
CFLAGS += -isystem esp32-camera/conversions/include
|
||||
endif
|
||||
|
||||
ifneq ($(CIRCUITPY_ESPULP),0)
|
||||
SRC_ULP := \
|
||||
$(wildcard common-hal/espulp/*.c) \
|
||||
$(wildcard bindings/espulp/*.c)
|
||||
SRC_C += $(SRC_ULP)
|
||||
CFLAGS += -isystem esp-idf/components/ulp/include
|
||||
CFLAGS += -isystem esp-idf/components/ulp/ulp_riscv/include
|
||||
endif
|
||||
|
||||
SRC_COMMON_HAL_EXPANDED = \
|
||||
$(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
|
||||
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
|
||||
|
@ -364,7 +371,7 @@ 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)
|
||||
ifneq ($(CIRCUITPY_ESPULP),0)
|
||||
ESP_IDF_COMPONENTS_LINK += ulp
|
||||
endif
|
||||
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* 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/microcontroller/Pin.h"
|
||||
#include "shared-bindings/util.h"
|
||||
#include "bindings/espulp/ULP.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
//| class ULP:
|
||||
//| def __init__(self):
|
||||
//| """The ultra-low-power processor.
|
||||
//|
|
||||
//| Raises an exception if another ULP has been instantiated. This
|
||||
//| ensures that is is only used by one piece of code at a time."""
|
||||
//| ...
|
||||
STATIC mp_obj_t espulp_ulp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
espulp_ulp_obj_t *self = m_new_obj(espulp_ulp_obj_t);
|
||||
self->base.type = &espulp_ulp_type;
|
||||
common_hal_espulp_ulp_construct(self);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
STATIC espulp_ulp_obj_t *get_ulp_obj(mp_obj_t self_in) {
|
||||
if (!mp_obj_is_type(self_in, &espulp_ulp_type)) {
|
||||
mp_raise_TypeError_varg(translate("Expected a %q"), MP_QSTR_ULP);
|
||||
}
|
||||
espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (common_hal_espulp_ulp_deinited(self)) {
|
||||
raise_deinited_error();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
//| def deinit(self) -> None:
|
||||
//| """Deinitialises the ULP and releases it for another program."""
|
||||
//| ...
|
||||
STATIC mp_obj_t espulp_ulp_deinit(mp_obj_t self_in) {
|
||||
espulp_ulp_obj_t *self = get_ulp_obj(self_in);
|
||||
common_hal_espulp_ulp_deinit(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_deinit_obj, espulp_ulp_deinit);
|
||||
|
||||
//| def __enter__(self) -> ULP:
|
||||
//| """No-op used by Context Managers."""
|
||||
//| ...
|
||||
// Provided by context manager helper.
|
||||
|
||||
//| def __exit__(self) -> None:
|
||||
//| """Automatically deinitializes the hardware when exiting a context. See
|
||||
//| :ref:`lifetime-and-contextmanagers` for more info."""
|
||||
//| ...
|
||||
STATIC mp_obj_t espulp_ulp_obj___exit__(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
return espulp_ulp_deinit(args[0]);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espulp_ulp___exit___obj, 4, 4, espulp_ulp_obj___exit__);
|
||||
|
||||
//| def run(
|
||||
//| self, program: ReadableBuffer, *, pins: Sequence[microcontroller.Pin] = ()
|
||||
//| ) -> None:
|
||||
//| """Loads the program into ULP memory and then runs the program. The given pins are
|
||||
//| claimed and not reset until `halt()` is called.
|
||||
//|
|
||||
//| The program will continue to run even when the running Python is halted."""
|
||||
//| ...
|
||||
STATIC mp_obj_t espulp_ulp_run(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_program, ARG_pins };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ},
|
||||
{ MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} },
|
||||
};
|
||||
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
espulp_ulp_obj_t *self = get_ulp_obj(pos_args[0]);
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[ARG_program].u_obj, &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
mp_obj_t pins_in = args[ARG_pins].u_obj;
|
||||
const size_t num_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(pins_in));
|
||||
|
||||
// The ULP only supports 21 pins on the ESP32-S2 and S3. So we can store it
|
||||
// as a bitmask in a 32 bit number. The common-hal code does further checks.
|
||||
uint32_t pin_mask = 0;
|
||||
|
||||
for (mp_uint_t i = 0; i < num_pins; i++) {
|
||||
mp_obj_t pin_obj = mp_obj_subscr(pins_in, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL);
|
||||
validate_obj_is_free_pin(pin_obj);
|
||||
const mcu_pin_obj_t *pin = ((const mcu_pin_obj_t *)pin_obj);
|
||||
if (pin->number >= 32) {
|
||||
raise_ValueError_invalid_pin();
|
||||
}
|
||||
pin_mask |= 1 << pin->number;
|
||||
}
|
||||
|
||||
common_hal_espulp_ulp_run(self, bufinfo.buf, bufinfo.len, pin_mask);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(espulp_ulp_run_obj, 2, espulp_ulp_run);
|
||||
|
||||
//| def halt(self) -> None:
|
||||
//| """Halts the running program and releases the pins given in `run()`."""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t espulp_ulp_halt(mp_obj_t self_in) {
|
||||
common_hal_espulp_ulp_halt(get_ulp_obj(self_in));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_halt_obj, espulp_ulp_halt);
|
||||
|
||||
STATIC const mp_rom_map_elem_t espulp_ulp_locals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espulp_ulp_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espulp_ulp___exit___obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&espulp_ulp_run_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&espulp_ulp_halt_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(espulp_ulp_locals_dict, espulp_ulp_locals_table);
|
||||
|
||||
const mp_obj_type_t espulp_ulp_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ULP,
|
||||
.make_new = espulp_ulp_make_new,
|
||||
.locals_dict = (mp_obj_t)&espulp_ulp_locals_dict,
|
||||
};
|
|
@ -24,14 +24,17 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_COPROC___INIT___H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_COPROC___INIT___H
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "common-hal/coproc/Coproc.h"
|
||||
#include "common-hal/espulp/ULP.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
|
||||
extern const mp_obj_type_t espulp_ulp_type;
|
||||
|
||||
void common_hal_espulp_ulp_construct(espulp_ulp_obj_t *self);
|
||||
bool common_hal_espulp_ulp_deinited(espulp_ulp_obj_t *self);
|
||||
void common_hal_espulp_ulp_deinit(espulp_ulp_obj_t *self);
|
||||
|
||||
void common_hal_espulp_ulp_run(espulp_ulp_obj_t *self, uint32_t *program, size_t length, uint32_t pin_mask);
|
||||
void common_hal_espulp_ulp_halt(espulp_ulp_obj_t *self);
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
|
@ -24,17 +24,33 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_COPROC_COPROC_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_COPROC_COPROC_H
|
||||
#include "bindings/espulp/ULPAlarm.h"
|
||||
|
||||
#include "common-hal/coproc/Coproc.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
extern const mp_obj_type_t coproc_coproc_type;
|
||||
//| class ULPAlarm:
|
||||
//| """Trigger an alarm when the ULP requests wake-up."""
|
||||
//|
|
||||
//| def __init__(self) -> None:
|
||||
//| """Create an alarm that will be triggered when the ULP requests wake-up.
|
||||
//|
|
||||
//| The alarm is not active until it is passed to an `alarm`-enabling function, such as
|
||||
//| `alarm.light_sleep_until_alarms()` or `alarm.exit_and_deep_sleep_until_alarms()`.
|
||||
//|
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t espulp_ulpalarm_make_new(const mp_obj_type_t *type,
|
||||
size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
|
||||
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);
|
||||
espulp_ulpalarm_obj_t *self = m_new_obj(espulp_ulpalarm_obj_t);
|
||||
self->base.type = &espulp_ulpalarm_type;
|
||||
common_hal_espulp_ulpalarm_construct(self);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
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
|
||||
const mp_obj_type_t espulp_ulpalarm_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ULPAlarm,
|
||||
.make_new = espulp_ulpalarm_make_new,
|
||||
};
|
|
@ -24,11 +24,10 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_COPROC_COPROCALARM_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_COPROC_COPROCALARM_H
|
||||
#pragma once
|
||||
|
||||
#include "common-hal/alarm/coproc/CoprocAlarm.h"
|
||||
#include "common-hal/espulp/ULPAlarm.h"
|
||||
|
||||
extern const mp_obj_type_t alarm_coproc_coprocalarm_type;
|
||||
extern const mp_obj_type_t espulp_ulpalarm_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_COPROC_COPROCALARM_H
|
||||
void common_hal_espulp_ulpalarm_construct(espulp_ulpalarm_obj_t *self);
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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 "bindings/espulp/__init__.h"
|
||||
#include "bindings/espulp/ULP.h"
|
||||
#include "bindings/espulp/ULPAlarm.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
//| """ESP Ultra Low Power Processor Module
|
||||
//|
|
||||
//| The `espulp` module adds ability to load and run
|
||||
//| programs on the ESP32-Sx's ultra-low-power RISC-V processor.
|
||||
//|
|
||||
//| .. code-block:: python
|
||||
//|
|
||||
//| import espulp
|
||||
//| import memorymap
|
||||
//|
|
||||
//| shared_mem = memorymap.AddressRange(start=0x50000000, length=1024)
|
||||
//| ulp = espulp.ULP()
|
||||
//|
|
||||
//| with open("program.bin", "rb") as f:
|
||||
//| program = f.read()
|
||||
//|
|
||||
//| ulp.run(program)
|
||||
//| print(shared_mem[0])
|
||||
//| # ulp.halt()
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
|
||||
//| def get_rtc_gpio_number(pin: microcontroller.Pin) -> Optional[int]:
|
||||
//| """Return the RTC GPIO number of the given pin or None if not connected
|
||||
//| to RTC GPIO."""
|
||||
//| ...
|
||||
//|
|
||||
|
||||
STATIC mp_obj_t espulp_get_rtc_gpio_number(mp_obj_t pin_obj) {
|
||||
const mcu_pin_obj_t *pin = validate_obj_is_pin(pin_obj);
|
||||
mp_int_t number = common_hal_espulp_get_rtc_gpio_number(pin);
|
||||
if (number < 0) {
|
||||
return mp_const_none;
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(number);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(espulp_get_rtc_gpio_number_obj, espulp_get_rtc_gpio_number);
|
||||
|
||||
STATIC const mp_rom_map_elem_t espulp_module_globals_table[] = {
|
||||
// module name
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espulp) },
|
||||
|
||||
// module functions
|
||||
{ MP_ROM_QSTR(MP_QSTR_get_rtc_gpio_number), MP_OBJ_FROM_PTR(&espulp_get_rtc_gpio_number_obj) },
|
||||
|
||||
// module classes
|
||||
{ MP_ROM_QSTR(MP_QSTR_ULP), MP_OBJ_FROM_PTR(&espulp_ulp_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ULPAlarm), MP_OBJ_FROM_PTR(&espulp_ulpalarm_type) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(espulp_module_globals, espulp_module_globals_table);
|
||||
|
||||
const mp_obj_module_t espulp_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&espulp_module_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_espulp, espulp_module, CIRCUITPY_ESPULP);
|
|
@ -24,17 +24,10 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROC_H
|
||||
#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROC_H
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "common-hal/coproc/CoprocMemory.h"
|
||||
#include "shared-bindings/microcontroller/Pin.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;
|
||||
void espulp_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROC_H
|
||||
mp_int_t common_hal_espulp_get_rtc_gpio_number(const mcu_pin_obj_t *pin);
|
|
@ -35,11 +35,14 @@
|
|||
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||
#include "shared-bindings/alarm/touch/TouchAlarm.h"
|
||||
#include "shared-bindings/alarm/coproc/CoprocAlarm.h"
|
||||
|
||||
#include "shared-bindings/wifi/__init__.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
#if CIRCUITPY_ESPULP
|
||||
#include "bindings/espulp/ULPAlarm.h"
|
||||
#endif
|
||||
|
||||
#include "common-hal/digitalio/DigitalInOut.h"
|
||||
|
||||
#include "supervisor/port.h"
|
||||
|
@ -67,7 +70,9 @@ void alarm_reset(void) {
|
|||
alarm_pin_pinalarm_reset();
|
||||
alarm_time_timealarm_reset();
|
||||
alarm_touch_touchalarm_reset();
|
||||
alarm_coproc_coprocalarm_reset();
|
||||
#if CIRCUITPY_ESPULP
|
||||
espulp_ulpalarm_reset();
|
||||
#endif
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||
}
|
||||
|
||||
|
@ -82,9 +87,11 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
|
|||
if (alarm_touch_touchalarm_woke_this_cycle()) {
|
||||
return ESP_SLEEP_WAKEUP_TOUCHPAD;
|
||||
}
|
||||
if (alarm_coproc_coprocalarm_woke_this_cycle()) {
|
||||
#if CIRCUITPY_ESPULP
|
||||
if (espulp_ulpalarm_woke_this_cycle()) {
|
||||
return ESP_SLEEP_WAKEUP_ULP;
|
||||
}
|
||||
#endif
|
||||
// If waking from true deep sleep, modules will have lost their state,
|
||||
// so check the deep wakeup cause manually
|
||||
return esp_sleep_get_wakeup_cause();
|
||||
|
@ -113,9 +120,11 @@ mp_obj_t common_hal_alarm_record_wake_alarm(void) {
|
|||
return alarm_touch_touchalarm_record_wake_alarm();
|
||||
}
|
||||
|
||||
#if CIRCUITPY_ESPULP
|
||||
case ESP_SLEEP_WAKEUP_ULP: {
|
||||
return alarm_coproc_coprocalarm_record_wake_alarm();
|
||||
return espulp_ulpalarm_record_wake_alarm();
|
||||
}
|
||||
#endif
|
||||
|
||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
default:
|
||||
|
@ -130,7 +139,9 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t
|
|||
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||
alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
||||
alarm_coproc_coprocalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
||||
#if CIRCUITPY_ESPULP
|
||||
espulp_ulpalarm_set_alarm(deep_sleep, n_alarms, alarms);
|
||||
#endif
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
|
@ -157,10 +168,12 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
|
|||
wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms,alarms);
|
||||
break;
|
||||
}
|
||||
#if CIRCUITPY_ESPULP
|
||||
case ESP_SLEEP_WAKEUP_ULP: {
|
||||
wake_alarm = alarm_coproc_coprocalarm_find_triggered_alarm(n_alarms,alarms);
|
||||
wake_alarm = espulp_ulpalarm_find_triggered_alarm(n_alarms,alarms);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
// Should not reach this, if all light sleep types are covered correctly
|
||||
break;
|
||||
|
@ -187,7 +200,9 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
|
|||
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
|
||||
alarm_pin_pinalarm_prepare_for_deep_sleep();
|
||||
alarm_touch_touchalarm_prepare_for_deep_sleep();
|
||||
alarm_coproc_coprocalarm_prepare_for_deep_sleep();
|
||||
#if CIRCUITPY_ESPULP
|
||||
espulp_ulpalarm_prepare_for_deep_sleep();
|
||||
#endif
|
||||
|
||||
// We no longer need to remember the pin preservations, since any pin resets are all done.
|
||||
clear_pin_preservations();
|
||||
|
|
|
@ -27,13 +27,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "common-hal/alarm/SleepMemory.h"
|
||||
#include "common-hal/alarm/coproc/CoprocAlarm.h"
|
||||
#include "common-hal/alarm/pin/PinAlarm.h"
|
||||
#include "common-hal/alarm/time/TimeAlarm.h"
|
||||
#include "common-hal/alarm/touch/TouchAlarm.h"
|
||||
|
||||
#if CIRCUITPY_ESPULP
|
||||
#include "common-hal/espulp/ULPAlarm.h"
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
alarm_coproc_coprocalarm_obj_t coproc_alarm;
|
||||
#if CIRCUITPY_ESPULP
|
||||
espulp_ulpalarm_obj_t ulp_alarm;
|
||||
#endif
|
||||
alarm_pin_pinalarm_obj_t pin_alarm;
|
||||
alarm_time_timealarm_obj_t time_alarm;
|
||||
alarm_touch_touchalarm_obj_t touch_alarm;
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython 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/alarm/__init__.h"
|
||||
#include "shared-bindings/alarm/coproc/CoprocAlarm.h"
|
||||
#include "shared-bindings/coproc/__init__.h"
|
||||
|
||||
#if CIRCUITPY_COPROC
|
||||
|
||||
#include "supervisor/port.h"
|
||||
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "esp_sleep.h"
|
||||
|
||||
static volatile bool woke_up = false;
|
||||
|
||||
mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (mp_obj_is_type(alarms[i], &alarm_coproc_coprocalarm_type)) {
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t alarm_coproc_coprocalarm_record_wake_alarm(void) {
|
||||
alarm_coproc_coprocalarm_obj_t *const alarm = &alarm_wake_alarm.coproc_alarm;
|
||||
|
||||
alarm->base.type = &alarm_coproc_coprocalarm_type;
|
||||
return alarm;
|
||||
}
|
||||
|
||||
// This is used to wake the main CircuitPython task.
|
||||
STATIC void coproc_interrupt(void *arg) {
|
||||
(void)arg;
|
||||
woke_up = true;
|
||||
port_wake_main_task_from_isr();
|
||||
}
|
||||
|
||||
void alarm_coproc_coprocalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
bool coproc_alarm_set = false;
|
||||
alarm_coproc_coprocalarm_obj_t *coproc_alarm = MP_OBJ_NULL;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (mp_obj_is_type(alarms[i], &alarm_coproc_coprocalarm_type)) {
|
||||
if (deep_sleep && coproc_alarm_set) {
|
||||
mp_raise_ValueError_varg(translate("Only one %q can be set in deep sleep."), MP_QSTR_CoprocAlarm);
|
||||
}
|
||||
coproc_alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
coproc_alarm_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!coproc_alarm_set) {
|
||||
return;
|
||||
}
|
||||
|
||||
// enable coproc interrupt
|
||||
rtc_isr_register(&coproc_interrupt, NULL, RTC_CNTL_COCPU_INT_ST);
|
||||
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA);
|
||||
|
||||
// start coproc program
|
||||
common_hal_coproc_run(coproc_alarm->coproc);
|
||||
}
|
||||
|
||||
void alarm_coproc_coprocalarm_prepare_for_deep_sleep(void) {
|
||||
// disbale coproc interrupt
|
||||
rtc_isr_deregister(&coproc_interrupt, NULL);
|
||||
REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA);
|
||||
|
||||
// enable coproc wakeup
|
||||
esp_sleep_enable_ulp_wakeup();
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
|
||||
}
|
||||
|
||||
bool alarm_coproc_coprocalarm_woke_this_cycle(void) {
|
||||
return woke_up;
|
||||
}
|
||||
|
||||
void alarm_coproc_coprocalarm_reset(void) {
|
||||
woke_up = false;
|
||||
}
|
||||
|
||||
#else // CIRCUITPY_COPROC
|
||||
|
||||
mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t alarm_coproc_coprocalarm_record_wake_alarm(void) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
void alarm_coproc_coprocalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
}
|
||||
|
||||
void alarm_coproc_coprocalarm_prepare_for_deep_sleep(void) {
|
||||
}
|
||||
|
||||
bool alarm_coproc_coprocalarm_woke_this_cycle(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void alarm_coproc_coprocalarm_reset(void) {
|
||||
}
|
||||
|
||||
#endif // CIRCUITPY_COPROC
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#include "esp32s2/ulp.h"
|
||||
#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM)
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#include "esp32s3/ulp.h"
|
||||
#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM)
|
||||
#endif
|
||||
|
||||
#define RTC_SLOW_MEM_END ((uint32_t)RTC_SLOW_MEM + ULP_COPROC_RESERVE_MEM)
|
||||
|
||||
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
|
||||
if (coproc_memory != NULL) {
|
||||
if (coproc_memory->address < ((uint32_t)RTC_SLOW_MEM + buf_len) ||
|
||||
coproc_memory->address > (RTC_SLOW_MEM_END - coproc_memory->len)) {
|
||||
mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_CoprocMemory);
|
||||
}
|
||||
}
|
||||
self->coproc_memory = coproc_memory;
|
||||
|
||||
// load buffer
|
||||
if (buf_len > ULP_COPROC_RESERVE_MEM) {
|
||||
mp_raise_RuntimeError(translate("Firmware is too big"));
|
||||
}
|
||||
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;
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* 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 (GET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN)) {
|
||||
mp_raise_RuntimeError(translate("Already running"));
|
||||
}
|
||||
|
||||
ulp_riscv_load_binary(self->buf, self->buf_len);
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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 "bindings/espulp/__init__.h"
|
||||
#include "bindings/espulp/ULP.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
#include "esp32s2/ulp.h"
|
||||
#include "esp32s2/ulp_riscv.h"
|
||||
#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM)
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#include "esp32s3/ulp.h"
|
||||
#include "esp32s3/ulp_riscv.h"
|
||||
#define ULP_COPROC_RESERVE_MEM (CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM)
|
||||
#endif
|
||||
|
||||
// To-do idf v5.0: remove following include
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
STATIC bool ulp_used = false;
|
||||
STATIC uint32_t pins_used = 0;
|
||||
|
||||
void espulp_reset(void) {
|
||||
// NOTE: This *doesn't* disable the ULP. It'll keep running even when CircuitPython isn't.
|
||||
ulp_used = false;
|
||||
}
|
||||
|
||||
void common_hal_espulp_ulp_run(espulp_ulp_obj_t *self, uint32_t *program, size_t length, uint32_t pin_mask) {
|
||||
if (length > ULP_COPROC_RESERVE_MEM) {
|
||||
mp_raise_ValueError(translate("Program too long"));
|
||||
}
|
||||
if (GET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN)) {
|
||||
mp_raise_RuntimeError(translate("Already running"));
|
||||
}
|
||||
|
||||
if (pin_mask >= (1 << 22)) {
|
||||
raise_ValueError_invalid_pin();
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
if ((pin_mask & (1 << i)) != 0 && !pin_number_is_free(i)) {
|
||||
mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_Pin);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
if ((pin_mask & (1 << i)) != 0) {
|
||||
claim_pin_number(i);
|
||||
never_reset_pin_number(i);
|
||||
}
|
||||
}
|
||||
pins_used = pin_mask;
|
||||
|
||||
|
||||
ulp_riscv_load_binary((const uint8_t *)program, length);
|
||||
ulp_set_wakeup_period(0, 20000);
|
||||
ulp_riscv_run();
|
||||
}
|
||||
|
||||
void common_hal_espulp_ulp_halt(espulp_ulp_obj_t *self) {
|
||||
// To-do idf v5.0: use following functions
|
||||
// ulp_riscv_timer_stop();
|
||||
// ulp_riscv_halt();
|
||||
|
||||
// stop the ulp timer so that it doesn't restart the cpu
|
||||
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);
|
||||
|
||||
// Release pins we were using.
|
||||
for (uint8_t i = 0; i < 32; i++) {
|
||||
if ((pins_used & (1 << i)) != 0) {
|
||||
reset_pin_number(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_espulp_ulp_construct(espulp_ulp_obj_t *self) {
|
||||
// Use a static variable to track ULP in use so that subsequent code runs can
|
||||
// use a running ULP. This is only to prevent multiple portions of user code
|
||||
// from using the ULP concurrently.
|
||||
if (ulp_used) {
|
||||
mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_ULP);
|
||||
}
|
||||
self->inited = true;
|
||||
}
|
||||
|
||||
bool common_hal_espulp_ulp_deinited(espulp_ulp_obj_t *self) {
|
||||
return !self->inited;
|
||||
}
|
||||
|
||||
void common_hal_espulp_ulp_deinit(espulp_ulp_obj_t *self) {
|
||||
if (common_hal_espulp_ulp_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
common_hal_espulp_ulp_halt(self);
|
||||
self->inited = false;
|
||||
ulp_used = false;
|
||||
}
|
|
@ -24,15 +24,11 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROCMEMORY_H
|
||||
#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_COPROC_COPROCMEMORY_H
|
||||
#pragma once
|
||||
|
||||
#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
|
||||
bool inited;
|
||||
} espulp_ulp_obj_t;
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* This file is part of the MicroPython 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 "bindings/espulp/ULPAlarm.h"
|
||||
|
||||
#include "common-hal/alarm/__init__.h"
|
||||
#include "supervisor/port.h"
|
||||
|
||||
#include "driver/rtc_cntl.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "esp_sleep.h"
|
||||
|
||||
static volatile bool woke_up = false;
|
||||
static bool alarm_set = false;
|
||||
|
||||
void common_hal_espulp_ulpalarm_construct(espulp_ulpalarm_obj_t *self) {
|
||||
|
||||
}
|
||||
|
||||
mp_obj_t espulp_ulpalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (mp_obj_is_type(alarms[i], &espulp_ulpalarm_type)) {
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t espulp_ulpalarm_record_wake_alarm(void) {
|
||||
espulp_ulpalarm_obj_t *const alarm = &alarm_wake_alarm.ulp_alarm;
|
||||
|
||||
alarm->base.type = &espulp_ulpalarm_type;
|
||||
return alarm;
|
||||
}
|
||||
|
||||
// This is used to wake the main CircuitPython task.
|
||||
STATIC void ulp_interrupt(void *arg) {
|
||||
(void)arg;
|
||||
woke_up = true;
|
||||
port_wake_main_task_from_isr();
|
||||
}
|
||||
|
||||
void espulp_ulpalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) {
|
||||
espulp_ulpalarm_obj_t *alarm = MP_OBJ_NULL;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (mp_obj_is_type(alarms[i], &espulp_ulpalarm_type)) {
|
||||
if (alarm != MP_OBJ_NULL) {
|
||||
mp_raise_ValueError_varg(translate("Only one %q can be set."), MP_QSTR_ULPAlarm);
|
||||
}
|
||||
alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (alarm == MP_OBJ_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// enable ulp interrupt
|
||||
rtc_isr_register(&ulp_interrupt, NULL, RTC_CNTL_COCPU_INT_ST);
|
||||
REG_SET_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA);
|
||||
|
||||
alarm_set = true;
|
||||
}
|
||||
|
||||
void espulp_ulpalarm_prepare_for_deep_sleep(void) {
|
||||
if (!alarm_set) {
|
||||
return;
|
||||
}
|
||||
// disable ulp interrupt
|
||||
rtc_isr_deregister(&ulp_interrupt, NULL);
|
||||
REG_CLR_BIT(RTC_CNTL_INT_ENA_REG, RTC_CNTL_COCPU_INT_ENA);
|
||||
|
||||
// enable ulp wakeup
|
||||
esp_sleep_enable_ulp_wakeup();
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_ON);
|
||||
}
|
||||
|
||||
bool espulp_ulpalarm_woke_this_cycle(void) {
|
||||
return woke_up;
|
||||
}
|
||||
|
||||
void espulp_ulpalarm_reset(void) {
|
||||
woke_up = false;
|
||||
alarm_set = false;
|
||||
}
|
|
@ -29,17 +29,14 @@
|
|||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "common-hal/coproc/Coproc.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
coproc_coproc_obj_t *coproc;
|
||||
} alarm_coproc_coprocalarm_obj_t;
|
||||
} espulp_ulpalarm_obj_t;
|
||||
|
||||
mp_obj_t alarm_coproc_coprocalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms);
|
||||
mp_obj_t alarm_coproc_coprocalarm_record_wake_alarm(void);
|
||||
mp_obj_t espulp_ulpalarm_find_triggered_alarm(const size_t n_alarms, const mp_obj_t *alarms);
|
||||
mp_obj_t espulp_ulpalarm_record_wake_alarm(void);
|
||||
|
||||
void alarm_coproc_coprocalarm_prepare_for_deep_sleep(void);
|
||||
void alarm_coproc_coprocalarm_reset(void);
|
||||
void alarm_coproc_coprocalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
|
||||
bool alarm_coproc_coprocalarm_woke_this_cycle(void);
|
||||
void espulp_ulpalarm_prepare_for_deep_sleep(void);
|
||||
void espulp_ulpalarm_reset(void);
|
||||
void espulp_ulpalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms);
|
||||
bool espulp_ulpalarm_woke_this_cycle(void);
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries LLC
|
||||
*
|
||||
* 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 "bindings/espulp/__init__.h"
|
||||
|
||||
mp_int_t common_hal_espulp_get_rtc_gpio_number(const mcu_pin_obj_t *pin) {
|
||||
if (pin->number <= 21) {
|
||||
return pin->number;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 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 <string.h>
|
||||
|
||||
#include "shared-bindings/memorymap/AddressRange.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
|
||||
size_t allow_ranges[][2] = {
|
||||
// ULP accessible RAM
|
||||
{SOC_RTC_DATA_LOW, SOC_RTC_DATA_HIGH},
|
||||
// CPU accessible RAM that is preserved during sleep if the RTC power domain is left on.
|
||||
{SOC_RTC_DRAM_LOW, SOC_RTC_DRAM_HIGH},
|
||||
// RTC peripheral registers
|
||||
{0x60008000, 0x60009000}
|
||||
|
||||
};
|
||||
|
||||
void common_hal_memorymap_addressrange_construct(memorymap_addressrange_obj_t *self, uint8_t *start_address, size_t length) {
|
||||
bool allowed = false;
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(allow_ranges); i++) {
|
||||
uint8_t *allowed_start = (uint8_t *)allow_ranges[i][0];
|
||||
uint8_t *allowed_end = (uint8_t *)allow_ranges[i][1];
|
||||
if (allowed_start <= start_address &&
|
||||
(start_address + length) <= allowed_end) {
|
||||
allowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowed) {
|
||||
mp_raise_ValueError(translate("Address range not allowed"));
|
||||
}
|
||||
|
||||
self->start_address = start_address;
|
||||
self->len = length;
|
||||
}
|
||||
|
||||
size_t common_hal_memorymap_addressrange_get_length(const memorymap_addressrange_obj_t *self) {
|
||||
return self->len;
|
||||
}
|
||||
|
||||
bool common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_obj_t *self,
|
||||
size_t start_index, uint8_t *values, size_t len) {
|
||||
uint8_t *address = self->start_address + start_index;
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
if (len == 1) {
|
||||
*((uint8_t *)address) = values[0];
|
||||
} else if (len == sizeof(uint16_t) && (((size_t)address) % sizeof(uint16_t)) == 0) {
|
||||
*((uint16_t *)address) = ((uint16_t *)values)[0];
|
||||
} else if (len == sizeof(uint32_t) && (((size_t)address) % sizeof(uint32_t)) == 0) {
|
||||
*((uint32_t *)address) = ((uint32_t *)values)[0];
|
||||
} else if (len == sizeof(uint64_t) && (((size_t)address) % sizeof(uint64_t)) == 0) {
|
||||
*((uint64_t *)address) = ((uint64_t *)values)[0];
|
||||
} else {
|
||||
memcpy(address, values, len);
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void common_hal_memorymap_addressrange_get_bytes(const memorymap_addressrange_obj_t *self,
|
||||
size_t start_index, size_t len, uint8_t *values) {
|
||||
uint8_t *address = self->start_address + start_index;
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
if (len == 1) {
|
||||
values[0] = *((uint8_t *)address);
|
||||
} else if (len == sizeof(uint16_t) && (((size_t)address) % sizeof(uint16_t)) == 0) {
|
||||
((uint16_t *)values)[0] = *((uint16_t *)address);
|
||||
} else if (len == sizeof(uint32_t) && (((size_t)address) % sizeof(uint32_t)) == 0) {
|
||||
((uint32_t *)values)[0] = *((uint32_t *)address);
|
||||
} else if (len == sizeof(uint64_t) && (((size_t)address) % sizeof(uint64_t)) == 0) {
|
||||
((uint64_t *)values)[0] = *((uint64_t *)address);
|
||||
} else {
|
||||
memcpy(values, address, len);
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 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_MEMORYMAP_ADDRESSRANGE_H
|
||||
#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint8_t *start_address;
|
||||
size_t len;
|
||||
} memorymap_addressrange_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H
|
|
@ -0,0 +1 @@
|
|||
// No memorymap module functions.
|
|
@ -139,6 +139,7 @@ mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
|||
case ESP_SLEEP_WAKEUP_EXT0:
|
||||
case ESP_SLEEP_WAKEUP_EXT1:
|
||||
case ESP_SLEEP_WAKEUP_TOUCHPAD:
|
||||
case ESP_SLEEP_WAKEUP_ULP:
|
||||
return RESET_REASON_DEEP_SLEEP_ALARM;
|
||||
|
||||
case ESP_SLEEP_WAKEUP_UNDEFINED:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 20c6d4a623a9391afd0e803b2bbebe020ed15ec8
|
||||
Subproject commit 8d0f1abce769ad4a212c1bb0337999cacd7ee83d
|
|
@ -22,7 +22,6 @@ CIRCUITPY_AUDIOMP3 ?= 0
|
|||
CIRCUITPY_BLEIO ?= 1
|
||||
CIRCUITPY_BLEIO_HCI = 0
|
||||
CIRCUITPY_CANIO ?= 1
|
||||
CIRCUITPY_COPROC ?= 1
|
||||
CIRCUITPY_COUNTIO ?= 1
|
||||
CIRCUITPY_DUALBANK ?= 1
|
||||
CIRCUITPY_ESP32_CAMERA ?= 1
|
||||
|
@ -44,7 +43,6 @@ CIRCUITPY_WIFI ?= 1
|
|||
ifeq ($(IDF_TARGET),esp32)
|
||||
# Modules
|
||||
CIRCUITPY_BLEIO = 0
|
||||
CIRCUITPY_COPROC = 0
|
||||
CIRCUITPY_PARALLELDISPLAY = 0
|
||||
CIRCUITPY_RGBMATRIX = 0
|
||||
# Features
|
||||
|
@ -54,7 +52,6 @@ else ifeq ($(IDF_TARGET),esp32c3)
|
|||
# Modules
|
||||
CIRCUITPY_ALARM = 0
|
||||
CIRCUITPY_AUDIOBUSIO = 0
|
||||
CIRCUITPY_COPROC = 0
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_ESP32_CAMERA = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
|
@ -68,10 +65,14 @@ CIRCUITPY_USB = 0
|
|||
else ifeq ($(IDF_TARGET),esp32s2)
|
||||
# Modules
|
||||
CIRCUITPY_BLEIO = 0
|
||||
CIRCUITPY_ESPULP = 1
|
||||
CIRCUITPY_MEMORYMAP = 1
|
||||
|
||||
else ifeq ($(IDF_TARGET),esp32s3)
|
||||
# Modules
|
||||
CIRCUITPY_PARALLELDISPLAY = 0
|
||||
CIRCUITPY_ESPULP = 1
|
||||
CIRCUITPY_MEMORYMAP = 1
|
||||
endif
|
||||
|
||||
# No room for dualbank on boards with 2MB flash
|
||||
|
|
|
@ -30,12 +30,14 @@
|
|||
#include "supervisor/board.h"
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/filesystem.h"
|
||||
#include "supervisor/shared/reload.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "bindings/espidf/__init__.h"
|
||||
#include "bindings/espulp/__init__.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/analogio/AnalogOut.h"
|
||||
#include "common-hal/busio/I2C.h"
|
||||
|
@ -367,6 +369,10 @@ void reset_port(void) {
|
|||
dualbank_reset();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_ESPULP
|
||||
espulp_reset();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_FREQUENCYIO
|
||||
peripherals_timer_reset();
|
||||
#endif
|
||||
|
@ -511,7 +517,7 @@ void port_interrupt_after_ticks(uint32_t ticks) {
|
|||
// On the ESP we use FreeRTOS notifications instead of interrupts so this is a
|
||||
// bit of a misnomer.
|
||||
void port_idle_until_interrupt(void) {
|
||||
if (!background_callback_pending()) {
|
||||
if (!background_callback_pending() && !autoreload_pending()) {
|
||||
xTaskNotifyWait(0x01, 0x01, NULL, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,9 +167,6 @@ 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
|
||||
|
@ -227,6 +224,9 @@ endif
|
|||
ifeq ($(CIRCUITPY_MATH),1)
|
||||
SRC_PATTERNS += math/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_MEMORYMAP),1)
|
||||
SRC_PATTERNS += memorymap/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_MEMORYMONITOR),1)
|
||||
SRC_PATTERNS += memorymonitor/%
|
||||
endif
|
||||
|
@ -400,7 +400,6 @@ SRC_COMMON_HAL_ALL = \
|
|||
alarm/pin/PinAlarm.c \
|
||||
alarm/time/TimeAlarm.c \
|
||||
alarm/touch/TouchAlarm.c \
|
||||
alarm/coproc/CoprocAlarm.c \
|
||||
analogbufio/BufferedIn.c \
|
||||
analogbufio/__init__.c \
|
||||
analogio/AnalogIn.c \
|
||||
|
@ -423,9 +422,6 @@ 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 \
|
||||
|
@ -443,9 +439,11 @@ SRC_COMMON_HAL_ALL = \
|
|||
hashlib/Hash.c \
|
||||
i2ctarget/I2CTarget.c \
|
||||
i2ctarget/__init__.c \
|
||||
memorymap/__init__.c \
|
||||
memorymap/AddressRange.c \
|
||||
microcontroller/__init__.c \
|
||||
microcontroller/Pin.c \
|
||||
microcontroller/Processor.c \
|
||||
microcontroller/__init__.c \
|
||||
mdns/__init__.c \
|
||||
mdns/Server.c \
|
||||
mdns/RemoteService.c \
|
||||
|
|
|
@ -221,12 +221,15 @@ CFLAGS += -DCIRCUITPY_OS_GETENV=$(CIRCUITPY_OS_GETENV)
|
|||
CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD)
|
||||
CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO)
|
||||
|
||||
# CIRCUITPY_ESPIDF is handled in the espressif tree.
|
||||
# CIRCUITPY_ESPIDF and CIRCUITPY_ESPULP is handled in the espressif tree.
|
||||
# Only for ESP32S chips.
|
||||
# Assume not a ESP build.
|
||||
CIRCUITPY_ESPIDF ?= 0
|
||||
CFLAGS += -DCIRCUITPY_ESPIDF=$(CIRCUITPY_ESPIDF)
|
||||
|
||||
CIRCUITPY_ESPULP ?= 0
|
||||
CFLAGS += -DCIRCUITPY_ESPULP=$(CIRCUITPY_ESPULP)
|
||||
|
||||
CIRCUITPY_ESP32_CAMERA ?= 0
|
||||
CFLAGS += -DCIRCUITPY_ESP32_CAMERA=$(CIRCUITPY_ESP32_CAMERA)
|
||||
|
||||
|
@ -283,6 +286,9 @@ CFLAGS += -DCIRCUITPY_KEYPAD=$(CIRCUITPY_KEYPAD)
|
|||
CIRCUITPY_MATH ?= 1
|
||||
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
|
||||
|
||||
CIRCUITPY_MEMORYMAP ?= 0
|
||||
CFLAGS += -DCIRCUITPY_MEMORYMAP=$(CIRCUITPY_MEMORYMAP)
|
||||
|
||||
CIRCUITPY_MEMORYMONITOR ?= 0
|
||||
CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR)
|
||||
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#if CIRCUITPY_ESPULP
|
||||
#include "bindings/espulp/ULPAlarm.h"
|
||||
#endif
|
||||
|
||||
#include "shared-bindings/alarm/__init__.h"
|
||||
#include "shared-bindings/alarm/SleepMemory.h"
|
||||
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||
#include "shared-bindings/alarm/touch/TouchAlarm.h"
|
||||
#include "shared-bindings/alarm/coproc/CoprocAlarm.h"
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "shared-bindings/supervisor/Runtime.h"
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
|
@ -77,8 +80,10 @@ STATIC void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
|
|||
for (size_t i = 0; i < n_args; i++) {
|
||||
if (mp_obj_is_type(objs[i], &alarm_pin_pinalarm_type) ||
|
||||
mp_obj_is_type(objs[i], &alarm_time_timealarm_type) ||
|
||||
mp_obj_is_type(objs[i], &alarm_touch_touchalarm_type) ||
|
||||
mp_obj_is_type(objs[i], &alarm_coproc_coprocalarm_type)) {
|
||||
#if CIRCUITPY_ESPULP
|
||||
mp_obj_is_type(objs[i], &espulp_ulpalarm_type) ||
|
||||
#endif
|
||||
mp_obj_is_type(objs[i], &alarm_touch_touchalarm_type)) {
|
||||
continue;
|
||||
}
|
||||
mp_raise_TypeError_varg(translate("Expected an %q"), MP_QSTR_Alarm);
|
||||
|
@ -256,18 +261,6 @@ STATIC const mp_obj_module_t alarm_touch_module = {
|
|||
.globals = (mp_obj_dict_t *)&alarm_touch_globals,
|
||||
};
|
||||
|
||||
STATIC const mp_map_elem_t alarm_coproc_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_coproc) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_CoprocAlarm), MP_OBJ_FROM_PTR(&alarm_coproc_coprocalarm_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_coproc_globals, alarm_coproc_globals_table);
|
||||
|
||||
STATIC const mp_obj_module_t alarm_coproc_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&alarm_coproc_globals,
|
||||
};
|
||||
|
||||
// The module table is mutable because .wake_alarm is a mutable attribute.
|
||||
STATIC mp_map_elem_t alarm_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) },
|
||||
|
@ -282,7 +275,6 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_pin), MP_OBJ_FROM_PTR(&alarm_pin_module) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_OBJ_FROM_PTR(&alarm_time_module) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_touch), MP_OBJ_FROM_PTR(&alarm_touch_module) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_coproc), MP_OBJ_FROM_PTR(&alarm_coproc_module) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_SleepMemory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_memory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_obj) },
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* This file is part of the MicroPython 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/runtime.h"
|
||||
|
||||
#if CIRCUITPY_COPROC
|
||||
#include "shared-bindings/util.h"
|
||||
#include "shared-bindings/alarm/coproc/CoprocAlarm.h"
|
||||
#include "shared-bindings/coproc/Coproc.h"
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
//| class CoprocAlarm:
|
||||
//| """Trigger an alarm when another core or co-processor requests wake-up."""
|
||||
//|
|
||||
//| def __init__(self, coproc: coproc.Coproc) -> None:
|
||||
//| """Create an alarm that will be triggered when the co-processor requests wake-up.
|
||||
//|
|
||||
//| The alarm is not active until it is passed to an `alarm`-enabling function, such as
|
||||
//| `alarm.light_sleep_until_alarms()` or `alarm.exit_and_deep_sleep_until_alarms()`.
|
||||
//|
|
||||
//| :param coproc.Coproc coproc: The coproc program to run.
|
||||
//|
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t alarm_coproc_coprocalarm_make_new(const mp_obj_type_t *type,
|
||||
size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_coproc };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_coproc, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
#if CIRCUITPY_COPROC
|
||||
// initialize CoprocAlarm object
|
||||
alarm_coproc_coprocalarm_obj_t *self = m_new_obj(alarm_coproc_coprocalarm_obj_t);
|
||||
self->base.type = &alarm_coproc_coprocalarm_type;
|
||||
self->coproc = get_coproc_obj(&args[ARG_coproc].u_obj);
|
||||
// return CoprocAlarm object
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
#else
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
return mp_const_none;
|
||||
#endif
|
||||
}
|
||||
|
||||
const mp_obj_type_t alarm_coproc_coprocalarm_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_CoprocAlarm,
|
||||
.make_new = alarm_coproc_coprocalarm_make_new,
|
||||
};
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* 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,
|
||||
};
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* 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
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* 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);
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 microDev
|
||||
* Copyright (c) 2017 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
|
||||
|
@ -28,45 +28,62 @@
|
|||
#include "py/objproperty.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/runtime0.h"
|
||||
|
||||
#include "shared-bindings/coproc/CoprocMemory.h"
|
||||
#include "shared-bindings/memorymap/AddressRange.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
//| class CoprocMemory:
|
||||
//| def __init__(self, address: int, length: int) -> None:
|
||||
//| """Initialize coproc shared memory.
|
||||
//| class AddressRange:
|
||||
//| r"""Presents a range of addresses as a bytearray.
|
||||
//|
|
||||
//| :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 },
|
||||
};
|
||||
//| The addresses may access memory or memory mapped peripherals.
|
||||
//|
|
||||
//| Some address ranges may be protected by CircuitPython to prevent errors.
|
||||
//| An exception will be raised when constructing an AddressRange for an
|
||||
//| invalid or protected address.
|
||||
//|
|
||||
//| Multiple AddressRanges may overlap. There is no "claiming" of addresses.
|
||||
//|
|
||||
//| Example usage on ESP32-S2::
|
||||
//|
|
||||
//| import memorymap
|
||||
//| rtc_slow_mem = memorymap.AddressRange(start=0x50000000, length=0x2000)
|
||||
//| rtc_slow_mem[0:3] = b"\xcc\x10\x00"
|
||||
//| """
|
||||
|
||||
//| def __init__(self, *, start, length) -> None:
|
||||
//| """Constructs an address range starting at ``start`` and ending at
|
||||
//| ``start + length``. An exception will be raised if any of the
|
||||
//| addresses are invalid or protected."""
|
||||
//| ...
|
||||
STATIC mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_start, ARG_length };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_length, MP_ARG_KW_ONLY | 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;
|
||||
size_t start =
|
||||
mp_arg_validate_int_min(args[ARG_start].u_int, 0, MP_QSTR_start);
|
||||
size_t length =
|
||||
mp_arg_validate_int_min(args[ARG_length].u_int, 1, MP_QSTR_length);
|
||||
|
||||
|
||||
memorymap_addressrange_obj_t *self = m_new_obj(memorymap_addressrange_obj_t);
|
||||
self->base.type = &memorymap_addressrange_type;
|
||||
|
||||
common_hal_memorymap_addressrange_construct(self, (uint8_t *)start, length);
|
||||
|
||||
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 __bool__(self) -> bool: ...
|
||||
//| 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);
|
||||
STATIC mp_obj_t memorymap_addressrange_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||
memorymap_addressrange_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
uint16_t len = common_hal_memorymap_addressrange_get_length(self);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL:
|
||||
return mp_obj_new_bool(len != 0);
|
||||
|
@ -77,36 +94,42 @@ STATIC mp_obj_t coproc_memory_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
|||
}
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t coproc_memory_locals_dict_table[] = {
|
||||
STATIC const mp_rom_map_elem_t memorymap_addressrange_locals_dict_table[] = {
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(coproc_memory_locals_dict, coproc_memory_locals_dict_table);
|
||||
STATIC MP_DEFINE_CONST_DICT(memorymap_addressrange_locals_dict, memorymap_addressrange_locals_dict_table);
|
||||
|
||||
//| @overload
|
||||
//| def __getitem__(self, index: slice) -> bytearray: ...
|
||||
//| @overload
|
||||
//| def __getitem__(self, index: int) -> int:
|
||||
//| """Returns the value at the given index."""
|
||||
//| """Returns the value(s) at the given index.
|
||||
//|
|
||||
//| 1, 2, 4 and 8 byte aligned reads will be done in one transaction.
|
||||
//| All others may use multiple transactions."""
|
||||
//| ...
|
||||
//| @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."""
|
||||
//| """Set the value(s) at the given index.
|
||||
//|
|
||||
//| 1, 2, 4 and 8 byte aligned writes will be done in one transaction.
|
||||
//| All others may use multiple transactions."""
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t coproc_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
|
||||
STATIC mp_obj_t memorymap_addressrange_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);
|
||||
memorymap_addressrange_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)) {
|
||||
if (!mp_seq_get_fast_slice_indexes(common_hal_memorymap_addressrange_get_length(self), index_in, &slice)) {
|
||||
mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported"));
|
||||
}
|
||||
if (value != MP_OBJ_SENTINEL) {
|
||||
|
@ -132,8 +155,8 @@ STATIC mp_obj_t coproc_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj
|
|||
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"));
|
||||
if (!common_hal_memorymap_addressrange_set_bytes(self, slice.start, src_items, src_len)) {
|
||||
mp_raise_RuntimeError(translate("Unable to write to address."));
|
||||
}
|
||||
return mp_const_none;
|
||||
#else
|
||||
|
@ -143,18 +166,18 @@ STATIC mp_obj_t coproc_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj
|
|||
// 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);
|
||||
common_hal_memorymap_addressrange_get_bytes(self, slice.start, len, items);
|
||||
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),
|
||||
size_t index = mp_get_index(self->base.type, common_hal_memorymap_addressrange_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);
|
||||
common_hal_memorymap_addressrange_get_bytes(self, index, 1, &value_out);
|
||||
return MP_OBJ_NEW_SMALL_INT(value_out);
|
||||
} else {
|
||||
// store
|
||||
|
@ -162,8 +185,8 @@ STATIC mp_obj_t coproc_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj
|
|||
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"));
|
||||
if (!common_hal_memorymap_addressrange_set_bytes(self, index, &short_value, 1)) {
|
||||
mp_raise_RuntimeError(translate("Unable to write to address."));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
@ -171,14 +194,14 @@ STATIC mp_obj_t coproc_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj
|
|||
}
|
||||
}
|
||||
|
||||
const mp_obj_type_t coproc_memory_type = {
|
||||
const mp_obj_type_t memorymap_addressrange_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,
|
||||
.name = MP_QSTR_AddressRange,
|
||||
.make_new = memorymap_addressrange_make_new,
|
||||
.locals_dict = (mp_obj_t)&memorymap_addressrange_locals_dict,
|
||||
MP_TYPE_EXTENDED_FIELDS(
|
||||
.subscr = coproc_memory_subscr,
|
||||
.unary_op = coproc_memory_unary_op,
|
||||
.subscr = memorymap_addressrange_subscr,
|
||||
.unary_op = memorymap_addressrange_unary_op,
|
||||
),
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 microDev
|
||||
* Copyright (c) 2017 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
|
||||
|
@ -24,29 +24,23 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "shared-bindings/coproc/CoprocMemory.h"
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMAP_ADDRESSRANGE_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMAP_ADDRESSRANGE_H
|
||||
|
||||
uint32_t common_hal_coproc_memory_get_length(coproc_memory_obj_t *self) {
|
||||
return self->len;
|
||||
}
|
||||
#include "common-hal/memorymap/AddressRange.h"
|
||||
|
||||
bool common_hal_coproc_memory_set_bytes(coproc_memory_obj_t *self,
|
||||
uint32_t start_index, const uint8_t *values, uint32_t len) {
|
||||
extern const mp_obj_type_t memorymap_addressrange_type;
|
||||
|
||||
if (start_index + len > self->len) {
|
||||
return false;
|
||||
}
|
||||
void common_hal_memorymap_addressrange_construct(memorymap_addressrange_obj_t *self, uint8_t *start_address, size_t length);
|
||||
|
||||
memcpy((uint8_t *)(self->address + start_index), values, len);
|
||||
return true;
|
||||
}
|
||||
uint32_t common_hal_memorymap_addressrange_get_length(const memorymap_addressrange_obj_t *self);
|
||||
|
||||
void common_hal_coproc_memory_get_bytes(coproc_memory_obj_t *self,
|
||||
uint32_t start_index, uint8_t *values, uint32_t len) {
|
||||
bool common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_obj_t *self,
|
||||
uint32_t start_index, uint8_t *values, uint32_t len);
|
||||
|
||||
if (start_index + len > self->len) {
|
||||
return;
|
||||
}
|
||||
// len and values are intentionally swapped to signify values is an output and
|
||||
// also leverage the compiler to validate uses are expected.
|
||||
void common_hal_memorymap_addressrange_get_bytes(const memorymap_addressrange_obj_t *self,
|
||||
uint32_t start_index, uint32_t len, uint8_t *values);
|
||||
|
||||
memcpy(values, (uint8_t *)(self->address + start_index), len);
|
||||
}
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_MEMORYMAP_ADDRESSRANGE_H
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 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 "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/memorymap/__init__.h"
|
||||
#include "shared-bindings/memorymap/AddressRange.h"
|
||||
|
||||
//| """Raw memory map access
|
||||
//|
|
||||
//| The `memorymap` module allows you to read and write memory addresses in the
|
||||
//| address space seen from the processor running CircuitPython. It is usually
|
||||
//| the physical address space.
|
||||
//| """
|
||||
STATIC const mp_rom_map_elem_t memorymap_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_memorymap) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_AddressRange), MP_ROM_PTR(&memorymap_addressrange_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(memorymap_module_globals, memorymap_module_globals_table);
|
||||
|
||||
const mp_obj_module_t memorymap_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&memorymap_module_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_memorymap, memorymap_module, CIRCUITPY_MEMORYMAP);
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 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 SHARED_BINDINGS_MEMORYMAP_H
|
||||
#define SHARED_BINDINGS_MEMORYMAP_H
|
||||
|
||||
#endif // SHARED_BINDINGS_MEMORYMAP_H
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "py/mphal.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/shared/reload.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
|
@ -52,6 +53,7 @@ void reload_initiate(supervisor_run_reason_t run_reason) {
|
|||
MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
|
||||
}
|
||||
#endif
|
||||
port_wake_main_task();
|
||||
}
|
||||
|
||||
void autoreload_reset() {
|
||||
|
|
|
@ -246,6 +246,15 @@ void supervisor_web_workflow_status(void) {
|
|||
void supervisor_start_web_workflow(void) {
|
||||
#if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_OS_GETENV
|
||||
|
||||
// Skip starting the workflow if we're not starting from power on or reset.
|
||||
const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason();
|
||||
if (reset_reason != RESET_REASON_POWER_ON &&
|
||||
reset_reason != RESET_REASON_RESET_PIN &&
|
||||
reset_reason != RESET_REASON_UNKNOWN &&
|
||||
reset_reason != RESET_REASON_SOFTWARE) {
|
||||
return;
|
||||
}
|
||||
|
||||
char ssid[33];
|
||||
char password[64];
|
||||
|
||||
|
|
Loading…
Reference in New Issue