mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
Merge remote-tracking branch 'remotes/esp8266/esp8266' into esp8266
This commit is contained in:
commit
1544a6ad0f
20
README.md
20
README.md
@ -184,18 +184,24 @@ Allows the sketch to respond to multicast DNS queries for domain names like "foo
|
||||
Currently the library only works on STA interface, AP interface is not supported.
|
||||
See attached example and library README file for details.
|
||||
|
||||
#### Servo ####
|
||||
|
||||
This library exposes the ability to control RC (hobby) servo motors. It will support upto 24 servos on any available output pin. By defualt the first 12 servos will use Timer0 and currently this will not interfere with any other support. Servo counts above 12 will use Timer1 and features that use it will be effected.
|
||||
While many RC servo motors will accept the 3.3v IO data pin from a esp8266, most will not be able to run off 3.3v and will require another power source that matches their specifications. Make sure to connect the grounds between the esp8266 and the servo motor power supply.
|
||||
|
||||
#### Other libraries (not included with the IDE)
|
||||
|
||||
Libraries that don't rely on low-level access to AVR registers should work well. Here are a few libraries that were verified to work:
|
||||
|
||||
- [aREST](https://github.com/marcoschwartz/aREST) REST API handler library.
|
||||
- [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy.
|
||||
- [DHT11](https://github.com/adafruit/DHT-sensor-library) - initialize DHT as follows: ```DHT dht(DHTPIN, DHTTYPE, 15);```
|
||||
- [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library.git)
|
||||
- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266.
|
||||
- [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266.
|
||||
- [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)).
|
||||
- [arduinoWebSockets](https://github.com/Links2004/arduinoWebSockets) - WebSocket Server and Client compatible with esp8266 (RFC6455)
|
||||
- [aREST](https://github.com/marcoschwartz/aREST) REST API handler library.
|
||||
- [Blynk](https://github.com/blynkkk/blynk-library) - easy IoT framework for Makers (check out the [Kickstarter page](http://tiny.cc/blynk-kick)).
|
||||
- [DallasTemperature](https://github.com/milesburton/Arduino-Temperature-Control-Library.git)
|
||||
- [DHT11](https://github.com/adafruit/DHT-sensor-library) - initialize DHT as follows: ```DHT dht(DHTPIN, DHTTYPE, 15);```
|
||||
- [NeoPixelBus](https://github.com/Makuna/NeoPixelBus) - Arduino NeoPixel library compatible with esp8266.
|
||||
- [PubSubClient](https://github.com/Imroy/pubsubclient) MQTT library by @Imroy.
|
||||
- [RTC](https://github.com/Makuna/Rtc) - Arduino Library for Ds1307 & Ds3231 compatible with esp8266.
|
||||
- [Souliss, Smart Home](https://github.com/souliss/souliss) - Framework for Smart Home based on Arduino, Android and openHAB.
|
||||
|
||||
#### Upload via serial port ####
|
||||
Pick the correct serial port.
|
||||
|
@ -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) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
cmd->action = ACTION_LOAD_APP;
|
||||
cmd->args[0] = 0;
|
||||
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
bootloaders/eboot/flash.c
Normal file
49
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));
|
||||
|
88
cores/esp8266/core_esp8266_eboot_command.c
Normal file
88
cores/esp8266/core_esp8266_eboot_command.c
Normal file
@ -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;
|
||||
}
|
||||
|
64
cores/esp8266/core_esp8266_flash_utils.c
Normal file
64
cores/esp8266/core_esp8266_flash_utils.c
Normal file
@ -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
cores/esp8266/eboot_command.h
Normal file
36
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
cores/esp8266/flash_utils.h
Normal file
63
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,6 +104,7 @@ int ESP8266WiFiClass::begin(const char* ssid, const char *passphrase, int32_t ch
|
||||
wifi_set_channel(channel);
|
||||
}
|
||||
|
||||
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,6 +318,7 @@ protected:
|
||||
|
||||
bool _useApMode;
|
||||
bool _useClientMode;
|
||||
bool _useStaticIp;
|
||||
|
||||
static size_t _scanCount;
|
||||
static void* _scanResult;
|
||||
|
Loading…
x
Reference in New Issue
Block a user