mirror of
https://github.com/Threnklyn/esphome-dev.git
synced 2026-05-19 04:33:27 +02:00
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:
+11
-17
@@ -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
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user