esp32: Add support for the esp32's ULP.
The ULP is available as esp32.ULP(). See README.ulp.md for basic usage.
This commit is contained in:
parent
d43c737756
commit
298c072433
|
@ -83,6 +83,7 @@ INC_ESPCOMP += -I$(ESPCOMP)/lwip/include/lwip/posix
|
||||||
INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/include
|
INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/include
|
||||||
INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/port/include
|
INC_ESPCOMP += -I$(ESPCOMP)/mbedtls/port/include
|
||||||
INC_ESPCOMP += -I$(ESPCOMP)/spi_flash/include
|
INC_ESPCOMP += -I$(ESPCOMP)/spi_flash/include
|
||||||
|
INC_ESPCOMP += -I$(ESPCOMP)/ulp/include
|
||||||
INC_ESPCOMP += -I$(ESPCOMP)/vfs/include
|
INC_ESPCOMP += -I$(ESPCOMP)/vfs/include
|
||||||
INC_ESPCOMP += -I$(ESPCOMP)/newlib/platform_include
|
INC_ESPCOMP += -I$(ESPCOMP)/newlib/platform_include
|
||||||
INC_ESPCOMP += -I$(ESPCOMP)/xtensa-debug-module/include
|
INC_ESPCOMP += -I$(ESPCOMP)/xtensa-debug-module/include
|
||||||
|
@ -148,6 +149,7 @@ SRC_C = \
|
||||||
network_lan.c \
|
network_lan.c \
|
||||||
modsocket.c \
|
modsocket.c \
|
||||||
modesp.c \
|
modesp.c \
|
||||||
|
esp32_ulp.c \
|
||||||
modesp32.c \
|
modesp32.c \
|
||||||
moduhashlib.c \
|
moduhashlib.c \
|
||||||
espneopixel.c \
|
espneopixel.c \
|
||||||
|
@ -417,6 +419,10 @@ ESPIDF_SPI_FLASH_O = $(addprefix $(ESPCOMP)/spi_flash/,\
|
||||||
flash_ops.o \
|
flash_ops.o \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
ESPIDF_ULP_O = $(addprefix $(ESPCOMP)/ulp/,\
|
||||||
|
ulp.o \
|
||||||
|
)
|
||||||
|
|
||||||
$(BUILD)/$(ESPCOMP)/lwip/%.o: CFLAGS += -Wno-address -Wno-unused-variable -Wno-unused-but-set-variable
|
$(BUILD)/$(ESPCOMP)/lwip/%.o: CFLAGS += -Wno-address -Wno-unused-variable -Wno-unused-but-set-variable
|
||||||
ESPIDF_LWIP_O = $(addprefix $(ESPCOMP)/lwip/,\
|
ESPIDF_LWIP_O = $(addprefix $(ESPCOMP)/lwip/,\
|
||||||
api/pppapi.o \
|
api/pppapi.o \
|
||||||
|
@ -605,6 +611,7 @@ OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_NGHTTP_O))
|
||||||
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_NVS_FLASH_O))
|
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_NVS_FLASH_O))
|
||||||
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_OPENSSL_O))
|
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_OPENSSL_O))
|
||||||
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_SPI_FLASH_O))
|
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_SPI_FLASH_O))
|
||||||
|
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_ULP_O))
|
||||||
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_WPA_SUPPLICANT_O))
|
OBJ_ESPIDF += $(addprefix $(BUILD)/, $(ESPIDF_WPA_SUPPLICANT_O))
|
||||||
################################################################################
|
################################################################################
|
||||||
# Main targets
|
# Main targets
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
# ULP
|
||||||
|
|
||||||
|
To compile binarys for the ulp you need the ulp toolkit. Download it from https://github.com/espressif/binutils-esp32ulp/wiki#downloads
|
||||||
|
Then extract it, then add ```esp32ulp-elf-binutils/bin``` to your PATH
|
||||||
|
|
||||||
|
## Example Makefile
|
||||||
|
|
||||||
|
```make
|
||||||
|
ULP_S_SOURCES := main.S
|
||||||
|
ULP_APP_NAME := test
|
||||||
|
ULP_LD_SCRIPT := esp32.ulp.ld
|
||||||
|
|
||||||
|
SRC_PATH := src
|
||||||
|
BUILD_PATH := build
|
||||||
|
|
||||||
|
include $(ESPIDF)/components/ulp/Makefile.projbuild
|
||||||
|
|
||||||
|
ULP_ELF := $(ULP_APP_NAME).elf
|
||||||
|
ULP_MAP := $(ULP_ELF:.elf=.map)
|
||||||
|
ULP_SYM := $(ULP_ELF:.elf=.sym)
|
||||||
|
ULP_BIN := $(ULP_ELF:.elf=.bin)
|
||||||
|
ULP_EXPORTS_LD := $(ULP_ELF:.elf=.ld)
|
||||||
|
ULP_EXPORTS_HEADER := $(ULP_ELF:.elf=.h)
|
||||||
|
|
||||||
|
ULP_OBJECTS := $(notdir $(ULP_S_SOURCES:.S=.ulp.o))
|
||||||
|
ULP_DEP := $(notdir $(ULP_S_SOURCES:.S=.ulp.d)) $(ULP_LD_SCRIPT:.ld=.d)
|
||||||
|
ULP_PREPROCESSED := $(notdir $(ULP_S_SOURCES:.S=.ulp.pS))
|
||||||
|
ULP_LISTINGS := $(notdir $(ULP_S_SOURCES:.S=.ulp.lst))
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
|
|
||||||
|
all: $(BUILD_PATH) $(BUILD_PATH)/$(ULP_BIN)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_PATH)
|
||||||
|
|
||||||
|
$(BUILD_PATH):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
# Generate preprocessed linker file.
|
||||||
|
$(BUILD_PATH)/$(ULP_APP_NAME).ld: $(SRC_PATH)/$(ULP_LD_SCRIPT)
|
||||||
|
cpp -P $< -o $@
|
||||||
|
|
||||||
|
# Generate preprocessed assembly files.
|
||||||
|
# To inspect these preprocessed files, add a ".PRECIOUS: %.ulp.pS" rule.
|
||||||
|
$(BUILD_PATH)/%.ulp.pS: $(SRC_PATH)/%.S
|
||||||
|
cpp $< -o $@
|
||||||
|
|
||||||
|
# Compiled preprocessed files into object files.
|
||||||
|
$(BUILD_PATH)/%.ulp.o: $(BUILD_PATH)/%.ulp.pS
|
||||||
|
$(ULP_AS) -al=$(patsubst %.ulp.o,%.ulp.lst,$@) -o $@ $<
|
||||||
|
|
||||||
|
# Link object files and generate map file
|
||||||
|
$(BUILD_PATH)/$(ULP_ELF): $(BUILD_PATH)/$(ULP_OBJECTS) $(BUILD_PATH)/$(ULP_APP_NAME).ld
|
||||||
|
$(ULP_LD) -o $@ -A elf32-esp32ulp -Map=$(BUILD_PATH)/$(ULP_MAP) -T $(BUILD_PATH)/$(ULP_APP_NAME).ld $<
|
||||||
|
|
||||||
|
# Dump the list of global symbols in a convenient format.
|
||||||
|
$(ULP_SYM): $(ULP_ELF)
|
||||||
|
$(ULP_NM) -g -f posix $< > $@
|
||||||
|
|
||||||
|
# Dump the binary for inclusion into the project
|
||||||
|
$(BUILD_PATH)/$(ULP_BIN): $(BUILD_PATH)/$(ULP_ELF)
|
||||||
|
$(ULP_OBJCOPY) -O binary $< $@
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example linker script for the ulp
|
||||||
|
```
|
||||||
|
#define ULP_BIN_MAGIC 0x00706c75
|
||||||
|
#define HEADER_SIZE 12
|
||||||
|
#define CONFIG_ULP_COPROC_RESERVE_MEM 4096
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ram(RW) : ORIGIN = 0, LENGTH = CONFIG_ULP_COPROC_RESERVE_MEM
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text : AT(HEADER_SIZE)
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
} >ram
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.data)
|
||||||
|
} >ram
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.bss)
|
||||||
|
} >ram
|
||||||
|
|
||||||
|
.header : AT(0)
|
||||||
|
{
|
||||||
|
LONG(ULP_BIN_MAGIC)
|
||||||
|
SHORT(LOADADDR(.text))
|
||||||
|
SHORT(SIZEOF(.text))
|
||||||
|
SHORT(SIZEOF(.data))
|
||||||
|
SHORT(SIZEOF(.bss))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example ulp code
|
||||||
|
```asm
|
||||||
|
move R3, 99
|
||||||
|
move R0, 10
|
||||||
|
|
||||||
|
# mem[R0+0] = R3
|
||||||
|
st R3, R0, 0
|
||||||
|
|
||||||
|
HALT
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example python code using the ulp
|
||||||
|
```python
|
||||||
|
import esp32
|
||||||
|
import time
|
||||||
|
|
||||||
|
u = esp32.ULP()
|
||||||
|
with open('test.bin', 'rb') as f:
|
||||||
|
b = f.read()
|
||||||
|
u.load_binary(0,b)
|
||||||
|
u.run(0)
|
||||||
|
```
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 "Andreas Valder" <andreas.valder@serioese.gmbh>
|
||||||
|
*
|
||||||
|
* 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"
|
||||||
|
|
||||||
|
#include "esp32/ulp.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
typedef struct _esp32_ulp_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
|
} esp32_ulp_obj_t;
|
||||||
|
|
||||||
|
const mp_obj_type_t esp32_ulp_type;
|
||||||
|
|
||||||
|
// singleton ULP object
|
||||||
|
STATIC const esp32_ulp_obj_t esp32_ulp_obj = {{&esp32_ulp_type}};
|
||||||
|
|
||||||
|
STATIC mp_obj_t esp32_ulp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
|
// check arguments
|
||||||
|
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||||
|
|
||||||
|
// return constant object
|
||||||
|
return (mp_obj_t)&esp32_ulp_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC mp_obj_t esp32_ulp_set_wakeup_period(mp_obj_t self_in, mp_obj_t period_index_in, mp_obj_t period_us_in) {
|
||||||
|
mp_uint_t period_index = mp_obj_get_int(period_index_in);
|
||||||
|
mp_uint_t period_us = mp_obj_get_int(period_us_in);
|
||||||
|
int _errno = ulp_set_wakeup_period(period_index, period_us);
|
||||||
|
if (_errno != ESP_OK) {
|
||||||
|
mp_raise_OSError(_errno);
|
||||||
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp32_ulp_set_wakeup_period_obj, esp32_ulp_set_wakeup_period);
|
||||||
|
|
||||||
|
STATIC mp_obj_t esp32_ulp_load_binary(mp_obj_t self_in, mp_obj_t load_addr_in, mp_obj_t program_binary_in) {
|
||||||
|
mp_uint_t load_addr = mp_obj_get_int(load_addr_in);
|
||||||
|
|
||||||
|
mp_buffer_info_t bufinfo;
|
||||||
|
mp_get_buffer_raise(program_binary_in, &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
||||||
|
int _errno = ulp_load_binary(load_addr, bufinfo.buf, bufinfo.len/sizeof(uint32_t));
|
||||||
|
if (_errno != ESP_OK) {
|
||||||
|
mp_raise_OSError(_errno);
|
||||||
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp32_ulp_load_binary_obj, esp32_ulp_load_binary);
|
||||||
|
|
||||||
|
STATIC mp_obj_t esp32_ulp_run(mp_obj_t self_in, mp_obj_t entry_point_in) {
|
||||||
|
mp_uint_t entry_point = mp_obj_get_int(entry_point_in);
|
||||||
|
int _errno = ulp_run(entry_point/sizeof(uint32_t));
|
||||||
|
if (_errno != ESP_OK) {
|
||||||
|
mp_raise_OSError(_errno);
|
||||||
|
}
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_ulp_run_obj, esp32_ulp_run);
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t esp32_ulp_locals_dict_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_set_wakeup_period), MP_ROM_PTR(&esp32_ulp_set_wakeup_period_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_load_binary), MP_ROM_PTR(&esp32_ulp_load_binary_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&esp32_ulp_run_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_RESERVE_MEM), MP_ROM_INT(CONFIG_ULP_COPROC_RESERVE_MEM) },
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(esp32_ulp_locals_dict, esp32_ulp_locals_dict_table);
|
||||||
|
|
||||||
|
const mp_obj_type_t esp32_ulp_type = {
|
||||||
|
{ &mp_type_type },
|
||||||
|
.name = MP_QSTR_ULP,
|
||||||
|
.make_new = esp32_ulp_make_new,
|
||||||
|
.locals_dict = (mp_obj_t)&esp32_ulp_locals_dict,
|
||||||
|
};
|
|
@ -126,6 +126,9 @@ STATIC const mp_rom_map_elem_t esp32_module_globals_table[] = {
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_touch), (mp_obj_t)&esp32_wake_on_touch_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_touch), (mp_obj_t)&esp32_wake_on_touch_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext0), (mp_obj_t)&esp32_wake_on_ext0_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext0), (mp_obj_t)&esp32_wake_on_ext0_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext1), (mp_obj_t)&esp32_wake_on_ext1_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_on_ext1), (mp_obj_t)&esp32_wake_on_ext1_obj },
|
||||||
|
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_ULP), MP_ROM_PTR(&esp32_ulp_type) },
|
||||||
|
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ALL_LOW), mp_const_false },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ALL_LOW), mp_const_false },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ANY_HIGH), mp_const_true },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_WAKEUP_ANY_HIGH), mp_const_true },
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,4 +26,6 @@
|
||||||
#define RTC_LAST_EXT_PIN 39
|
#define RTC_LAST_EXT_PIN 39
|
||||||
#define RTC_IS_VALID_EXT_PIN(pin_id) ((1ll << (pin_id)) & RTC_VALID_EXT_PINS)
|
#define RTC_IS_VALID_EXT_PIN(pin_id) ((1ll << (pin_id)) & RTC_VALID_EXT_PINS)
|
||||||
|
|
||||||
|
extern const mp_obj_type_t esp32_ulp_type;
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_ESP32_MODESP32_H
|
#endif // MICROPY_INCLUDED_ESP32_MODESP32_H
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0
|
#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0
|
||||||
#define CONFIG_BT_RESERVE_DRAM 0x0
|
#define CONFIG_BT_RESERVE_DRAM 0x0
|
||||||
#define CONFIG_ULP_COPROC_RESERVE_MEM 0
|
#define CONFIG_ULP_COPROC_RESERVE_MEM 2040
|
||||||
#define CONFIG_PHY_DATA_OFFSET 0xf000
|
#define CONFIG_PHY_DATA_OFFSET 0xf000
|
||||||
#define CONFIG_APP_OFFSET 0x10000
|
#define CONFIG_APP_OFFSET 0x10000
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue