Add ESP8266 core v2.6.2 (#905)

* Add ESP8266 core v2.6.2

* Upstream ESP8266 Wifi fixes

* Replace disable_interrupt with InterruptLock C++ class

* Update code to use InterruptLock

* Lint

* Update dht.cpp

* Improve InterruptLock docs, mark as ICACHE_RAM_ATTR

* Fixes
This commit is contained in:
Otto Winter
2019-12-04 19:30:10 +01:00
committed by GitHub
parent bba6d6897d
commit 7a6df38515
12 changed files with 291 additions and 180 deletions
+11 -17
View File
@@ -156,21 +156,6 @@ ParseOnOffState parse_on_off(const char *str, const char *on, const char *off) {
const char *HOSTNAME_CHARACTER_WHITELIST = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
void disable_interrupts() {
#ifdef ARDUINO_ARCH_ESP32
portDISABLE_INTERRUPTS();
#else
noInterrupts();
#endif
}
void enable_interrupts() {
#ifdef ARDUINO_ARCH_ESP32
portENABLE_INTERRUPTS();
#else
interrupts();
#endif
}
uint8_t crc8(uint8_t *data, uint8_t len) {
uint8_t crc = 0;
@@ -193,8 +178,8 @@ void delay_microseconds_accurate(uint32_t usec) {
if (usec <= 16383UL) {
delayMicroseconds(usec);
} else {
delay(usec / 1000UL);
delayMicroseconds(usec % 1000UL);
delay(usec / 16383UL);
delayMicroseconds(usec % 16383UL);
}
}
@@ -330,4 +315,13 @@ std::string hexencode(const uint8_t *data, uint32_t len) {
return res;
}
#ifdef ARDUINO_ARCH_ESP8266
ICACHE_RAM_ATTR InterruptLock::InterruptLock() { xt_state_ = xt_rsil(15); }
ICACHE_RAM_ATTR InterruptLock::~InterruptLock() { xt_wsr_ps(xt_state_); }
#endif
#ifdef ARDUINO_ARCH_ESP32
ICACHE_RAM_ATTR InterruptLock::InterruptLock() { portENABLE_INTERRUPTS(); }
ICACHE_RAM_ATTR InterruptLock::~InterruptLock() { portDISABLE_INTERRUPTS(); }
#endif
} // namespace esphome
+28 -6
View File
@@ -133,16 +133,38 @@ uint16_t encode_uint16(uint8_t msb, uint8_t lsb);
/// Decode a 16-bit unsigned integer into an array of two values: most significant byte, least significant byte.
std::array<uint8_t, 2> decode_uint16(uint16_t value);
/** Cross-platform method to disable interrupts.
/***
* An interrupt helper class.
*
* Useful when you need to do some timing-dependent communication.
* This behaves like std::lock_guard. As long as the value is visible in the current stack, all interrupts
* (including flash reads) will be disabled.
*
* @see Do not forget to call `enable_interrupts()` again or otherwise things will go very wrong.
* Please note all functions called when the interrupt lock must be marked ICACHE_RAM_ATTR (loading code into
* instruction cache is done via interrupts; disabling interrupts prevents data not already in cache from being
* pulled from flash).
*
* Example:
*
* ```cpp
* // interrupts are enabled
* {
* InterruptLock lock;
* // do something
* // interrupts are disabled
* }
* // interrupts are enabled
* ```
*/
void disable_interrupts();
class InterruptLock {
public:
InterruptLock();
~InterruptLock();
/// Cross-platform method to enable interrupts after they have been disabled.
void enable_interrupts();
protected:
#ifdef ARDUINO_ARCH_ESP8266
uint32_t xt_state_;
#endif
};
/// Calculate a crc8 of data with the provided data length.
uint8_t crc8(uint8_t *data, uint8_t len);
+13 -9
View File
@@ -105,16 +105,18 @@ void ESPPreferences::save_esp8266_flash_() {
return;
ESP_LOGVV(TAG, "Saving preferences to flash...");
disable_interrupts();
auto erase_res = spi_flash_erase_sector(get_esp8266_flash_sector());
SpiFlashOpResult erase_res, write_res = SPI_FLASH_RESULT_OK;
{
InterruptLock lock;
erase_res = spi_flash_erase_sector(get_esp8266_flash_sector());
if (erase_res == SPI_FLASH_RESULT_OK) {
write_res = spi_flash_write(get_esp8266_flash_address(), this->flash_storage_, ESP8266_FLASH_STORAGE_SIZE * 4);
}
}
if (erase_res != SPI_FLASH_RESULT_OK) {
enable_interrupts();
ESP_LOGV(TAG, "Erase ESP8266 flash failed!");
return;
}
auto write_res = spi_flash_write(get_esp8266_flash_address(), this->flash_storage_, ESP8266_FLASH_STORAGE_SIZE * 4);
enable_interrupts();
if (write_res != SPI_FLASH_RESULT_OK) {
ESP_LOGV(TAG, "Write ESP8266 flash failed!");
return;
@@ -173,9 +175,11 @@ ESPPreferences::ESPPreferences()
void ESPPreferences::begin() {
this->flash_storage_ = new uint32_t[ESP8266_FLASH_STORAGE_SIZE];
ESP_LOGVV(TAG, "Loading preferences from flash...");
disable_interrupts();
spi_flash_read(get_esp8266_flash_address(), this->flash_storage_, ESP8266_FLASH_STORAGE_SIZE * 4);
enable_interrupts();
{
InterruptLock lock;
spi_flash_read(get_esp8266_flash_address(), this->flash_storage_, ESP8266_FLASH_STORAGE_SIZE * 4);
}
}
ESPPreferenceObject ESPPreferences::make_preference(size_t length, uint32_t type, bool in_flash) {