diff options
Diffstat (limited to 'esp8266')
-rw-r--r-- | esp8266/Makefile | 16 | ||||
-rw-r--r-- | esp8266/esp8266.ld | 2 | ||||
-rw-r--r-- | esp8266/esp8266_512k.ld | 2 | ||||
-rw-r--r-- | esp8266/esp8266_ota.ld | 306 | ||||
-rw-r--r-- | esp8266/esp_mphal.h | 2 | ||||
-rw-r--r-- | esp8266/gccollect.c | 5 | ||||
-rw-r--r-- | esp8266/gccollect.h | 1 | ||||
-rw-r--r-- | esp8266/lexerstr32.c | 11 | ||||
-rw-r--r-- | esp8266/machine_adc.c | 2 | ||||
-rw-r--r-- | esp8266/machine_hspi.c | 79 | ||||
-rw-r--r-- | esp8266/machine_pin.c | 4 | ||||
-rw-r--r-- | esp8266/machine_rtc.c | 2 | ||||
-rw-r--r-- | esp8266/machine_spi.c | 142 | ||||
-rw-r--r-- | esp8266/machine_uart.c | 1 | ||||
-rw-r--r-- | esp8266/machine_wdt.c | 2 | ||||
-rw-r--r-- | esp8266/main.c | 16 | ||||
-rw-r--r-- | esp8266/modesp.c | 136 | ||||
-rw-r--r-- | esp8266/modmachine.c | 4 | ||||
-rw-r--r-- | esp8266/modmachine.h | 4 | ||||
-rw-r--r-- | esp8266/modules/flashbdev.py | 39 | ||||
-rw-r--r-- | esp8266/modules/websocket_helper.py (renamed from esp8266/scripts/websocket_helper.py) | 0 | ||||
-rw-r--r-- | esp8266/mpconfigport.h | 14 | ||||
-rw-r--r-- | esp8266/mpconfigport_512k.h | 8 | ||||
-rw-r--r-- | esp8266/scripts/inisetup.py | 11 |
24 files changed, 533 insertions, 276 deletions
diff --git a/esp8266/Makefile b/esp8266/Makefile index b2191353a2..1d50a0fb31 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -14,6 +14,7 @@ FROZEN_MPY_DIR = modules # include py core make definitions include ../py/py.mk +FWBIN = $(BUILD)/firmware-combined.bin PORT ?= /dev/ttyACM0 BAUD ?= 115200 FLASH_MODE ?= qio @@ -82,7 +83,6 @@ SRC_C = \ machine_adc.c \ machine_uart.c \ machine_wdt.c \ - machine_spi.c \ machine_hspi.c \ modesp.c \ modnetwork.c \ @@ -160,7 +160,7 @@ SRC_QSTR += $(SRC_C) $(STM_SRC_C) $(EXTMOD_SRC_C) $(DRIVERS_SRC_C) # Append any auto-generated sources that are needed by sources listed in SRC_QSTR SRC_QSTR_AUTO_DEPS += -all: $(BUILD)/libaxtls.a $(BUILD)/firmware-combined.bin +all: $(BUILD)/libaxtls.a $(FWBIN) CONFVARS_FILE = $(BUILD)/confvars @@ -181,13 +181,17 @@ deploy: $(BUILD)/firmware-combined.bin $(ECHO) "Writing $< to the board" $(Q)esptool.py --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=$(FLASH_SIZE) --flash_mode=$(FLASH_MODE) 0 $< +erase: + $(ECHO) "Erase flash" + $(Q)esptool.py --port $(PORT) --baud $(BAUD) erase_flash + reset: echo -e "\r\nimport machine; machine.reset()\r\n" >$(PORT) -$(BUILD)/firmware-combined.bin: $(BUILD)/firmware.elf +$(FWBIN): $(BUILD)/firmware.elf $(ECHO) "Create $@" $(Q)esptool.py elf2image $^ - $(Q)$(PYTHON) makeimg.py $(BUILD)/firmware.elf-0x00000.bin $(BUILD)/firmware.elf-0x0[1-f]000.bin $@ + $(Q)$(PYTHON) makeimg.py $(BUILD)/firmware.elf-0x00000.bin $(BUILD)/firmware.elf-0x[0-5][1-f]000.bin $@ $(BUILD)/firmware.elf: $(OBJ) $(ECHO) "LINK $@" @@ -197,6 +201,10 @@ $(BUILD)/firmware.elf: $(OBJ) 512k: $(MAKE) LDSCRIPT=esp8266_512k.ld CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_512k.h>"' MICROPY_FATFS=0 MICROPY_PY_BTREE=0 +ota: + rm -f $(BUILD)/firmware.elf $(BUILD)/firmware.elf*.bin + $(MAKE) LDSCRIPT=esp8266_ota.ld FWBIN=$(BUILD)/firmware-ota.bin + #MAKE_PINS = boards/make-pins.py #BOARD_PINS = boards/$(BOARD)/pins.csv #AF_FILE = boards/stm32f4xx_af.csv diff --git a/esp8266/esp8266.ld b/esp8266/esp8266.ld index 20b259dff2..a6a4b930bb 100644 --- a/esp8266/esp8266.ld +++ b/esp8266/esp8266.ld @@ -88,9 +88,11 @@ SECTIONS *py/builtin*.o*(.literal* .text*) *py/compile.o*(.literal* .text*) *py/emit*.o*(.literal* .text*) + *py/persistentcode*.o*(.literal* .text*) *py/formatfloat.o*(.literal* .text*) *py/frozenmod.o*(.literal* .text*) *py/gc.o*(.literal* .text*) + *py/reader*.o*(.literal* .text*) *py/lexer*.o*(.literal* .text*) *py/malloc*.o*(.literal* .text*) *py/map*.o*(.literal* .text*) diff --git a/esp8266/esp8266_512k.ld b/esp8266/esp8266_512k.ld index 781cbb985c..2bffcab80d 100644 --- a/esp8266/esp8266_512k.ld +++ b/esp8266/esp8266_512k.ld @@ -88,9 +88,11 @@ SECTIONS *py/builtin*.o*(.literal* .text*) *py/compile.o*(.literal* .text*) *py/emit*.o*(.literal* .text*) + *py/persistentcode*.o*(.literal* .text*) *py/formatfloat.o*(.literal* .text*) *py/frozenmod.o*(.literal* .text*) *py/gc.o*(.literal* .text*) + *py/reader*.o*(.literal* .text*) *py/lexer*.o*(.literal* .text*) *py/malloc*.o*(.literal* .text*) *py/map*.o*(.literal* .text*) diff --git a/esp8266/esp8266_ota.ld b/esp8266/esp8266_ota.ld new file mode 100644 index 0000000000..aceeb25a51 --- /dev/null +++ b/esp8266/esp8266_ota.ld @@ -0,0 +1,306 @@ +/* GNU linker script for ESP8266 */ + +MEMORY +{ + dport0_0_seg : org = 0x3ff00000, len = 0x10 + dram0_0_seg : org = 0x3ffe8000, len = 0x14000 + iram1_0_seg : org = 0x40100000, len = 0x8000 + /* 0x3c000 is size of bootloader, 0x9000 is size of packed RAM segments */ + irom0_0_seg : org = 0x40200000 + 0x3c000 + 0x9000, len = 0x87000 +} + +/* define the top of RAM */ +_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg); + +PHDRS +{ + dport0_0_phdr PT_LOAD; + dram0_0_phdr PT_LOAD; + dram0_0_bss_phdr PT_LOAD; + iram1_0_phdr PT_LOAD; + irom0_0_phdr PT_LOAD; +} + +ENTRY(firmware_start) +EXTERN(_DebugExceptionVector) +EXTERN(_DoubleExceptionVector) +EXTERN(_KernelExceptionVector) +EXTERN(_NMIExceptionVector) +EXTERN(_UserExceptionVector) + +PROVIDE(_memmap_vecbase_reset = 0x40000000); + +/* Various memory-map dependent cache attribute settings: */ +_memmap_cacheattr_wb_base = 0x00000110; +_memmap_cacheattr_wt_base = 0x00000110; +_memmap_cacheattr_bp_base = 0x00000220; +_memmap_cacheattr_unused_mask = 0xFFFFF00F; +_memmap_cacheattr_wb_trapnull = 0x2222211F; +_memmap_cacheattr_wba_trapnull = 0x2222211F; +_memmap_cacheattr_wbna_trapnull = 0x2222211F; +_memmap_cacheattr_wt_trapnull = 0x2222211F; +_memmap_cacheattr_bp_trapnull = 0x2222222F; +_memmap_cacheattr_wb_strict = 0xFFFFF11F; +_memmap_cacheattr_wt_strict = 0xFFFFF11F; +_memmap_cacheattr_bp_strict = 0xFFFFF22F; +_memmap_cacheattr_wb_allvalid = 0x22222112; +_memmap_cacheattr_wt_allvalid = 0x22222112; +_memmap_cacheattr_bp_allvalid = 0x22222222; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); + +SECTIONS +{ + + .dport0.rodata : ALIGN(4) + { + _dport0_rodata_start = ABSOLUTE(.); + *(.dport0.rodata) + *(.dport.rodata) + _dport0_rodata_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .dport0.literal : ALIGN(4) + { + _dport0_literal_start = ABSOLUTE(.); + *(.dport0.literal) + *(.dport.literal) + _dport0_literal_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .dport0.data : ALIGN(4) + { + _dport0_data_start = ABSOLUTE(.); + *(.dport0.data) + *(.dport.data) + _dport0_data_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .irom0.text : ALIGN(4) + { + _irom0_text_start = ABSOLUTE(.); + *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) + + /* we put some specific text in this section */ + + *py/argcheck.o*(.literal* .text*) + *py/asm*.o*(.literal* .text*) + *py/bc.o*(.literal* .text*) + *py/binary.o*(.literal* .text*) + *py/builtin*.o*(.literal* .text*) + *py/compile.o*(.literal* .text*) + *py/emit*.o*(.literal* .text*) + *py/persistentcode*.o*(.literal* .text*) + *py/formatfloat.o*(.literal* .text*) + *py/frozenmod.o*(.literal* .text*) + *py/gc.o*(.literal* .text*) + *py/reader*.o*(.literal* .text*) + *py/lexer*.o*(.literal* .text*) + *py/malloc*.o*(.literal* .text*) + *py/map*.o*(.literal* .text*) + *py/mod*.o*(.literal* .text*) + *py/mpprint.o*(.literal* .text*) + *py/mpstate.o*(.literal* .text*) + *py/mpz.o*(.literal* .text*) + *py/native*.o*(.literal* .text*) + *py/nlr*.o*(.literal* .text*) + *py/obj*.o*(.literal* .text*) + *py/opmethods.o*(.literal* .text*) + *py/parse*.o*(.literal* .text*) + *py/qstr.o*(.literal* .text*) + *py/repl.o*(.literal* .text*) + *py/runtime.o*(.literal* .text*) + *py/scope.o*(.literal* .text*) + *py/sequence.o*(.literal* .text*) + *py/showbc.o*(.literal* .text*) + *py/smallint.o*(.literal* .text*) + *py/stackctrl.o*(.literal* .text*) + *py/stream.o*(.literal* .text*) + *py/unicode.o*(.literal* .text*) + *py/vm.o*(.literal* .text*) + *py/vstr.o*(.literal* .text*) + *py/warning.o*(.literal* .text*) + + *extmod/*.o*(.literal* .text*) + + *lib/fatfs/*.o*(.literal*, .text*) + */libaxtls.a:(.literal*, .text*) + *lib/berkeley-db-1.xx/*.o(.literal*, .text*) + *lib/libm/*.o*(.literal*, .text*) + *lib/mp-readline/*.o(.literal*, .text*) + *lib/netutils/*.o*(.literal*, .text*) + *lib/timeutils/*.o*(.literal*, .text*) + *lib/utils/*.o*(.literal*, .text*) + + *stmhal/pybstdio.o(.literal*, .text*) + + build/main.o(.literal* .text*) + *gccollect.o(.literal* .text*) + *gchelper.o(.literal* .text*) + *help.o(.literal* .text*) + *lexerstr32.o(.literal* .text*) + *utils.o(.literal* .text*) + *modpyb.o(.literal*, .text*) + *machine_pin.o(.literal*, .text*) + *machine_pwm.o(.literal*, .text*) + *machine_rtc.o(.literal*, .text*) + *machine_adc.o(.literal*, .text*) + *machine_uart.o(.literal*, .text*) + *modpybi2c.o(.literal*, .text*) + *modmachine.o(.literal*, .text*) + *machine_wdt.o(.literal*, .text*) + *machine_spi.o(.literal*, .text*) + *machine_hspi.o(.literal*, .text*) + *hspi.o(.literal*, .text*) + *modesp.o(.literal* .text*) + *modnetwork.o(.literal* .text*) + *moduos.o(.literal* .text*) + *modutime.o(.literal* .text*) + *modlwip.o(.literal* .text*) + *modsocket.o(.literal* .text*) + *modonewire.o(.literal* .text*) + + /* we put as much rodata as possible in this section */ + /* note that only rodata accessed as a machine word is allowed here */ + *py/qstr.o(.rodata.const_pool) + *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */ + *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */ + *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */ + */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */ + */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ + + /* for -mforce-l32 */ + build/*.o(.rodata*) + + _irom0_text_end = ABSOLUTE(.); + } >irom0_0_seg :irom0_0_phdr + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.UserEnter.text) + . = ALIGN(16); + *(.DebugExceptionVector.text) + . = ALIGN(16); + *(.NMIExceptionVector.text) + . = ALIGN(16); + *(.KernelExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN(16); + *(.UserExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN(16); + *(.DoubleExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >iram1_0_seg :iram1_0_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >iram1_0_seg :iram1_0_phdr + + .data : ALIGN(4) + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + } >dram0_0_seg :dram0_0_phdr + + .rodata : ALIGN(4) + { + _rodata_start = ABSOLUTE(.); + *(.sdk.version) + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + /* C++ constructor and destructor tables, properly ordered: */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); /* this table MUST be 4-byte aligned */ + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + } >dram0_0_seg :dram0_0_phdr + + .bss ALIGN(8) (NOLOAD) : ALIGN(4) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + _heap_start = ABSOLUTE(.); + } >dram0_0_seg :dram0_0_bss_phdr +} + +/* get ROM code address */ +INCLUDE "eagle.rom.addr.v6.ld" diff --git a/esp8266/esp_mphal.h b/esp8266/esp_mphal.h index 1622667f93..d783f1f09a 100644 --- a/esp8266/esp_mphal.h +++ b/esp8266/esp_mphal.h @@ -76,8 +76,10 @@ void ets_event_poll(void); #include "etshal.h" #include "gpio.h" #include "esp8266/modmachine.h" +#define MP_HAL_PIN_FMT "%u" #define mp_hal_pin_obj_t uint32_t #define mp_hal_get_pin_obj(o) mp_obj_get_pin(o) +#define mp_hal_pin_name(p) (p) void mp_hal_pin_input(mp_hal_pin_obj_t pin); void mp_hal_pin_output(mp_hal_pin_obj_t pin); void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin); diff --git a/esp8266/gccollect.c b/esp8266/gccollect.c index 3a5032bc93..1b9349f574 100644 --- a/esp8266/gccollect.c +++ b/esp8266/gccollect.c @@ -46,6 +46,11 @@ void gc_collect(void) { // trace the stack, including the registers (since they live on the stack in this function) gc_collect_root((void**)sp, (STACK_END - sp) / sizeof(uint32_t)); + #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA + // trace any native code because it can contain pointers to the heap + esp_native_code_gc_collect(); + #endif + // end the GC gc_collect_end(); } diff --git a/esp8266/gccollect.h b/esp8266/gccollect.h index e360ef2f29..d81cba12c4 100644 --- a/esp8266/gccollect.h +++ b/esp8266/gccollect.h @@ -38,3 +38,4 @@ extern uint32_t _heap_start; extern uint32_t _heap_end; void gc_collect(void); +void esp_native_code_gc_collect(void); diff --git a/esp8266/lexerstr32.c b/esp8266/lexerstr32.c index 669df8ea7b..3fc62399e7 100644 --- a/esp8266/lexerstr32.c +++ b/esp8266/lexerstr32.c @@ -35,10 +35,11 @@ typedef struct _mp_lexer_str32_buf_t { uint8_t byte_off; } mp_lexer_str32_buf_t; -STATIC mp_uint_t str32_buf_next_byte(mp_lexer_str32_buf_t *sb) { +STATIC mp_uint_t str32_buf_next_byte(void *sb_in) { + mp_lexer_str32_buf_t *sb = (mp_lexer_str32_buf_t*)sb_in; byte c = sb->val & 0xff; if (c == 0) { - return MP_LEXER_EOF; + return MP_READER_EOF; } if (++sb->byte_off > 3) { @@ -51,7 +52,8 @@ STATIC mp_uint_t str32_buf_next_byte(mp_lexer_str32_buf_t *sb) { return c; } -STATIC void str32_buf_free(mp_lexer_str32_buf_t *sb) { +STATIC void str32_buf_free(void *sb_in) { + mp_lexer_str32_buf_t *sb = (mp_lexer_str32_buf_t*)sb_in; m_del_obj(mp_lexer_str32_buf_t, sb); } @@ -63,7 +65,8 @@ mp_lexer_t *mp_lexer_new_from_str32(qstr src_name, const char *str, mp_uint_t le sb->byte_off = (uint32_t)str & 3; sb->src_cur = (uint32_t*)(str - sb->byte_off); sb->val = *sb->src_cur++ >> sb->byte_off * 8; - return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_byte_t)str32_buf_next_byte, (mp_lexer_stream_close_t)str32_buf_free); + mp_reader_t reader = {sb, str32_buf_next_byte, str32_buf_free}; + return mp_lexer_new(src_name, reader); } #endif // MICROPY_ENABLE_COMPILER diff --git a/esp8266/machine_adc.c b/esp8266/machine_adc.c index 26b28c50b2..f1fb5be315 100644 --- a/esp8266/machine_adc.c +++ b/esp8266/machine_adc.c @@ -42,7 +42,7 @@ typedef struct _pyb_adc_obj_t { STATIC pyb_adc_obj_t pyb_adc_vdd3 = {{&pyb_adc_type}, true}; STATIC pyb_adc_obj_t pyb_adc_adc = {{&pyb_adc_type}, false}; -STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args, mp_uint_t n_kw, +STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); diff --git a/esp8266/machine_hspi.c b/esp8266/machine_hspi.c index 10a090269f..1be342b526 100644 --- a/esp8266/machine_hspi.c +++ b/esp8266/machine_hspi.c @@ -36,21 +36,17 @@ #include "py/stream.h" #include "py/mphal.h" #include "extmod/machine_spi.h" - +#include "modmachine.h" #include "hspi.h" -mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, - size_t n_kw, const mp_obj_t *args); - -typedef struct _pyb_hspi_obj_t { +typedef struct _machine_hspi_obj_t { mp_obj_base_t base; uint32_t baudrate; uint8_t polarity; uint8_t phase; -} pyb_hspi_obj_t; +} machine_hspi_obj_t; - -STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { +STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) { (void)self_in; if (dest == NULL) { @@ -93,16 +89,17 @@ STATIC void hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src /******************************************************************************/ // MicroPython bindings for HSPI -STATIC void pyb_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - pyb_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); +STATIC void machine_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + machine_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_printf(print, "HSPI(id=1, baudrate=%u, polarity=%u, phase=%u)", self->baudrate, self->polarity, self->phase); } -STATIC void pyb_hspi_init_helper(pyb_hspi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase }; +STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + machine_hspi_obj_t *self = (machine_hspi_obj_t*)self_in; + + enum { ARG_baudrate, ARG_polarity, ARG_phase }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_id, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} }, @@ -150,63 +147,35 @@ STATIC void pyb_hspi_init_helper(pyb_hspi_obj_t *self, size_t n_args, const mp_o spi_mode(HSPI, self->phase, self->polarity); } -mp_obj_t pyb_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 1, true); - mp_int_t id = -1; - if (n_args > 0) { - id = mp_obj_get_int(args[0]); - } - - if (id == -1) { - // Multiplex to bitbanging SPI - if (n_args > 0) { - args++; - } - return pyb_spi_make_new(type, 0, n_kw, args); - } - - if (id != 1) { +mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // args[0] holds the id of the peripheral + if (args[0] != MP_OBJ_NEW_SMALL_INT(1)) { // FlashROM is on SPI0, so far we don't support its usage mp_raise_ValueError(""); } - pyb_hspi_obj_t *self = m_new_obj(pyb_hspi_obj_t); - self->base.type = &pyb_hspi_type; + machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t); + self->base.type = &machine_hspi_type; // set defaults self->baudrate = 80000000L; self->polarity = 0; self->phase = 0; mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - pyb_hspi_init_helper(self, n_args, args, &kw_args); + machine_hspi_init((mp_obj_base_t*)self, n_args - 1, args + 1, &kw_args); return MP_OBJ_FROM_PTR(self); } -STATIC mp_obj_t pyb_hspi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - pyb_hspi_init_helper(args[0], n_args - 1, args + 1, kw_args); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(pyb_hspi_init_obj, 1, pyb_hspi_init); - -STATIC const mp_rom_map_elem_t pyb_hspi_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_hspi_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(pyb_hspi_locals_dict, pyb_hspi_locals_dict_table); - -STATIC const mp_machine_spi_p_t pyb_hspi_p = { - .transfer = hspi_transfer, +STATIC const mp_machine_spi_p_t machine_hspi_p = { + .init = machine_hspi_init, + .transfer = machine_hspi_transfer, }; -const mp_obj_type_t pyb_hspi_type = { +const mp_obj_type_t machine_hspi_type = { { &mp_type_type }, .name = MP_QSTR_HSPI, - .print = pyb_hspi_print, - .make_new = pyb_hspi_make_new, - .protocol = &pyb_hspi_p, - .locals_dict = (mp_obj_dict_t*)&pyb_hspi_locals_dict, + .print = machine_hspi_print, + .make_new = mp_machine_spi_make_new, // delegate to master constructor + .protocol = &machine_hspi_p, + .locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict, }; diff --git a/esp8266/machine_pin.c b/esp8266/machine_pin.c index 205c58aaee..e10b2cfb79 100644 --- a/esp8266/machine_pin.c +++ b/esp8266/machine_pin.c @@ -276,7 +276,7 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, mp_uint_t n_args, c } // constructor(id, ...) -STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); // get the wanted pin object @@ -300,7 +300,7 @@ STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp } // fast method for getting/setting pin value -STATIC mp_obj_t pyb_pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t pyb_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); pyb_pin_obj_t *self = self_in; if (n_args == 0) { diff --git a/esp8266/machine_rtc.c b/esp8266/machine_rtc.c index 54eeea6f6e..8c1fe0779c 100644 --- a/esp8266/machine_rtc.c +++ b/esp8266/machine_rtc.c @@ -78,7 +78,7 @@ void mp_hal_rtc_init(void) { pyb_rtc_alarm0_expiry = 0; } -STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t pyb_rtc_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); diff --git a/esp8266/machine_spi.c b/esp8266/machine_spi.c deleted file mode 100644 index e974547111..0000000000 --- a/esp8266/machine_spi.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * 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 <stdio.h> -#include <stdint.h> -#include <string.h> - -#include "py/runtime.h" -#include "py/stream.h" -#include "py/mphal.h" -#include "extmod/machine_spi.h" - -/******************************************************************************/ -// MicroPython bindings for SPI - -STATIC uint32_t baudrate_from_delay_half(uint32_t delay_half) { - return 500000 / delay_half; -} - -STATIC uint32_t baudrate_to_delay_half(uint32_t baudrate) { - uint32_t delay_half = 500000 / baudrate; - // round delay_half up so that: actual_baudrate <= requested_baudrate - if (500000 % baudrate != 0) { - delay_half += 1; - } - return delay_half; -} - -STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - mp_machine_soft_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "SPI(baudrate=%u, polarity=%u, phase=%u, sck=%u, mosi=%u, miso=%u)", - baudrate_from_delay_half(self->delay_half), - self->polarity, self->phase, self->sck, self->mosi, self->miso); -} - -STATIC void pyb_spi_init_helper(mp_machine_soft_spi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_sck, ARG_mosi, ARG_miso }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - if (args[ARG_baudrate].u_int != -1) { - self->delay_half = baudrate_to_delay_half(args[ARG_baudrate].u_int); - } - if (args[ARG_polarity].u_int != -1) { - self->polarity = args[ARG_polarity].u_int; - } - if (args[ARG_phase].u_int != -1) { - self->phase = args[ARG_phase].u_int; - } - if (args[ARG_sck].u_obj != MP_OBJ_NULL) { - self->sck = mp_hal_get_pin_obj(args[ARG_sck].u_obj); - } - if (args[ARG_mosi].u_obj != MP_OBJ_NULL) { - self->mosi = mp_hal_get_pin_obj(args[ARG_mosi].u_obj); - } - if (args[ARG_miso].u_obj != MP_OBJ_NULL) { - self->miso = mp_hal_get_pin_obj(args[ARG_miso].u_obj); - } - - // configure pins - mp_hal_pin_write(self->sck, self->polarity); - mp_hal_pin_output(self->sck); - mp_hal_pin_output(self->mosi); - mp_hal_pin_input(self->miso); -} - -mp_obj_t pyb_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - mp_machine_soft_spi_obj_t *self = m_new_obj(mp_machine_soft_spi_obj_t); - self->base.type = &pyb_spi_type; - // set defaults - self->delay_half = baudrate_to_delay_half(500000); - self->polarity = 0; - self->phase = 0; - self->sck = 14; - self->mosi = 13; - self->miso = 12; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - pyb_spi_init_helper(self, n_args, args, &kw_args); - return MP_OBJ_FROM_PTR(self); -} - -STATIC mp_obj_t pyb_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - pyb_spi_init_helper(args[0], n_args - 1, args + 1, kw_args); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_init_obj, 1, pyb_spi_init); - -STATIC const mp_rom_map_elem_t pyb_spi_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_spi_init_obj) }, - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_machine_spi_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_machine_spi_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_machine_spi_write_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&mp_machine_spi_write_readinto_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table); - -STATIC const mp_machine_spi_p_t pyb_spi_p = { - .transfer = mp_machine_soft_spi_transfer, -}; - -const mp_obj_type_t pyb_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SoftSPI, - .print = pyb_spi_print, - .make_new = pyb_spi_make_new, - .protocol = &pyb_spi_p, - .locals_dict = (mp_obj_dict_t*)&pyb_spi_locals_dict, -}; diff --git a/esp8266/machine_uart.c b/esp8266/machine_uart.c index 80e10d1310..9bc6422cc7 100644 --- a/esp8266/machine_uart.c +++ b/esp8266/machine_uart.c @@ -197,7 +197,6 @@ STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_readall), MP_ROM_PTR(&mp_stream_readall_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, diff --git a/esp8266/machine_wdt.c b/esp8266/machine_wdt.c index 6dc4c0d18c..83b5e8f322 100644 --- a/esp8266/machine_wdt.c +++ b/esp8266/machine_wdt.c @@ -41,7 +41,7 @@ typedef struct _machine_wdt_obj_t { STATIC machine_wdt_obj_t wdt_default = {{&esp_wdt_type}}; -STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_int_t id = 0; diff --git a/esp8266/main.c b/esp8266/main.c index a2e747d211..da37706fcd 100644 --- a/esp8266/main.c +++ b/esp8266/main.c @@ -52,12 +52,12 @@ STATIC void mp_reset(void) { mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_)); mp_obj_list_init(mp_sys_argv, 0); - #if MICROPY_VFS_FAT - memset(MP_STATE_PORT(fs_user_mount), 0, sizeof(MP_STATE_PORT(fs_user_mount))); - #endif - MP_STATE_PORT(mp_kbd_exception) = mp_obj_new_exception(&mp_type_KeyboardInterrupt); MP_STATE_PORT(term_obj) = MP_OBJ_NULL; MP_STATE_PORT(dupterm_arr_obj) = MP_OBJ_NULL; + #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA + extern void esp_native_code_init(void); + esp_native_code_init(); + #endif pin_init0(); readline_init0(); dupterm_task_init(); @@ -109,17 +109,13 @@ void user_init(void) { system_init_done_cb(init_done); } -mp_lexer_t *fat_vfs_lexer_new_from_file(const char *filename); mp_import_stat_t fat_vfs_import_stat(const char *path); +#if !MICROPY_VFS_FAT mp_lexer_t *mp_lexer_new_from_file(const char *filename) { - #if MICROPY_VFS_FAT - return fat_vfs_lexer_new_from_file(filename); - #else - (void)filename; return NULL; - #endif } +#endif mp_import_stat_t mp_import_stat(const char *path) { #if MICROPY_VFS_FAT diff --git a/esp8266/modesp.c b/esp8266/modesp.c index 207422b67d..b7ce122b17 100644 --- a/esp8266/modesp.c +++ b/esp8266/modesp.c @@ -628,17 +628,35 @@ STATIC mp_obj_t esp_flash_size(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size); +// If there's just 1 loadable segment at the start of flash, +// we assume there's a yaota8266 bootloader. +#define IS_OTA_FIRMWARE() ((*(uint32_t*)0x40200000 & 0xff00) == 0x100) + STATIC mp_obj_t esp_flash_user_start(void) { - return MP_OBJ_NEW_SMALL_INT(0x90000); + if (IS_OTA_FIRMWARE()) { + return MP_OBJ_NEW_SMALL_INT(0x3c000 + 0x90000); + } else { + return MP_OBJ_NEW_SMALL_INT(0x90000); + } } STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_user_start_obj, esp_flash_user_start); STATIC mp_obj_t esp_check_fw(void) { MD5_CTX ctx; - uint32_t *sz_p = (uint32_t*)0x40208ffc; - printf("size: %d\n", *sz_p); + char *fw_start = (char*)0x40200000; + if (IS_OTA_FIRMWARE()) { + // Skip yaota8266 bootloader + fw_start += 0x3c000; + } + + uint32_t size = *(uint32_t*)(fw_start + 0x8ffc); + printf("size: %d\n", size); + if (size > 1024 * 1024) { + printf("Invalid size\n"); + return mp_const_false; + } MD5Init(&ctx); - MD5Update(&ctx, (char*)0x40200004, *sz_p - 4); + MD5Update(&ctx, fw_start + 4, size - 4); unsigned char digest[16]; MD5Final(digest, &ctx); printf("md5: "); @@ -646,7 +664,7 @@ STATIC mp_obj_t esp_check_fw(void) { printf("%02x", digest[i]); } printf("\n"); - return mp_obj_new_bool(memcmp(digest, (void*)(0x40200000 + *sz_p), sizeof(digest)) == 0); + return mp_obj_new_bool(memcmp(digest, fw_start + size, sizeof(digest)) == 0); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_check_fw_obj, esp_check_fw); @@ -699,6 +717,111 @@ STATIC mp_obj_t esp_esf_free_bufs(mp_obj_t idx_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_esf_free_bufs_obj, esp_esf_free_bufs); +#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA + +// We provide here a way of committing executable data to a region from +// which it can be executed by the CPU. There are 2 such writable regions: +// - iram1, which may have some space left at the end of it +// - memory-mapped flash rom +// +// By default the iram1 region (the space at the end of it) is used. The +// user can select iram1 or a section of flash by calling the +// esp.set_native_code_location() function; see below. If flash is selected +// then it is erased as needed. + +#include "gccollect.h" + +#define IRAM1_END (0x40108000) +#define FLASH_START (0x40200000) +#define FLASH_END (0x40300000) +#define FLASH_SEC_SIZE (4096) + +#define ESP_NATIVE_CODE_IRAM1 (0) +#define ESP_NATIVE_CODE_FLASH (1) + +extern uint32_t _lit4_end; +STATIC uint32_t esp_native_code_location; +STATIC uint32_t esp_native_code_start; +STATIC uint32_t esp_native_code_end; +STATIC uint32_t esp_native_code_cur; +STATIC uint32_t esp_native_code_erased; + +void esp_native_code_init(void) { + esp_native_code_location = ESP_NATIVE_CODE_IRAM1; + esp_native_code_start = (uint32_t)&_lit4_end; + esp_native_code_end = IRAM1_END; + esp_native_code_cur = esp_native_code_start; + esp_native_code_erased = 0; +} + +void esp_native_code_gc_collect(void) { + void *src; + if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1) { + src = (void*)esp_native_code_start; + } else { + src = (void*)(FLASH_START + esp_native_code_start); + } + gc_collect_root(src, (esp_native_code_end - esp_native_code_start) / sizeof(uint32_t)); +} + +void *esp_native_code_commit(void *buf, size_t len) { + //printf("COMMIT(buf=%p, len=%u, start=%08x, cur=%08x, end=%08x, erased=%08x)\n", buf, len, esp_native_code_start, esp_native_code_cur, esp_native_code_end, esp_native_code_erased); + + len = (len + 3) & ~3; + if (esp_native_code_cur + len > esp_native_code_end) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, + "memory allocation failed, allocating %u bytes for native code", (uint)len)); + } + + void *dest; + if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1) { + dest = (void*)esp_native_code_cur; + memcpy(dest, buf, len); + } else { + SpiFlashOpResult res; + while (esp_native_code_erased < esp_native_code_cur + len) { + res = spi_flash_erase_sector(esp_native_code_erased / FLASH_SEC_SIZE); + if (res != SPI_FLASH_RESULT_OK) { + break; + } + esp_native_code_erased += FLASH_SEC_SIZE; + } + if (res == SPI_FLASH_RESULT_OK) { + res = spi_flash_write(esp_native_code_cur, buf, len); + } + if (res != SPI_FLASH_RESULT_OK) { + mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO); + } + dest = (void*)(FLASH_START + esp_native_code_cur); + } + + esp_native_code_cur += len; + + return dest; +} + +STATIC mp_obj_t esp_set_native_code_location(mp_obj_t start_in, mp_obj_t len_in) { + if (start_in == mp_const_none && len_in == mp_const_none) { + // use end of iram1 region + esp_native_code_init(); + } else { + // use flash; input params are byte offsets from start of flash + esp_native_code_location = ESP_NATIVE_CODE_FLASH; + esp_native_code_start = mp_obj_get_int(start_in); + esp_native_code_end = esp_native_code_start + mp_obj_get_int(len_in); + esp_native_code_cur = esp_native_code_start; + esp_native_code_erased = esp_native_code_start; + // memory-mapped flash is limited in extents to 1MByte + if (esp_native_code_end > FLASH_END - FLASH_START) { + mp_raise_ValueError("flash location must be below 1MByte"); + } + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_set_native_code_location_obj, esp_set_native_code_location); + +#endif + STATIC const mp_map_elem_t esp_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_esp) }, @@ -729,6 +852,9 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_malloc), (mp_obj_t)&esp_malloc_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_free), (mp_obj_t)&esp_free_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_esf_free_bufs), (mp_obj_t)&esp_esf_free_bufs_obj }, + #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA + { MP_OBJ_NEW_QSTR(MP_QSTR_set_native_code_location), (mp_obj_t)&esp_set_native_code_location_obj }, + #endif #if MODESP_INCLUDE_CONSTANTS { MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP_NONE), diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index 29a72f7e4a..a5073d96c0 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -147,7 +147,7 @@ STATIC void esp_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ mp_printf(print, "Timer(%p)", &self->timer); } -STATIC mp_obj_t esp_timer_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +STATIC mp_obj_t esp_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); esp_timer_obj_t *tim = m_new_obj(esp_timer_obj_t); tim->base.type = &esp_timer_type; @@ -255,7 +255,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&pyb_hspi_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hspi_type) }, // wake abilities { MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) }, diff --git a/esp8266/modmachine.h b/esp8266/modmachine.h index df7953ecb6..414aaa85b0 100644 --- a/esp8266/modmachine.h +++ b/esp8266/modmachine.h @@ -9,9 +9,7 @@ extern const mp_obj_type_t pyb_adc_type; extern const mp_obj_type_t pyb_rtc_type; extern const mp_obj_type_t pyb_uart_type; extern const mp_obj_type_t pyb_i2c_type; -extern const mp_obj_type_t pyb_spi_type; -extern const mp_obj_type_t pyb_hspi_type; -extern const mp_obj_type_t machine_spi_type; +extern const mp_obj_type_t machine_hspi_type; MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj); diff --git a/esp8266/modules/flashbdev.py b/esp8266/modules/flashbdev.py index e879895fb0..8f8df0b640 100644 --- a/esp8266/modules/flashbdev.py +++ b/esp8266/modules/flashbdev.py @@ -3,8 +3,9 @@ import esp class FlashBdev: SEC_SIZE = 4096 - START_SEC = esp.flash_user_start() // SEC_SIZE - NUM_BLK = 0x6b + RESERVED_SECS = 0 + START_SEC = esp.flash_user_start() // SEC_SIZE + RESERVED_SECS + NUM_BLK = 0x6b - RESERVED_SECS def __init__(self, blocks=NUM_BLK): self.blocks = blocks @@ -26,40 +27,6 @@ class FlashBdev: if op == 5: # BP_IOCTL_SEC_SIZE return self.SEC_SIZE -def set_bl_flash_size(real_size): - if real_size == 256*1024: - code = 1 - elif real_size == 512*1024: - code = 0 - elif real_size == 1024*1024: - code = 2 - elif real_size == 2048*1024: - code = 3 - elif real_size == 4096*1024: - code = 4 - else: - code = 2 - buf = bytearray(4096) - esp.flash_read(0, buf) - buf[3] = (buf[3] & 0xf) | (code << 4) - esp.flash_erase(0) - esp.flash_write(0, buf) - -# If bootloader size ID doesn't correspond to real Flash size, -# fix bootloader value and reboot. -size = esp.flash_id() >> 16 -# Check that it looks like realistic power of 2 for flash sizes -# commonly used with esp8266 -if 22 >= size >= 18: - size = 1 << size - if size != esp.flash_size(): - import machine - import time - print("Bootloader Flash size appear to have been set incorrectly, trying to fix") - set_bl_flash_size(size) - machine.reset() - while 1: time.sleep(1) - size = esp.flash_size() if size < 1024*1024: bdev = None diff --git a/esp8266/scripts/websocket_helper.py b/esp8266/modules/websocket_helper.py index 9c06db5023..9c06db5023 100644 --- a/esp8266/scripts/websocket_helper.py +++ b/esp8266/modules/websocket_helper.py diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index 602b3e9c81..5ba153ce5f 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -10,15 +10,16 @@ #define MICROPY_ALLOC_PARSE_RESULT_INC (8) #define MICROPY_ALLOC_PARSE_CHUNK_INIT (64) #define MICROPY_PERSISTENT_CODE_LOAD (1) -#define MICROPY_EMIT_X64 (0) -#define MICROPY_EMIT_THUMB (0) -#define MICROPY_EMIT_INLINE_THUMB (0) +#define MICROPY_EMIT_XTENSA (1) +#define MICROPY_EMIT_INLINE_XTENSA (1) #define MICROPY_MEM_STATS (0) #define MICROPY_DEBUG_PRINTERS (1) #define MICROPY_DEBUG_PRINTER_DEST mp_debug_print +#define MICROPY_READER_FATFS (MICROPY_VFS_FAT) #define MICROPY_ENABLE_GC (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) +#define MICROPY_KBD_EXCEPTION (1) #define MICROPY_REPL_EVENT_DRIVEN (0) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_HELPER_REPL (1) @@ -59,9 +60,11 @@ #define MICROPY_PY_UHASHLIB (1) #define MICROPY_PY_UHASHLIB_SHA1 (MICROPY_PY_USSL && MICROPY_SSL_AXTLS) #define MICROPY_PY_UHEAPQ (1) +#define MICROPY_PY_UTIMEQ (1) #define MICROPY_PY_UJSON (1) #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URE (1) +#define MICROPY_PY_USELECT (1) #define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_LWIP (1) @@ -69,6 +72,7 @@ #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SPI (1) +#define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hspi_make_new #define MICROPY_PY_WEBSOCKET (1) #define MICROPY_PY_WEBREPL (1) #define MICROPY_PY_WEBREPL_DELAY (20) @@ -128,6 +132,8 @@ typedef uint32_t sys_prot_t; // for modlwip #include <sys/types.h> #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) +void *esp_native_code_commit(void*, size_t); +#define MP_PLAT_COMMIT_EXEC(buf, len) esp_native_code_commit(buf, len) #define mp_type_fileio fatfs_type_fileio #define mp_type_textio fatfs_type_textio @@ -163,13 +169,13 @@ extern const struct _mp_obj_module_t onewire_module; { MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&uos_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_json), (mp_obj_t)&mp_module_ujson }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_errno), (mp_obj_t)&mp_module_uerrno }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&mp_module_uselect }, \ #define MP_STATE_PORT MP_STATE_VM #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ vstr_t *repl_line; \ - mp_obj_t mp_kbd_exception; \ mp_obj_t pin_irq_handler[16]; \ // We need to provide a declaration/definition of alloca() diff --git a/esp8266/mpconfigport_512k.h b/esp8266/mpconfigport_512k.h index f0de6035f1..d1d6025793 100644 --- a/esp8266/mpconfigport_512k.h +++ b/esp8266/mpconfigport_512k.h @@ -1,5 +1,10 @@ #include <mpconfigport.h> +#undef MICROPY_EMIT_XTENSA +#define MICROPY_EMIT_XTENSA (0) +#undef MICROPY_EMIT_INLINE_XTENSA +#define MICROPY_EMIT_INLINE_XTENSA (0) + #undef MICROPY_FSUSERMOUNT #define MICROPY_FSUSERMOUNT (0) #undef MICROPY_VFS_FAT @@ -17,3 +22,6 @@ #define MICROPY_PY_BUILTINS_SLICE_ATTRS (0) #undef MICROPY_PY_ALL_SPECIAL_METHODS #define MICROPY_PY_ALL_SPECIAL_METHODS (0) + +#undef MICROPY_PY_FRAMEBUF +#define MICROPY_PY_FRAMEBUF (0) diff --git a/esp8266/scripts/inisetup.py b/esp8266/scripts/inisetup.py index 1cb9f0dd95..3930089db6 100644 --- a/esp8266/scripts/inisetup.py +++ b/esp8266/scripts/inisetup.py @@ -24,11 +24,12 @@ def fs_corrupted(): import time while 1: print("""\ -FAT filesystem appears to be corrupted. If you had important data there, you -may want to make a flash snapshot to try to recover it. Otherwise, perform -factory reprogramming of MicroPython firmware (completely erase flash, followed -by firmware programming). -""") +The FAT filesystem starting at sector %d with size %d sectors appears to +be corrupted. If you had important data there, you may want to make a flash +snapshot to try to recover it. Otherwise, perform factory reprogramming +of MicroPython firmware (completely erase flash, followed by firmware +programming). +""" % (bdev.START_SEC, bdev.blocks)) time.sleep(3) def setup(): |