diff --git a/README.md b/README.md index 6b6c1bf22..008ddcd3e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Arduino-compatible IDE with ESP8266 support =========================================== -![Linux build status](http://img.shields.io/travis/igrr/Arduino.svg) +[![Linux build status](http://img.shields.io/travis/igrr/Arduino.svg)](https://travis-ci.org/igrr/Arduino) [![Donate](http://img.shields.io/paypal/donate.png?color=yellow)](https://www.paypal.com/webscr?cmd=_s-xclick&hosted_button_id=4M56YCWV6PX66) This project brings support for ESP8266 chip to the Arduino environment. ESP8266WiFi library bundled with this project has the same interface as the WiFi Shield library, making it easy to re-use existing code and libraries. diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile index 32e325f34..cd9e14143 100644 --- a/bootloaders/eboot/Makefile +++ b/bootloaders/eboot/Makefile @@ -5,6 +5,7 @@ TARGET_DIR := ./ TARGET_OBJ_FILES := \ eboot.o \ + eboot_command.o \ TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES)) diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index e39375d2d..b3193e299 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -10,6 +10,7 @@ #include #include #include "eboot.h" +#include "eboot_command.h" extern void* flashchip; #define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0); @@ -71,9 +72,100 @@ int load_app_from_flash_raw(const uint32_t flash_addr) } + +int erase(const uint32_t start, const uint32_t size) +{ + if (start & (FLASH_SECTOR_SIZE - 1) != 0) { + return 1; + } + + const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + uint32_t current_sector = start / FLASH_SECTOR_SIZE; + uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; + const uint32_t end = current_sector + sector_count; + + for (; current_sector < end && (current_sector & (sectors_per_block-1)); + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 2; + } + } + + for (;current_sector + sectors_per_block <= end; + current_sector += sectors_per_block, + sector_count -= sectors_per_block) { + if (SPIEraseBlock(current_sector / sectors_per_block)) { + return 3; + } + } + + for (; current_sector < end; + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 4; + } + } + + return 0; +} + +int copy_raw(const uint32_t src_addr, + const uint32_t dst_addr, + const uint32_t size) +{ + // require regions to be aligned + if (src_addr & 0xfff != 0 || + dst_addr & 0xfff != 0) { + return 1; + } + + if (erase(dst_addr, size)) { + return 2; + } + + const uint32_t buffer_size = 4096; + uint8_t buffer[buffer_size]; + + const uint32_t end = src_addr + size; + uint32_t saddr = src_addr; + uint32_t daddr = dst_addr; + uint32_t left = size; + while (saddr < end) { + uint32_t will_copy = (left < buffer_size) ? left : buffer_size; + if (SPIRead(saddr, buffer, will_copy)) { + return 3; + } + if (SPIWrite(daddr, buffer, will_copy)) { + return 4; + } + saddr += will_copy; + daddr += will_copy; + left -= will_copy; + } + + return 0; +} + + + void main() { - int res = load_app_from_flash_raw(0); + int res = 9; + struct eboot_command cmd; + + eboot_command_read(&cmd); + + if (cmd.action == ACTION_COPY_RAW) { + res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); + if (res == 0) { + cmd.action = ACTION_LOAD_APP; + } + } + + if (cmd.action == ACTION_LOAD_APP) { + res = load_app_from_flash_raw(0); + } + if (res) { ets_putc('\n'); ets_putc('#'); diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index b2381a409..0637a0525 100755 Binary files a/bootloaders/eboot/eboot.elf and b/bootloaders/eboot/eboot.elf differ diff --git a/bootloaders/eboot/eboot.h b/bootloaders/eboot/eboot.h index b77f8f45a..973c616a8 100644 --- a/bootloaders/eboot/eboot.h +++ b/bootloaders/eboot/eboot.h @@ -14,6 +14,9 @@ int SPIEraseSector(uint32_t sector); int SPIRead(uint32_t addr, void *dest, size_t size); int SPIWrite(uint32_t addr, void *src, size_t size); + +#define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_BLOCK_SIZE 0x10000 #define APP_START_OFFSET 0x1000 typedef struct { diff --git a/bootloaders/eboot/eboot.ld b/bootloaders/eboot/eboot.ld index 0b9250dea..303ae8a56 100644 --- a/bootloaders/eboot/eboot.ld +++ b/bootloaders/eboot/eboot.ld @@ -4,7 +4,7 @@ MEMORY { dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 - iram1_0_seg : org = 0x4010f800, len = 0x800 + iram1_0_seg : org = 0x4010f000, len = 0x1000 irom0_0_seg : org = 0x40240000, len = 0x32000 } diff --git a/bootloaders/eboot/eboot_command.c b/bootloaders/eboot/eboot_command.c new file mode 100644 index 000000000..1e9cbed2c --- /dev/null +++ b/bootloaders/eboot/eboot_command.c @@ -0,0 +1,47 @@ +#include "eboot_command.h" + +uint32_t crc_update(uint32_t crc, const uint8_t *data, size_t length) +{ + uint32_t i; + bool bit; + uint8_t c; + + while (length--) { + c = *data++; + for (i = 0x80; i > 0; i >>= 1) { + bit = crc & 0x80000000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x04c11db7; + } + } + } + return crc; +} + +uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) +{ + return crc_update(0xffffffff, (const uint8_t*) cmd, + offsetof(struct eboot_command, crc32)); +} + +void eboot_command_read(struct eboot_command* cmd) +{ + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + uint32_t* dst = (uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + dst[i] = RTC_MEM[i]; + } + + uint32_t crc32 = eboot_command_calculate_crc32(cmd); + if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC || + cmd->crc32 != crc32) { + + cmd->action = ACTION_LOAD_APP; + cmd->args[0] = 0; + } +} + diff --git a/bootloaders/eboot/eboot_command.h b/bootloaders/eboot/eboot_command.h new file mode 100644 index 000000000..aa0fc11bb --- /dev/null +++ b/bootloaders/eboot/eboot_command.h @@ -0,0 +1,29 @@ +#ifndef EBOOT_COMMAND_H +#define EBOOT_COMMAND_H + +#include +#include +#include + +#define RTC_MEM ((volatile uint32_t*)0x60001200) + +enum action_t { + ACTION_COPY_RAW = 0x00000001, + ACTION_LOAD_APP = 0xffffffff +}; + +#define EBOOT_MAGIC 0xeb001000 +#define EBOOT_MAGIC_MASK 0xfffff000 + +struct eboot_command { + uint32_t magic; + enum action_t action; + uint32_t args[29]; + uint32_t crc32; +}; + + +void eboot_command_read(struct eboot_command* cmd); + + +#endif //EBOOT_COMMAND_H diff --git a/cores/esp8266/core_esp8266_timer.c b/cores/esp8266/core_esp8266_timer.c index 08b971c58..819c5f990 100644 --- a/cores/esp8266/core_esp8266_timer.c +++ b/cores/esp8266/core_esp8266_timer.c @@ -20,18 +20,11 @@ */ #include "wiring_private.h" #include "pins_arduino.h" -#ifdef __cplusplus -extern "C" { -#endif #include "c_types.h" #include "ets_sys.h" -#ifdef __cplusplus -} -#endif - -/ ------------------------------------------------------------------ - +// ------------------------------------------------------------------ - // timer 1 static volatile timercallback timer1_user_cb = NULL; diff --git a/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino b/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino index a3fdaf49c..4176c511b 100644 --- a/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino +++ b/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino @@ -72,7 +72,7 @@ void loop() //get a random server from the pool WiFi.hostByName(ntpServerName, timeServerIP); - sendNTPpacket(timeServer); // send an NTP packet to a time server + sendNTPpacket(timeServerIP); // send an NTP packet to a time server // wait to see if a reply is available delay(1000); diff --git a/platform.txt b/platform.txt index f0796310b..2695115c2 100644 --- a/platform.txt +++ b/platform.txt @@ -78,7 +78,7 @@ recipe.objcopy.hex.pattern="{runtime.tools.esptool.path}/{compiler.esptool.cmd}" ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" -recipe.size.regex=^(?:\.irom0\.text|\.text|\.data|\.rodata|\.bss|)\s+([0-9]+).* +recipe.size.regex=^(?:\.irom0\.text|\.text|\.data|\.rodata|)\s+([0-9]+).* recipe.size.regex.data=^(?:\.data|\.rodata|\.bss)\s+([0-9]+).* #recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*