summaryrefslogtreecommitdiffstatshomepage
path: root/esp8266
diff options
context:
space:
mode:
Diffstat (limited to 'esp8266')
-rw-r--r--esp8266/Makefile16
-rw-r--r--esp8266/esp8266.ld2
-rw-r--r--esp8266/esp8266_512k.ld2
-rw-r--r--esp8266/esp8266_ota.ld306
-rw-r--r--esp8266/esp_mphal.h2
-rw-r--r--esp8266/gccollect.c5
-rw-r--r--esp8266/gccollect.h1
-rw-r--r--esp8266/lexerstr32.c11
-rw-r--r--esp8266/machine_adc.c2
-rw-r--r--esp8266/machine_hspi.c79
-rw-r--r--esp8266/machine_pin.c4
-rw-r--r--esp8266/machine_rtc.c2
-rw-r--r--esp8266/machine_spi.c142
-rw-r--r--esp8266/machine_uart.c1
-rw-r--r--esp8266/machine_wdt.c2
-rw-r--r--esp8266/main.c16
-rw-r--r--esp8266/modesp.c136
-rw-r--r--esp8266/modmachine.c4
-rw-r--r--esp8266/modmachine.h4
-rw-r--r--esp8266/modules/flashbdev.py39
-rw-r--r--esp8266/modules/websocket_helper.py (renamed from esp8266/scripts/websocket_helper.py)0
-rw-r--r--esp8266/mpconfigport.h14
-rw-r--r--esp8266/mpconfigport_512k.h8
-rw-r--r--esp8266/scripts/inisetup.py11
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():