mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-16 11:21:18 +03:00
Merge remote-tracking branch 'remotes/esp8266/esp8266' into esp8266
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
XTENSA_TOOCHAIN ?=
|
||||
XTENSA_TOOLCHAIN ?=
|
||||
|
||||
BIN_DIR := ./
|
||||
TARGET_DIR := ./
|
||||
@ -6,14 +6,15 @@ TARGET_DIR := ./
|
||||
TARGET_OBJ_FILES := \
|
||||
eboot.o \
|
||||
eboot_command.o \
|
||||
flash.o \
|
||||
|
||||
TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES))
|
||||
|
||||
CC := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-gcc
|
||||
CXX := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-g++
|
||||
AR := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-ar
|
||||
LD := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-gcc
|
||||
OBJDUMP := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-objdump
|
||||
CC := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-gcc
|
||||
CXX := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-g++
|
||||
AR := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-ar
|
||||
LD := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-gcc
|
||||
OBJDUMP := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-objdump
|
||||
|
||||
|
||||
CFLAGS += -std=gnu99
|
||||
|
@ -9,9 +9,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "eboot.h"
|
||||
#include "flash.h"
|
||||
#include "eboot_command.h"
|
||||
extern void* flashchip;
|
||||
|
||||
#define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0);
|
||||
|
||||
@ -73,53 +72,21 @@ 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)
|
||||
{
|
||||
ets_putc('\n');
|
||||
ets_putc('c');
|
||||
ets_putc('p');
|
||||
ets_putc('\n');
|
||||
// require regions to be aligned
|
||||
if (src_addr & 0xfff != 0 ||
|
||||
dst_addr & 0xfff != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (erase(dst_addr, size)) {
|
||||
if (SPIEraseAreaEx(dst_addr, size)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -153,17 +120,25 @@ void main()
|
||||
int res = 9;
|
||||
struct eboot_command cmd;
|
||||
|
||||
eboot_command_read(&cmd);
|
||||
if (eboot_command_read(&cmd)) {
|
||||
cmd.action = ACTION_LOAD_APP;
|
||||
cmd.args[0] = 0;
|
||||
ets_putc('e');
|
||||
} else {
|
||||
ets_putc('@');
|
||||
}
|
||||
eboot_command_clear();
|
||||
|
||||
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;
|
||||
cmd.args[0] = cmd.args[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd.action == ACTION_LOAD_APP) {
|
||||
res = load_app_from_flash_raw(0);
|
||||
res = load_app_from_flash_raw(cmd.args[0]);
|
||||
}
|
||||
|
||||
if (res) {
|
||||
|
Binary file not shown.
@ -28,7 +28,7 @@ uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd)
|
||||
offsetof(struct eboot_command, crc32));
|
||||
}
|
||||
|
||||
void eboot_command_read(struct eboot_command* cmd)
|
||||
int 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;
|
||||
@ -39,9 +39,27 @@ void eboot_command_read(struct eboot_command* cmd)
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eboot_command_write(struct eboot_command* cmd)
|
||||
{
|
||||
cmd->magic = EBOOT_MAGIC;
|
||||
cmd->crc32 = eboot_command_calculate_crc32(cmd);
|
||||
|
||||
const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t);
|
||||
const uint32_t* src = (const uint32_t *) cmd;
|
||||
for (uint32_t i = 0; i < dw_count; ++i) {
|
||||
RTC_MEM[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
void eboot_command_clear()
|
||||
{
|
||||
RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0;
|
||||
RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
/* Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
|
||||
* This file is part of eboot bootloader.
|
||||
*
|
||||
* Redistribution and use is permitted according to the conditions of the
|
||||
* 3-clause BSD license to be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef EBOOT_COMMAND_H
|
||||
#define EBOOT_COMMAND_H
|
||||
|
||||
@ -23,7 +30,8 @@ struct eboot_command {
|
||||
};
|
||||
|
||||
|
||||
void eboot_command_read(struct eboot_command* cmd);
|
||||
|
||||
int eboot_command_read(struct eboot_command* cmd);
|
||||
void eboot_command_write(struct eboot_command* cmd);
|
||||
void eboot_command_clear();
|
||||
|
||||
#endif //EBOOT_COMMAND_H
|
||||
|
49
hardware/esp8266com/esp8266/bootloaders/eboot/flash.c
Normal file
49
hardware/esp8266com/esp8266/bootloaders/eboot/flash.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
|
||||
* This file is part of eboot bootloader.
|
||||
*
|
||||
* Redistribution and use is permitted according to the conditions of the
|
||||
* 3-clause BSD license to be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "flash.h"
|
||||
|
||||
|
||||
int SPIEraseAreaEx(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;
|
||||
}
|
||||
|
@ -5,15 +5,14 @@
|
||||
* 3-clause BSD license to be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef EBOOT_H
|
||||
#define EBOOT_H
|
||||
|
||||
#ifndef FLASH_H
|
||||
#define FLASH_H
|
||||
|
||||
int SPIEraseBlock(uint32_t block);
|
||||
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);
|
||||
|
||||
int SPIEraseAreaEx(const uint32_t start, const uint32_t size);
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
#define FLASH_BLOCK_SIZE 0x10000
|
||||
@ -41,4 +40,4 @@ typedef struct {
|
||||
|
||||
|
||||
|
||||
#endif //EBOOT_H
|
||||
#endif //FLASH_H
|
@ -19,6 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "flash_utils.h"
|
||||
#include "eboot_command.h"
|
||||
#include <memory>
|
||||
|
||||
extern "C" {
|
||||
#include "user_interface.h"
|
||||
@ -26,6 +29,9 @@ extern "C" {
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
|
||||
|
||||
// #define DEBUG_SERIAL Serial
|
||||
|
||||
//extern "C" void ets_wdt_init(uint32_t val);
|
||||
extern "C" void ets_wdt_enable(void);
|
||||
extern "C" void ets_wdt_disable(void);
|
||||
@ -295,7 +301,7 @@ struct rst_info * EspClass::getResetInfoPtr(void) {
|
||||
return &resetInfo;
|
||||
}
|
||||
|
||||
bool EspClass::eraseESPconfig(void) {
|
||||
bool EspClass::eraseConfig(void) {
|
||||
bool ret = true;
|
||||
size_t cfgAddr = (ESP.getFlashChipSize() - 0x4000);
|
||||
size_t cfgSize = (8*1024);
|
||||
@ -315,4 +321,123 @@ bool EspClass::eraseESPconfig(void) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getSketchSize() {
|
||||
static uint32_t result = 0;
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
image_header_t image_header;
|
||||
uint32_t pos = APP_START_OFFSET;
|
||||
if (spi_flash_read(pos, (uint32_t*) &image_header, sizeof(image_header))) {
|
||||
return 0;
|
||||
}
|
||||
pos += sizeof(image_header);
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.printf("num_segments=%u\r\n", image_header.num_segments);
|
||||
#endif
|
||||
for (uint32_t section_index = 0;
|
||||
section_index < image_header.num_segments;
|
||||
++section_index)
|
||||
{
|
||||
section_header_t section_header = {0};
|
||||
if (spi_flash_read(pos, (uint32_t*) §ion_header, sizeof(section_header))) {
|
||||
return 0;
|
||||
}
|
||||
pos += sizeof(section_header);
|
||||
pos += section_header.size;
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.printf("section=%u size=%u pos=%u\r\n", section_index, section_header.size, pos);
|
||||
#endif
|
||||
}
|
||||
result = pos;
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" uint32_t _SPIFFS_start;
|
||||
|
||||
uint32_t EspClass::getFreeSketchSpace() {
|
||||
|
||||
uint32_t usedSize = getSketchSize();
|
||||
// round one sector up
|
||||
uint32_t freeSpaceStart = (usedSize + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1));
|
||||
uint32_t freeSpaceEnd = (uint32_t)&_SPIFFS_start - 0x40200000;
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.printf("usedSize=%u freeSpaceStart=%u freeSpaceEnd=%u\r\n", usedSize, freeSpaceStart, freeSpaceEnd);
|
||||
#endif
|
||||
return freeSpaceEnd - freeSpaceStart;
|
||||
}
|
||||
|
||||
bool EspClass::updateSketch(Stream& in, uint32_t size) {
|
||||
|
||||
if (size > getFreeSketchSpace())
|
||||
return false;
|
||||
|
||||
uint32_t usedSize = getSketchSize();
|
||||
uint32_t freeSpaceStart = (usedSize + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1));
|
||||
uint32_t roundedSize = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1));
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.printf("erase @0x%x size=0x%x\r\n", freeSpaceStart, roundedSize);
|
||||
#endif
|
||||
|
||||
noInterrupts();
|
||||
int rc = SPIEraseAreaEx(freeSpaceStart, roundedSize);
|
||||
interrupts();
|
||||
if (rc)
|
||||
return false;
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println("erase done");
|
||||
#endif
|
||||
|
||||
uint32_t addr = freeSpaceStart;
|
||||
uint32_t left = size;
|
||||
|
||||
const uint32_t bufferSize = FLASH_SECTOR_SIZE;
|
||||
std::unique_ptr<uint8_t> buffer(new uint8_t[bufferSize]);
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println("writing");
|
||||
#endif
|
||||
while (left > 0) {
|
||||
size_t willRead = (left < bufferSize) ? left : bufferSize;
|
||||
size_t rd = in.readBytes(buffer.get(), willRead);
|
||||
if (rd != willRead) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println("stream read failed");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
noInterrupts();
|
||||
rc = SPIWrite(addr, buffer.get(), willRead);
|
||||
interrupts();
|
||||
if (rc) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println("write failed");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
addr += willRead;
|
||||
left -= willRead;
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(".");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println("\r\nrestarting");
|
||||
#endif
|
||||
eboot_command ebcmd;
|
||||
ebcmd.action = ACTION_COPY_RAW;
|
||||
ebcmd.args[0] = freeSpaceStart;
|
||||
ebcmd.args[1] = 0x00000;
|
||||
ebcmd.args[2] = size;
|
||||
eboot_command_write(&ebcmd);
|
||||
|
||||
ESP.restart();
|
||||
return true; // never happens
|
||||
}
|
||||
|
||||
|
@ -69,44 +69,48 @@ class EspClass {
|
||||
// note: setting the timeout value is not implemented at the moment
|
||||
void wdtEnable(WDTO_t timeout_ms = WDTO_0MS);
|
||||
|
||||
void wdtDisable(void);
|
||||
void wdtFeed(void);
|
||||
void wdtDisable();
|
||||
void wdtFeed();
|
||||
|
||||
void deepSleep(uint32_t time_us, WakeMode mode = WAKE_RF_DEFAULT);
|
||||
|
||||
void reset(void);
|
||||
void restart(void);
|
||||
void reset();
|
||||
void restart();
|
||||
|
||||
uint16_t getVcc(void);
|
||||
uint32_t getFreeHeap(void);
|
||||
uint16_t getVcc();
|
||||
uint32_t getFreeHeap();
|
||||
|
||||
uint32_t getChipId(void);
|
||||
uint32_t getChipId();
|
||||
|
||||
const char * getSdkVersion(void);
|
||||
const char * getSdkVersion();
|
||||
|
||||
uint8_t getBootVersion(void);
|
||||
uint8_t getBootMode(void);
|
||||
uint8_t getBootVersion();
|
||||
uint8_t getBootMode();
|
||||
|
||||
uint8_t getCpuFreqMHz(void);
|
||||
uint8_t getCpuFreqMHz();
|
||||
|
||||
uint32_t getFlashChipId(void);
|
||||
uint32_t getFlashChipId();
|
||||
//gets the actual chip size based on the flash id
|
||||
uint32_t getFlashChipRealSize(void);
|
||||
uint32_t getFlashChipRealSize();
|
||||
//gets the size of the flash as set by the compiler
|
||||
uint32_t getFlashChipSize(void);
|
||||
uint32_t getFlashChipSpeed(void);
|
||||
FlashMode_t getFlashChipMode(void);
|
||||
uint32_t getFlashChipSizeByChipId(void);
|
||||
uint32_t getFlashChipSize();
|
||||
uint32_t getFlashChipSpeed();
|
||||
FlashMode_t getFlashChipMode();
|
||||
uint32_t getFlashChipSizeByChipId();
|
||||
|
||||
String getResetInfo(void);
|
||||
struct rst_info * getResetInfoPtr(void);
|
||||
uint32_t getSketchSize();
|
||||
uint32_t getFreeSketchSpace();
|
||||
bool updateSketch(Stream& in, uint32_t size);
|
||||
|
||||
bool eraseESPconfig(void);
|
||||
String getResetInfo();
|
||||
struct rst_info * getResetInfoPtr();
|
||||
|
||||
inline uint32_t getCycleCount(void);
|
||||
bool eraseConfig();
|
||||
|
||||
inline uint32_t getCycleCount();
|
||||
};
|
||||
|
||||
uint32_t EspClass::getCycleCount(void)
|
||||
uint32_t EspClass::getCycleCount()
|
||||
{
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
core_esp8266_eboot_command.c - interface to the eboot bootloader
|
||||
|
||||
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#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));
|
||||
}
|
||||
|
||||
int 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) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eboot_command_write(struct eboot_command* cmd)
|
||||
{
|
||||
cmd->magic = EBOOT_MAGIC;
|
||||
cmd->crc32 = eboot_command_calculate_crc32(cmd);
|
||||
|
||||
const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t);
|
||||
const uint32_t* src = (const uint32_t *) cmd;
|
||||
for (uint32_t i = 0; i < dw_count; ++i) {
|
||||
RTC_MEM[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
void eboot_command_clear()
|
||||
{
|
||||
RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0;
|
||||
RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0;
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
core_esp8266_flash_utils.c - flash and binary image helpers
|
||||
|
||||
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "flash_utils.h"
|
||||
|
||||
|
||||
int SPIEraseAreaEx(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;
|
||||
}
|
||||
|
36
hardware/esp8266com/esp8266/cores/esp8266/eboot_command.h
Normal file
36
hardware/esp8266com/esp8266/cores/esp8266/eboot_command.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef EBOOT_COMMAND_H
|
||||
#define EBOOT_COMMAND_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
|
||||
int eboot_command_read(struct eboot_command* cmd);
|
||||
void eboot_command_write(struct eboot_command* cmd);
|
||||
void eboot_command_clear();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //EBOOT_COMMAND_H
|
@ -284,7 +284,7 @@ extern uint8_t esp8266_gpioToFn[16];
|
||||
|
||||
//SPI_READY
|
||||
#define SPIRDY ESP8266_DREG(0x0C)
|
||||
#define SPIBUSY 9 //wait SPI idle
|
||||
#define SPI_BUSY 9 //wait SPI idle
|
||||
|
||||
//SPI0 Registers (SPI0 is used for the flash)
|
||||
#define SPI0CMD ESP8266_REG(0x200)
|
||||
|
63
hardware/esp8266com/esp8266/cores/esp8266/flash_utils.h
Normal file
63
hardware/esp8266com/esp8266/cores/esp8266/flash_utils.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
flash_utils.h - Flash access function and data structures
|
||||
Copyright (c) 2015 Ivan Grokhotkov. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FLASH_UTILS_H
|
||||
#define FLASH_UTILS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int SPIEraseBlock(uint32_t block);
|
||||
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);
|
||||
int SPIEraseAreaEx(const uint32_t start, const uint32_t size);
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
#define FLASH_BLOCK_SIZE 0x10000
|
||||
#define APP_START_OFFSET 0x1000
|
||||
|
||||
typedef struct {
|
||||
unsigned char magic;
|
||||
unsigned char num_segments;
|
||||
|
||||
/* SPI Flash Interface (0 = QIO, 1 = QOUT, 2 = DIO, 0x3 = DOUT) */
|
||||
unsigned char flash_mode;
|
||||
|
||||
/* High four bits: 0 = 512K, 1 = 256K, 2 = 1M, 3 = 2M, 4 = 4M,
|
||||
Low four bits: 0 = 40MHz, 1= 26MHz, 2 = 20MHz, 0xf = 80MHz */
|
||||
unsigned char flash_size_freq;
|
||||
|
||||
uint32_t entry;
|
||||
} image_header_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
uint32_t size;
|
||||
} section_header_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif //FLASH_UTILS_H
|
@ -40,6 +40,7 @@ extern "C" void esp_yield();
|
||||
ESP8266WiFiClass::ESP8266WiFiClass()
|
||||
: _useApMode(false)
|
||||
, _useClientMode(false)
|
||||
, _useStaticIp(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -103,7 +104,8 @@ int ESP8266WiFiClass::begin(const char* ssid, const char *passphrase, int32_t ch
|
||||
wifi_set_channel(channel);
|
||||
}
|
||||
|
||||
wifi_station_dhcpc_start();
|
||||
if(!_useStaticIp)
|
||||
wifi_station_dhcpc_start();
|
||||
return status();
|
||||
}
|
||||
|
||||
@ -115,6 +117,8 @@ uint8_t ESP8266WiFiClass::waitForConnectResult(){
|
||||
return status();
|
||||
}
|
||||
|
||||
|
||||
// You will have to set the DNS-Server manually later since this will not enable DHCP
|
||||
void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
|
||||
{
|
||||
struct ip_info info;
|
||||
@ -124,6 +128,26 @@ void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress s
|
||||
|
||||
wifi_station_dhcpc_stop();
|
||||
wifi_set_ip_info(STATION_IF, &info);
|
||||
|
||||
_useStaticIp = true;
|
||||
}
|
||||
|
||||
void ESP8266WiFiClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns)
|
||||
{
|
||||
struct ip_info info;
|
||||
info.ip.addr = static_cast<uint32_t>(local_ip);
|
||||
info.gw.addr = static_cast<uint32_t>(gateway);
|
||||
info.netmask.addr = static_cast<uint32_t>(subnet);
|
||||
|
||||
wifi_station_dhcpc_stop();
|
||||
wifi_set_ip_info(STATION_IF, &info);
|
||||
|
||||
// Set DNS-Server
|
||||
ip_addr_t d;
|
||||
d.addr = static_cast<uint32_t>(dns);
|
||||
dns_setserver(0,&d);
|
||||
|
||||
_useStaticIp = true;
|
||||
}
|
||||
|
||||
int ESP8266WiFiClass::disconnect()
|
||||
|
@ -75,7 +75,6 @@ public:
|
||||
*/
|
||||
void softAP(const char* ssid, const char* passphrase, int channel = 1);
|
||||
|
||||
|
||||
/* Change Ip configuration settings disabling the dhcp client
|
||||
*
|
||||
* param local_ip: Static ip configuration
|
||||
@ -84,6 +83,15 @@ public:
|
||||
*/
|
||||
void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet);
|
||||
|
||||
/* Change Ip configuration settings disabling the dhcp client
|
||||
*
|
||||
* param local_ip: Static ip configuration
|
||||
* param gateway: Static gateway configuration
|
||||
* param subnet: Static Subnet mask
|
||||
* param dns: Defined DNS
|
||||
*/
|
||||
void config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns);
|
||||
|
||||
/* Configure access point
|
||||
*
|
||||
* param local_ip: access point IP
|
||||
@ -310,7 +318,8 @@ protected:
|
||||
|
||||
bool _useApMode;
|
||||
bool _useClientMode;
|
||||
|
||||
bool _useStaticIp;
|
||||
|
||||
static size_t _scanCount;
|
||||
static void* _scanResult;
|
||||
|
||||
|
Reference in New Issue
Block a user