diff --git a/.github/workflows/Tasmota_build_devel.yml b/.github/workflows/Tasmota_build_devel.yml index e855f4cb6..3f9fe9e06 100644 --- a/.github/workflows/Tasmota_build_devel.yml +++ b/.github/workflows/Tasmota_build_devel.yml @@ -38,10 +38,12 @@ jobs: - tasmota32-ir - tasmota32-lvgl - tasmota32c3 + - tasmota32c3usb - tasmota32solo1 - tasmota32solo1-safeboot - tasmota32-safeboot - tasmota32c3-safeboot + - tasmota32c3usb-safeboot - tasmota32s2-safeboot - tasmota32s3-safeboot steps: diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index f065fd5f6..d39246639 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -37,12 +37,14 @@ jobs: - tasmota32-ir - tasmota32-lvgl - tasmota32c3 + - tasmota32c3usb - tasmota32solo1 - tasmota32solo1-safeboot - tasmota32-safeboot - tasmota32c3-safeboot - tasmota32s2-safeboot - tasmota32s3-safeboot + - tasmota32c3usb-safeboot steps: - uses: actions/checkout@v3 with: diff --git a/.github/workflows/build_all_the_things.yml b/.github/workflows/build_all_the_things.yml index f81bae9df..3303759f4 100644 --- a/.github/workflows/build_all_the_things.yml +++ b/.github/workflows/build_all_the_things.yml @@ -42,10 +42,12 @@ jobs: - tasmota32-lvgl - tasmota32s2 - tasmota32c3 + - tasmota32c3usb - tasmota32solo1 - tasmota32solo1-safeboot - tasmota32-safeboot - tasmota32c3-safeboot + - tasmota32c3usb-safeboot - tasmota32s2-safeboot - tasmota32s3-safeboot steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index cadcc0282..aac70f934 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] - Development -## [11.1.0.2] +## [11.1.0.3] ### Added -- ESP32 Command ``Restart 3`` to switch between SafeBoot and Production +- Support for Sonoff SPM v1.2.0 ### Changed -- Prepare to remove dedicated Home Assistant discovery in favour of Tasmota Discovery and hatasmota -- ESP32 Tasmota SafeBoot with changed partition scheme allowing larger binaries + ### Fixed @@ -17,6 +16,14 @@ All notable changes to this project will be documented in this file. ### Removed +## [11.1.0.2] 20220514 +### Added +- ESP32 Command ``Restart 3`` to switch between SafeBoot and Production + +### Changed +- Prepare to remove dedicated Home Assistant discovery in favour of Tasmota Discovery and hatasmota +- ESP32 Tasmota SafeBoot with changed partition scheme allowing larger binaries + ## [11.1.0.1] 20220504 ### Added - Support for Sonoff MS01 soil moisture sensor (#15335) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e9fe4d89e..24af1c458 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -104,7 +104,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v11.1.0.2 +## Changelog v11.1.0.3 ### Added - Command ``SetOption139 0/1`` to switch between pressure unit "mmHg" (0) or "inHg" (1) when ``SO24 1`` [#15350](https://github.com/arendst/Tasmota/issues/15350) - Command ``SetOption140 0/1`` to switch between MQTT Clean Session (0) or Persistent Session (1) [#15530](https://github.com/arendst/Tasmota/issues/15530) @@ -113,6 +113,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo - Support for Sonoff MS01 soil moisture sensor [#15335](https://github.com/arendst/Tasmota/issues/15335) - Support for daisy chaining MAX7219 displays [#15345](https://github.com/arendst/Tasmota/issues/15345) - Sonoff SPM delayed SetPowerOnState [#13447](https://github.com/arendst/Tasmota/issues/13447) +- Support for Sonoff SPM v1.2.0 - Support for flowrate meters like YF-DN50 and similary [#15474](https://github.com/arendst/Tasmota/issues/15474) - ESP32 Command ``Restart 3`` to switch between SafeBoot and Production diff --git a/boards/esp32-cam.json b/boards/esp32-cam.json index 84ece18d0..20113163e 100644 --- a/boards/esp32-cam.json +++ b/boards/esp32-cam.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "esp32", - "partitions": "esp32_partition_app2880k_fs320k.csv" + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32-m5core2.json b/boards/esp32-m5core2.json index 8567085ea..5168ea57d 100644 --- a/boards/esp32-m5core2.json +++ b/boards/esp32-m5core2.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "m5stack_core2", - "partitions": "esp32_partition_app2944k_fs10M.csv" + "partitions": "partitions/esp32_partition_app2944k_fs10M.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32-odroid.json b/boards/esp32-odroid.json index a21cedaa9..6d155670e 100644 --- a/boards/esp32-odroid.json +++ b/boards/esp32-odroid.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "odroid_esp32", - "partitions": "esp32_partition_app2944k_fs10M.csv" + "partitions": "partitions/esp32_partition_app2944k_fs10M.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32_16M.json b/boards/esp32_16M.json index 8314fa5b7..df52ebac4 100644 --- a/boards/esp32_16M.json +++ b/boards/esp32_16M.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "esp32", - "partitions": "esp32_partition_app2944k_fs10M.csv" + "partitions": "partitions/esp32_partition_app2944k_fs10M.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32_4M.json b/boards/esp32_4M.json index 4821878f7..c4875e1bd 100644 --- a/boards/esp32_4M.json +++ b/boards/esp32_4M.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "esp32", - "partitions": "esp32_partition_app2880k_fs320k.csv" + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32_4M_FS.json b/boards/esp32_4M_FS.json index 30c1fd74f..bc5447ad1 100644 --- a/boards/esp32_4M_FS.json +++ b/boards/esp32_4M_FS.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "esp32", - "partitions": "esp32_partition_app1856k_fs1344k.csv" + "partitions": "partitions/esp32_partition_app1856k_fs1344k.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32_8M.json b/boards/esp32_8M.json index cca93e38d..5a7842f75 100644 --- a/boards/esp32_8M.json +++ b/boards/esp32_8M.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "esp32", - "partitions": "esp32_partition_app2944k_fs2M.csv" + "partitions": "partitions/esp32_partition_app2944k_fs2M.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32_solo1_4M.json b/boards/esp32_solo1_4M.json index d95940d68..6a7d9ed44 100644 --- a/boards/esp32_solo1_4M.json +++ b/boards/esp32_solo1_4M.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32", "variant": "esp32", - "partitions": "esp32_partition_app2880k_fs320k.csv" + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32c3.json b/boards/esp32c3.json index f5e7321e4..c1fceed9a 100644 --- a/boards/esp32c3.json +++ b/boards/esp32c3.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32c3", "variant": "esp32c3", - "partitions": "esp32_partition_app2880k_fs320k.csv" + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" }, "connectivity": [ "wifi" diff --git a/boards/esp32c3usb.json b/boards/esp32c3usb.json new file mode 100644 index 000000000..5ce1f4a67 --- /dev/null +++ b/boards/esp32c3usb.json @@ -0,0 +1,43 @@ +{ + "build": { + "arduino":{ + "ldscript": "esp32c3_out.ld" + }, + "core": "esp32", + "extra_flags": "-DARDUINO_USB_MODE=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DESP32_4M -DESP32C3 -DUSE_USB_SERIAL_CONSOLE", + "f_cpu": "160000000L", + "f_flash": "80000000L", + "flash_mode": "dout", + "mcu": "esp32c3", + "variant": "esp32c3", + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" + }, + "connectivity": [ + "wifi" + ], + "debug": { + "openocd_target": "esp32c3.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-C3 4M Flash, Tasmota 2880k Code/OTA, 320k FS", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "variants/tasmota/tasmota32c3usb-safeboot.bin" + ] + ] + }, + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/hw-reference/esp32c3/user-guide-devkitm-1.html", + "vendor": "Espressif" + } diff --git a/boards/esp32s2.json b/boards/esp32s2.json index 7f48731af..4077ee33d 100644 --- a/boards/esp32s2.json +++ b/boards/esp32s2.json @@ -10,7 +10,7 @@ "flash_mode": "dout", "mcu": "esp32s2", "variant": "esp32s2", - "partitions": "esp32_partition_app2880k_fs320k.csv" + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" }, "connectivity": [ "wifi" diff --git a/boards/esp32s3.json b/boards/esp32s3.json index a86ea38f9..e2d61eada 100644 --- a/boards/esp32s3.json +++ b/boards/esp32s3.json @@ -11,7 +11,7 @@ "flash_mode": "dio", "mcu": "esp32s3", "variant": "esp32s3", - "partitions": "esp32_partition_app2880k_fs320k.csv" + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" }, "connectivity": [ "wifi", diff --git a/boards/esp32s3_8M.json b/boards/esp32s3_8M.json index affbb0479..d0c15a19f 100644 --- a/boards/esp32s3_8M.json +++ b/boards/esp32s3_8M.json @@ -11,7 +11,7 @@ "flash_mode": "dio", "mcu": "esp32s3", "variant": "esp32s3", - "partitions": "esp32_partition_app2944k_fs2M.csv" + "partitions": "partitions/esp32_partition_app2944k_fs2M.csv" }, "connectivity": [ "wifi", diff --git a/lib/lib_audio/ESP8266Audio/tasmota_lib_changes.md b/lib/lib_audio/ESP8266Audio/tasmota_lib_changes.md index bea02c652..6177f9d7d 100644 --- a/lib/lib_audio/ESP8266Audio/tasmota_lib_changes.md +++ b/lib/lib_audio/ESP8266Audio/tasmota_lib_changes.md @@ -13,6 +13,13 @@ remove in file `lib/lib_audio/ESP8266Audio/src/AudioFileSourceFS.cpp` #endif ``` +add in file `lib/lib_audio/ESP8266Audio/src/spiram-fast.h` +``` +#ifndef SPECIAL +#define SPECIAL 0xF0 +#endif +``` + Files to delete: ``` lib/lib_audio/ESP8266Audio/src/AudioFileSourceSPIFFS.h diff --git a/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.cpp b/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.cpp index 694502ea5..a3c798f1c 100644 --- a/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.cpp +++ b/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.cpp @@ -117,7 +117,7 @@ String HTTPUpdateLight::getLastErrorString(void) // error from Update class if(_lastError > 0) { StreamString error; - Update.printError(error); + TasUpdate.printError(error); error.trim(); // remove line ending return String("Update error: ") + error; } @@ -418,14 +418,17 @@ bool HTTPUpdateLight::runUpdate(Stream& in, uint32_t size, String md5, int comma StreamString error; if (_cbProgress) { - Update.onProgress(_cbProgress); + TasUpdate.onProgress(_cbProgress); } - if(!Update.begin(size, command, _ledPin, _ledOn)) { - _lastError = Update.getError(); - Update.printError(error); +// Start Tasmota Factory patch +// if(!Update.begin(size, command, _ledPin, _ledOn)) { + if(!TasUpdate.begin(size, command, _ledPin, _ledOn, NULL, _factory)) { +// End Tasmota Factory patch + _lastError = TasUpdate.getError(); + TasUpdate.printError(error); error.trim(); // remove line ending - log_e("Update.begin failed! (%s)\n", error.c_str()); + log_e("TasUpdate.begin failed! (%s)\n", error.c_str()); return false; } @@ -434,20 +437,20 @@ bool HTTPUpdateLight::runUpdate(Stream& in, uint32_t size, String md5, int comma } if(md5.length()) { - if(!Update.setMD5(md5.c_str())) { + if(!TasUpdate.setMD5(md5.c_str())) { _lastError = HTTP_UE_SERVER_FAULTY_MD5; - log_e("Update.setMD5 failed! (%s)\n", md5.c_str()); + log_e("TasUpdate.setMD5 failed! (%s)\n", md5.c_str()); return false; } } // To do: the SHA256 could be checked if the server sends it - if(Update.writeStream(in) != size) { - _lastError = Update.getError(); - Update.printError(error); + if(TasUpdate.writeStream(in) != size) { + _lastError = TasUpdate.getError(); + TasUpdate.printError(error); error.trim(); // remove line ending - log_e("Update.writeStream failed! (%s)\n", error.c_str()); + log_e("TasUpdate.writeStream failed! (%s)\n", error.c_str()); return false; } @@ -455,11 +458,11 @@ bool HTTPUpdateLight::runUpdate(Stream& in, uint32_t size, String md5, int comma _cbProgress(size, size); } - if(!Update.end()) { - _lastError = Update.getError(); - Update.printError(error); + if(!TasUpdate.end()) { + _lastError = TasUpdate.getError(); + TasUpdate.printError(error); error.trim(); // remove line ending - log_e("Update.end failed! (%s)\n", error.c_str()); + log_e("TasUpdate.end failed! (%s)\n", error.c_str()); return false; } diff --git a/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.h b/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.h index cbed38bd6..372f9f1b0 100644 --- a/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.h +++ b/lib/libesp32/Berry-HttpClientLight/src/HTTPUpdateLight.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include /// note we use HTTP client errors too so we start at 100 @@ -69,7 +69,7 @@ public: { _rebootOnUpdate = reboot; } - + /** * set redirect follow mode. See `followRedirects_t` enum for avaliable modes. * @param follow @@ -85,6 +85,13 @@ public: _ledOn = ledOn; } +// Start Tasmota Factory patch + void setFactory(bool factory = false) + { + _factory = factory; + } +// End Tasmota Factory patch + // t_httpUpdate_return update(WiFiClient& client, const String& url, const String& currentVersion = ""); // t_httpUpdate_return update(WiFiClient& client, const String& host, uint16_t port, const String& uri = "/", @@ -131,6 +138,9 @@ private: int _ledPin; uint8_t _ledOn; +// Start Tasmota Factory patch + bool _factory; +// End Tasmota Factory patch }; #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_HTTPUPDATE) diff --git a/lib/libesp32/Berry-HttpClientLight/src/TasUpdate.h b/lib/libesp32/Berry-HttpClientLight/src/TasUpdate.h new file mode 100644 index 000000000..0aaac13b3 --- /dev/null +++ b/lib/libesp32/Berry-HttpClientLight/src/TasUpdate.h @@ -0,0 +1,194 @@ +#ifndef TASUPDATER_H +#define TASUPDATER_H + +#include +#include +#include +#include "esp_partition.h" + +#define UPDATE_ERROR_OK (0) +#define UPDATE_ERROR_WRITE (1) +#define UPDATE_ERROR_ERASE (2) +#define UPDATE_ERROR_READ (3) +#define UPDATE_ERROR_SPACE (4) +#define UPDATE_ERROR_SIZE (5) +#define UPDATE_ERROR_STREAM (6) +#define UPDATE_ERROR_MD5 (7) +#define UPDATE_ERROR_MAGIC_BYTE (8) +#define UPDATE_ERROR_ACTIVATE (9) +#define UPDATE_ERROR_NO_PARTITION (10) +#define UPDATE_ERROR_BAD_ARGUMENT (11) +#define UPDATE_ERROR_ABORT (12) + +#define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF + +#define U_FLASH 0 +#define U_SPIFFS 100 +#define U_AUTH 200 + +#define ENCRYPTED_BLOCK_SIZE 16 + +class TasUpdateClass { + public: + typedef std::function THandlerFunction_Progress; + + TasUpdateClass(); + + /* + This callback will be called when Update is receiving data + */ + TasUpdateClass& onProgress(THandlerFunction_Progress fn); + + /* + Call this to check the space needed for the update + Will return false if there is not enough space + */ +// Start Tasmota Factory patch +// bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL); + bool begin(size_t size=UPDATE_SIZE_UNKNOWN, int command = U_FLASH, int ledPin = -1, uint8_t ledOn = LOW, const char *label = NULL, bool factory = false); +// End Tasmota Factory patch + + /* + Writes a buffer to the flash and increments the address + Returns the amount written + */ + size_t write(uint8_t *data, size_t len); + + /* + Writes the remaining bytes from the Stream to the flash + Uses readBytes() and sets UPDATE_ERROR_STREAM on timeout + Returns the bytes written + Should be equal to the remaining bytes when called + Usable for slow streams like Serial + */ + size_t writeStream(Stream &data); + + /* + If all bytes are written + this call will write the config to eboot + and return true + If there is already an update running but is not finished and !evenIfRemaining + or there is an error + this will clear everything and return false + the last error is available through getError() + evenIfRemaining is helpfull when you update without knowing the final size first + */ + bool end(bool evenIfRemaining = false); + + /* + Aborts the running update + */ + void abort(); + + /* + Prints the last error to an output stream + */ + void printError(Print &out); + + const char * errorString(); + + /* + sets the expected MD5 for the firmware (hexString) + */ + bool setMD5(const char * expected_md5); + + /* + returns the MD5 String of the successfully ended firmware + */ + String md5String(void){ return _md5.toString(); } + + /* + populated the result with the md5 bytes of the successfully ended firmware + */ + void md5(uint8_t * result){ return _md5.getBytes(result); } + + //Helpers + uint8_t getError(){ return _error; } + void clearError(){ _error = UPDATE_ERROR_OK; } + bool hasError(){ return _error != UPDATE_ERROR_OK; } + bool isRunning(){ return _size > 0; } + bool isFinished(){ return _progress == _size; } + size_t size(){ return _size; } + size_t progress(){ return _progress; } + size_t remaining(){ return _size - _progress; } + + /* + Template to write from objects that expose + available() and read(uint8_t*, size_t) methods + faster than the writeStream method + writes only what is available + */ + template + size_t write(T &data){ + size_t written = 0; + if (hasError() || !isRunning()) + return 0; + + size_t available = data.available(); + while(available) { + if(_bufferLen + available > remaining()){ + available = remaining() - _bufferLen; + } + if(_bufferLen + available > 4096) { + size_t toBuff = 4096 - _bufferLen; + data.read(_buffer + _bufferLen, toBuff); + _bufferLen += toBuff; + if(!_writeBuffer()) + return written; + written += toBuff; + } else { + data.read(_buffer + _bufferLen, available); + _bufferLen += available; + written += available; + if(_bufferLen == remaining()) { + if(!_writeBuffer()) { + return written; + } + } + } + if(remaining() == 0) + return written; + available = data.available(); + } + return written; + } + + /* + check if there is a firmware on the other OTA partition that you can bootinto + */ + bool canRollBack(); + /* + set the other OTA partition as bootable (reboot to enable) + */ + bool rollBack(); + + private: + void _reset(); + void _abort(uint8_t err); + bool _writeBuffer(); + bool _verifyHeader(uint8_t data); + bool _verifyEnd(); + bool _enablePartition(const esp_partition_t* partition); + + + uint8_t _error; + uint8_t *_buffer; + uint8_t *_skipBuffer; + size_t _bufferLen; + size_t _size; + THandlerFunction_Progress _progress_callback; + uint32_t _progress; + uint32_t _paroffset; + uint32_t _command; + const esp_partition_t* _partition; + + String _target_md5; + MD5Builder _md5; + + int _ledPin; + uint8_t _ledOn; +}; + +extern TasUpdateClass TasUpdate; + +#endif // TASUPDATER_H diff --git a/lib/libesp32/Berry-HttpClientLight/src/TasUpdater.cpp b/lib/libesp32/Berry-HttpClientLight/src/TasUpdater.cpp new file mode 100644 index 000000000..e359ff96f --- /dev/null +++ b/lib/libesp32/Berry-HttpClientLight/src/TasUpdater.cpp @@ -0,0 +1,404 @@ +#include "TasUpdate.h" +#include "Arduino.h" +#include "esp_spi_flash.h" +#include "esp_ota_ops.h" +#include "esp_image_format.h" + +static const char * _err2str(uint8_t _error){ + if(_error == UPDATE_ERROR_OK){ + return ("No Error"); + } else if(_error == UPDATE_ERROR_WRITE){ + return ("Flash Write Failed"); + } else if(_error == UPDATE_ERROR_ERASE){ + return ("Flash Erase Failed"); + } else if(_error == UPDATE_ERROR_READ){ + return ("Flash Read Failed"); + } else if(_error == UPDATE_ERROR_SPACE){ + return ("Not Enough Space"); + } else if(_error == UPDATE_ERROR_SIZE){ + return ("Bad Size Given"); + } else if(_error == UPDATE_ERROR_STREAM){ + return ("Stream Read Timeout"); + } else if(_error == UPDATE_ERROR_MD5){ + return ("MD5 Check Failed"); + } else if(_error == UPDATE_ERROR_MAGIC_BYTE){ + return ("Wrong Magic Byte"); + } else if(_error == UPDATE_ERROR_ACTIVATE){ + return ("Could Not Activate The Firmware"); + } else if(_error == UPDATE_ERROR_NO_PARTITION){ + return ("Partition Could Not be Found"); + } else if(_error == UPDATE_ERROR_BAD_ARGUMENT){ + return ("Bad Argument"); + } else if(_error == UPDATE_ERROR_ABORT){ + return ("Aborted"); + } + return ("UNKNOWN"); +} + +static bool _partitionIsBootable(const esp_partition_t* partition){ + uint8_t buf[ENCRYPTED_BLOCK_SIZE]; + if(!partition){ + return false; + } + if(!ESP.partitionRead(partition, 0, (uint32_t*)buf, ENCRYPTED_BLOCK_SIZE)) { + return false; + } + + if(buf[0] != ESP_IMAGE_HEADER_MAGIC) { + return false; + } + return true; +} + +bool TasUpdateClass::_enablePartition(const esp_partition_t* partition){ + if(!partition){ + return false; + } + return ESP.partitionWrite(partition, 0, (uint32_t*) _skipBuffer, ENCRYPTED_BLOCK_SIZE); +} + +TasUpdateClass::TasUpdateClass() +: _error(0) +, _buffer(0) +, _bufferLen(0) +, _size(0) +, _progress_callback(NULL) +, _progress(0) +, _paroffset(0) +, _command(U_FLASH) +, _partition(NULL) +{ +} + +TasUpdateClass& TasUpdateClass::onProgress(THandlerFunction_Progress fn) { + _progress_callback = fn; + return *this; +} + +void TasUpdateClass::_reset() { + if (_buffer) + delete[] _buffer; + _buffer = 0; + _bufferLen = 0; + _progress = 0; + _size = 0; + _command = U_FLASH; + + if(_ledPin != -1) { + digitalWrite(_ledPin, !_ledOn); // off + } +} + +bool TasUpdateClass::canRollBack(){ + if(_buffer){ //Update is running + return false; + } + const esp_partition_t* partition = esp_ota_get_next_update_partition(NULL); + return _partitionIsBootable(partition); +} + +bool TasUpdateClass::rollBack(){ + if(_buffer){ //Update is running + return false; + } + const esp_partition_t* partition = esp_ota_get_next_update_partition(NULL); + return _partitionIsBootable(partition) && !esp_ota_set_boot_partition(partition); +} + +// Start Tasmota Factory patch +//bool UpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, const char *label) { +bool TasUpdateClass::begin(size_t size, int command, int ledPin, uint8_t ledOn, const char *label, bool factory) { +// End Tasmota Factory patch + if(_size > 0){ + log_w("already running"); + return false; + } + + _ledPin = ledPin; + _ledOn = !!ledOn; // 0(LOW) or 1(HIGH) + + _reset(); + _error = 0; + _target_md5 = emptyString; + _md5 = MD5Builder(); + + if(size == 0) { + _error = UPDATE_ERROR_SIZE; + return false; + } + + if (command == U_FLASH) { +// Start Tasmota Factory patch +// _partition = esp_ota_get_next_update_partition(NULL); + if (factory) { + _partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL); + } else { + _partition = esp_ota_get_next_update_partition(NULL); + } +// End Tasmota Factory patch + if(!_partition){ + _error = UPDATE_ERROR_NO_PARTITION; + return false; + } + log_d("OTA Partition: %s", _partition->label); + } + else if (command == U_SPIFFS) { + _partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, label); + _paroffset = 0; + if(!_partition){ + _partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, NULL); + _paroffset = 0x1000; //Offset for ffat, assuming size is already corrected + if(!_partition){ + _error = UPDATE_ERROR_NO_PARTITION; + return false; + } + } + } + else { + _error = UPDATE_ERROR_BAD_ARGUMENT; + log_e("bad command %u", command); + return false; + } + + if(size == UPDATE_SIZE_UNKNOWN){ + size = _partition->size; + } else if(size > _partition->size){ + _error = UPDATE_ERROR_SIZE; + log_e("too large %u > %u", size, _partition->size); + return false; + } + + //initialize + _buffer = (uint8_t*)malloc(SPI_FLASH_SEC_SIZE); + if(!_buffer){ + log_e("malloc failed"); + return false; + } + _size = size; + _command = command; + _md5.begin(); + return true; +} + +void TasUpdateClass::_abort(uint8_t err){ + _reset(); + _error = err; +} + +void TasUpdateClass::abort(){ + _abort(UPDATE_ERROR_ABORT); +} + +bool TasUpdateClass::_writeBuffer(){ + //first bytes of new firmware + uint8_t skip = 0; + if(!_progress && _command == U_FLASH){ + //check magic + if(_buffer[0] != ESP_IMAGE_HEADER_MAGIC){ + _abort(UPDATE_ERROR_MAGIC_BYTE); + return false; + } + + //Stash the first 16 bytes of data and set the offset so they are + //not written at this point so that partially written firmware + //will not be bootable + skip = ENCRYPTED_BLOCK_SIZE; + _skipBuffer = (uint8_t*)malloc(skip); + if(!_skipBuffer){ + log_e("malloc failed"); + return false; + } + memcpy(_skipBuffer, _buffer, skip); + } + if (!_progress && _progress_callback) { + _progress_callback(0, _size); + } + if(!ESP.partitionEraseRange(_partition, _progress, SPI_FLASH_SEC_SIZE)){ + _abort(UPDATE_ERROR_ERASE); + return false; + } + if (!ESP.partitionWrite(_partition, _progress + skip, (uint32_t*)_buffer + skip/sizeof(uint32_t), _bufferLen - skip)) { + _abort(UPDATE_ERROR_WRITE); + return false; + } + //restore magic or md5 will fail + if(!_progress && _command == U_FLASH){ + _buffer[0] = ESP_IMAGE_HEADER_MAGIC; + } + _md5.add(_buffer, _bufferLen); + _progress += _bufferLen; + _bufferLen = 0; + if (_progress_callback) { + _progress_callback(_progress, _size); + } + return true; +} + +bool TasUpdateClass::_verifyHeader(uint8_t data) { + if(_command == U_FLASH) { + if(data != ESP_IMAGE_HEADER_MAGIC) { + _abort(UPDATE_ERROR_MAGIC_BYTE); + return false; + } + return true; + } else if(_command == U_SPIFFS) { + return true; + } + return false; +} + +bool TasUpdateClass::_verifyEnd() { + if(_command == U_FLASH) { + if(!_enablePartition(_partition) || !_partitionIsBootable(_partition)) { + _abort(UPDATE_ERROR_READ); + return false; + } + + if(esp_ota_set_boot_partition(_partition)){ + _abort(UPDATE_ERROR_ACTIVATE); + return false; + } + _reset(); + return true; + } else if(_command == U_SPIFFS) { + _reset(); + return true; + } + return false; +} + +bool TasUpdateClass::setMD5(const char * expected_md5){ + if(strlen(expected_md5) != 32) + { + return false; + } + _target_md5 = expected_md5; + return true; +} + +bool TasUpdateClass::end(bool evenIfRemaining){ + if(hasError() || _size == 0){ + return false; + } + + if(!isFinished() && !evenIfRemaining){ + log_e("premature end: res:%u, pos:%u/%u\n", getError(), progress(), _size); + _abort(UPDATE_ERROR_ABORT); + return false; + } + + if(evenIfRemaining) { + if(_bufferLen > 0) { + _writeBuffer(); + } + _size = progress(); + } + + _md5.calculate(); + if(_target_md5.length()) { + if(_target_md5 != _md5.toString()){ + _abort(UPDATE_ERROR_MD5); + return false; + } + } + + return _verifyEnd(); +} + +size_t TasUpdateClass::write(uint8_t *data, size_t len) { + if(hasError() || !isRunning()){ + return 0; + } + + if(len > remaining()){ + _abort(UPDATE_ERROR_SPACE); + return 0; + } + + size_t left = len; + + while((_bufferLen + left) > SPI_FLASH_SEC_SIZE) { + size_t toBuff = SPI_FLASH_SEC_SIZE - _bufferLen; + memcpy(_buffer + _bufferLen, data + (len - left), toBuff); + _bufferLen += toBuff; + if(!_writeBuffer()){ + return len - left; + } + left -= toBuff; + } + memcpy(_buffer + _bufferLen, data + (len - left), left); + _bufferLen += left; + if(_bufferLen == remaining()){ + if(!_writeBuffer()){ + return len - left; + } + } + return len; +} + +size_t TasUpdateClass::writeStream(Stream &data) { + size_t written = 0; + size_t toRead = 0; + int timeout_failures = 0; + + if(hasError() || !isRunning()) + return 0; + + if(!_verifyHeader(data.peek())) { + _reset(); + return 0; + } + + if(_ledPin != -1) { + pinMode(_ledPin, OUTPUT); + } + + while(remaining()) { + if(_ledPin != -1) { + digitalWrite(_ledPin, _ledOn); // Switch LED on + } + size_t bytesToRead = SPI_FLASH_SEC_SIZE - _bufferLen; + if(bytesToRead > remaining()) { + bytesToRead = remaining(); + } + + /* + Init read&timeout counters and try to read, if read failed, increase counter, + wait 100ms and try to read again. If counter > 300 (30 sec), give up/abort + */ + toRead = 0; + timeout_failures = 0; + while(!toRead) { + toRead = data.readBytes(_buffer + _bufferLen, bytesToRead); + if(toRead == 0) { + timeout_failures++; + if (timeout_failures >= 300) { + _abort(UPDATE_ERROR_STREAM); + return written; + } + delay(100); + } + } + + if(_ledPin != -1) { + digitalWrite(_ledPin, !_ledOn); // Switch LED off + } + _bufferLen += toRead; + if((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer()) + return written; + written += toRead; + + delay(1); // Fix solo WDT + } + return written; +} + +void TasUpdateClass::printError(Print &out){ + out.println(_err2str(_error)); +} + +const char * TasUpdateClass::errorString(){ + return _err2str(_error); +} + +TasUpdateClass TasUpdate; diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index 59c63801a..a4c6a602e 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -45,7 +45,6 @@ extern void analogWritePhase(uint8_t pin, uint32_t duty, uint32_t phase = 0); #define ETS_UART_INTR_ENABLE() #define ESPhttpUpdate httpUpdate -#define getFlashChipRealSize() getFlashChipSize() #define os_delay_us ets_delay_us // Serial minimal type to hold the config diff --git a/lib/libesp32/berry/generate/be_const_strtab.h b/lib/libesp32/berry/generate/be_const_strtab.h index 0a503c031..d9cdc2394 100644 --- a/lib/libesp32/berry/generate/be_const_strtab.h +++ b/lib/libesp32/berry/generate/be_const_strtab.h @@ -788,7 +788,6 @@ extern const bcstring be_const_str_return; extern const bcstring be_const_str_return_X20code_X3D_X25i; extern const bcstring be_const_str_reverse; extern const bcstring be_const_str_reverse_gamma10; -extern const bcstring be_const_str_rollback; extern const bcstring be_const_str_rotate; extern const bcstring be_const_str_round_end; extern const bcstring be_const_str_round_start; diff --git a/lib/libesp32/berry/generate/be_const_strtab_def.h b/lib/libesp32/berry/generate/be_const_strtab_def.h index ece302842..a2d290c79 100644 --- a/lib/libesp32/berry/generate/be_const_strtab_def.h +++ b/lib/libesp32/berry/generate/be_const_strtab_def.h @@ -607,7 +607,7 @@ be_define_const_str(length_X20in_X20bits_X20must_X20be_X20between_X200_X20and_X2 be_define_const_str(light, "light", 3801947695u, 0, 5, &be_const_str_set_ldo_voltage); be_define_const_str(light_X20must_X20be_X20of_X20class_X20_X27light_state_X27, "light must be of class 'light_state'", 3669350396u, 0, 36, &be_const_str_read_sensors); be_define_const_str(light_state, "light_state", 905783845u, 0, 11, &be_const_str_lv_wifi_bars_icon); -be_define_const_str(light_to_id, "light_to_id", 1117015647u, 0, 11, &be_const_str_rollback); +be_define_const_str(light_to_id, "light_to_id", 1117015647u, 0, 11, NULL); be_define_const_str(lights, "lights", 425118420u, 0, 6, &be_const_str_set_size); be_define_const_str(line_dsc, "line_dsc", 4094490978u, 0, 8, &be_const_str_try_run_compiled); be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_set_MAC); @@ -780,7 +780,6 @@ be_define_const_str(return, "return", 2246981567u, 60, 6, NULL); be_define_const_str(return_X20code_X3D_X25i, "return code=%i", 2127454401u, 0, 14, &be_const_str_write_bit); be_define_const_str(reverse, "reverse", 558918661u, 0, 7, &be_const_str_sin); be_define_const_str(reverse_gamma10, "reverse_gamma10", 739112262u, 0, 15, NULL); -be_define_const_str(rollback, "rollback", 2093668477u, 0, 8, NULL); be_define_const_str(rotate, "rotate", 2784296202u, 0, 6, &be_const_str_set_active); be_define_const_str(round_end, "round_end", 985288225u, 0, 9, NULL); be_define_const_str(round_start, "round_start", 2949484384u, 0, 11, &be_const_str_tolower); @@ -1543,6 +1542,6 @@ static const bstring* const m_string_table[] = { static const struct bconststrtab m_const_string_table = { .size = 505, - .count = 1034, + .count = 1033, .table = m_string_table }; diff --git a/lib/libesp32/berry_mapping/src/be_class_wrapper.c b/lib/libesp32/berry_mapping/src/be_class_wrapper.c index 2591477ce..a1f6502bb 100644 --- a/lib/libesp32/berry_mapping/src/be_class_wrapper.c +++ b/lib/libesp32/berry_mapping/src/be_class_wrapper.c @@ -222,6 +222,7 @@ intptr_t be_convert_single_elt(bvm *vm, int idx, const char * arg_type, int *buf type_ok = (arg_type[0] == '.'); // any type is accepted type_ok = type_ok || (arg_type[0] == provided_type && arg_type[1] == 0); // or type is a match (single char only) type_ok = type_ok || (ret == 0 && arg_type_len != 1); // or NULL is accepted for an instance + type_ok = type_ok || (ret == 0 && arg_type[0] == 's' && arg_type[1] == 0); // accept nil for string, can be dangerous if (!type_ok) { be_raisef(vm, "type_error", "Unexpected argument type '%c', expected '%s'", provided_type, arg_type); diff --git a/lib/libesp32/berry_tasmota/src/be_lv_openhasp.c b/lib/libesp32/berry_tasmota/src/be_lv_openhasp.c index 97924f0dc..1f82d2643 100644 --- a/lib/libesp32/berry_tasmota/src/be_lv_openhasp.c +++ b/lib/libesp32/berry_tasmota/src/be_lv_openhasp.c @@ -465,11 +465,55 @@ void be_load_lvh_page_class(bvm *vm) { } /******************************************************************** -** Solidified function: get_enabled +** Solidified function: set_radius2 ********************************************************************/ -be_local_closure(lvh_obj_get_enabled, /* name */ +be_local_closure(lvh_obj_set_radius2, /* name */ be_nested_proto( - 4, /* nstack */ + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("set_style_radius"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + }), + be_str_literal("set_radius2"), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: register_event_cb +********************************************************************/ +be_local_closure(lvh_obj_register_event_cb, /* name */ + be_nested_proto( + 8, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -477,65 +521,36 @@ be_local_closure(lvh_obj_get_enabled, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("has_flag"), - /* K2 */ be_nested_str_literal("lv"), - /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), - }), - be_str_literal("get_enabled"), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(lvh_obj_init, /* name */ - be_nested_proto( - 8, /* nstack */ - 5, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ + ( &(const bvalue[ 6]) { /* constants */ /* K0 */ be_nested_str_literal("_page"), - /* K1 */ be_nested_str_literal("_lv_class"), - /* K2 */ be_nested_str_literal("_lv_obj"), - /* K3 */ be_nested_str_literal("post_init"), + /* K1 */ be_nested_str_literal("_oh"), + /* K2 */ be_nested_str_literal("_event_map"), + /* K3 */ be_nested_str_literal("keys"), + /* K4 */ be_nested_str_literal("register_event"), + /* K5 */ be_nested_str_literal("stop_iteration"), }), - be_str_literal("init"), + be_str_literal("register_event_cb"), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x90020002, // 0000 SETMBR R0 K0 R2 - 0x4C140000, // 0001 LDNIL R5 - 0x1C140805, // 0002 EQ R5 R4 R5 - 0x78160007, // 0003 JMPF R5 #000C - 0x88140101, // 0004 GETMBR R5 R0 K1 - 0x78160005, // 0005 JMPF R5 #000C - 0x88140101, // 0006 GETMBR R5 R0 K1 - 0x5C180A00, // 0007 MOVE R6 R5 - 0x5C1C0200, // 0008 MOVE R7 R1 - 0x7C180200, // 0009 CALL R6 1 - 0x90020406, // 000A SETMBR R0 K2 R6 - 0x70020000, // 000B JMP #000D - 0x90020404, // 000C SETMBR R0 K2 R4 - 0x8C140103, // 000D GETMET R5 R0 K3 - 0x7C140200, // 000E CALL R5 1 - 0x80000000, // 000F RET 0 + ( &(const binstruction[19]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x60080010, // 0002 GETGBL R2 G16 + 0x880C0102, // 0003 GETMBR R3 R0 K2 + 0x8C0C0703, // 0004 GETMET R3 R3 K3 + 0x7C0C0200, // 0005 CALL R3 1 + 0x7C080200, // 0006 CALL R2 1 + 0xA8020006, // 0007 EXBLK 0 #000F + 0x5C0C0400, // 0008 MOVE R3 R2 + 0x7C0C0000, // 0009 CALL R3 0 + 0x8C100304, // 000A GETMET R4 R1 K4 + 0x5C180000, // 000B MOVE R6 R0 + 0x5C1C0600, // 000C MOVE R7 R3 + 0x7C100600, // 000D CALL R4 3 + 0x7001FFF8, // 000E JMP #0008 + 0x58080005, // 000F LDCONST R2 K5 + 0xAC080200, // 0010 CATCH R2 1 0 + 0xB0080000, // 0011 RAISE 2 R0 R0 + 0x80000000, // 0012 RET 0 }) ) ); @@ -543,9 +558,9 @@ be_local_closure(lvh_obj_init, /* name */ /******************************************************************** -** Solidified function: get_value_color +** Solidified function: get_value_ofs_x ********************************************************************/ -be_local_closure(lvh_obj_get_value_color, /* name */ +be_local_closure(lvh_obj_get_value_ofs_x, /* name */ be_nested_proto( 3, /* nstack */ 1, /* argc */ @@ -555,560 +570,17 @@ be_local_closure(lvh_obj_get_value_color, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("get_value_color"), + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_label"), + /* K1 */ be_nested_str_literal("get_x"), }), - be_str_literal("get_value_color"), - &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_click -********************************************************************/ -be_local_closure(lvh_obj_set_click, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("set_enabled"), - }), - be_str_literal("set_click"), + be_str_literal("get_value_ofs_x"), &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_text_rule -********************************************************************/ -be_local_closure(lvh_obj_get_text_rule, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_text_rule"), - }), - be_str_literal("get_text_rule"), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_hidden -********************************************************************/ -be_local_closure(lvh_obj_set_hidden, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("add_flag"), - /* K2 */ be_nested_str_literal("lv"), - /* K3 */ be_nested_str_literal("OBJ_FLAG_HIDDEN"), - /* K4 */ be_nested_str_literal("clear_flag"), - }), - be_str_literal("set_hidden"), - &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x78060005, // 0000 JMPF R1 #0007 - 0x88080100, // 0001 GETMBR R2 R0 K0 - 0x8C080501, // 0002 GETMET R2 R2 K1 - 0xB8120400, // 0003 GETNGBL R4 K2 - 0x88100903, // 0004 GETMBR R4 R4 K3 - 0x7C080400, // 0005 CALL R2 2 - 0x70020004, // 0006 JMP #000C - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080504, // 0008 GETMET R2 R2 K4 - 0xB8120400, // 0009 GETNGBL R4 K2 - 0x88100903, // 000A GETMBR R4 R4 K3 - 0x7C080400, // 000B CALL R2 2 - 0x80000000, // 000C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_text_rule_formula -********************************************************************/ -be_local_closure(lvh_obj_get_text_rule_formula, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_text_rule_formula"), - }), - be_str_literal("get_text_rule_formula"), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_pad_all2 -********************************************************************/ -be_local_closure(lvh_obj_set_pad_all2, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("set_style_pad_all"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("set_pad_all2"), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: text_rule_matched -********************************************************************/ -be_local_closure(lvh_obj_text_rule_matched, /* name */ - be_nested_proto( - 12, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 8]) { /* constants */ - /* K0 */ be_nested_str_literal("int"), - /* K1 */ be_nested_str_literal("_text_rule_function"), - /* K2 */ be_nested_str_literal("string"), - /* K3 */ be_nested_str_literal("format"), - /* K4 */ be_nested_str_literal("HSP: failed to run self._text_rule_function - %s (%s)"), - /* K5 */ be_nested_str_literal("_text_rule_format"), - /* K6 */ be_nested_str_literal(""), - /* K7 */ be_nested_str_literal("text"), - }), - be_str_literal("text_rule_matched"), - &be_const_str_solidified, - ( &(const binstruction[49]) { /* code */ - 0x60080004, // 0000 GETGBL R2 G4 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x1C080500, // 0003 EQ R2 R2 K0 - 0x780A0003, // 0004 JMPF R2 #0009 - 0x6008000A, // 0005 GETGBL R2 G10 - 0x5C0C0200, // 0006 MOVE R3 R1 - 0x7C080200, // 0007 CALL R2 1 - 0x5C040400, // 0008 MOVE R1 R2 - 0x88080101, // 0009 GETMBR R2 R0 K1 - 0x4C0C0000, // 000A LDNIL R3 - 0x200C0403, // 000B NE R3 R2 R3 - 0x780E0012, // 000C JMPF R3 #0020 - 0xA8020005, // 000D EXBLK 0 #0014 - 0x5C0C0400, // 000E MOVE R3 R2 - 0x5C100200, // 000F MOVE R4 R1 - 0x7C0C0200, // 0010 CALL R3 1 - 0x5C040600, // 0011 MOVE R1 R3 - 0xA8040001, // 0012 EXBLK 1 1 - 0x7002000B, // 0013 JMP #0020 - 0xAC0C0002, // 0014 CATCH R3 0 2 - 0x70020008, // 0015 JMP #001F - 0xA4160400, // 0016 IMPORT R5 K2 - 0x60180001, // 0017 GETGBL R6 G1 - 0x8C1C0B03, // 0018 GETMET R7 R5 K3 - 0x58240004, // 0019 LDCONST R9 K4 - 0x5C280600, // 001A MOVE R10 R3 - 0x5C2C0800, // 001B MOVE R11 R4 - 0x7C1C0800, // 001C CALL R7 4 - 0x7C180200, // 001D CALL R6 1 - 0x70020000, // 001E JMP #0020 - 0xB0080000, // 001F RAISE 2 R0 R0 - 0x880C0105, // 0020 GETMBR R3 R0 K5 - 0x60100004, // 0021 GETGBL R4 G4 - 0x5C140600, // 0022 MOVE R5 R3 - 0x7C100200, // 0023 CALL R4 1 - 0x1C100902, // 0024 EQ R4 R4 K2 - 0x78120006, // 0025 JMPF R4 #002D - 0xA4120400, // 0026 IMPORT R4 K2 - 0x8C140903, // 0027 GETMET R5 R4 K3 - 0x5C1C0600, // 0028 MOVE R7 R3 - 0x5C200200, // 0029 MOVE R8 R1 - 0x7C140600, // 002A CALL R5 3 - 0x5C0C0A00, // 002B MOVE R3 R5 - 0x70020000, // 002C JMP #002E - 0x580C0006, // 002D LDCONST R3 K6 - 0x90020E03, // 002E SETMBR R0 K7 R3 - 0x50100000, // 002F LDBOOL R4 0 0 - 0x80040800, // 0030 RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_pad_left2 -********************************************************************/ -be_local_closure(lvh_obj_set_pad_left2, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("set_style_pad_left"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("set_pad_left2"), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: setmember -********************************************************************/ -be_local_closure(lvh_obj_setmember, /* name */ - be_nested_proto( - 11, /* nstack */ - 3, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[16]) { /* constants */ - /* K0 */ be_nested_str_literal("_attr_ignore"), - /* K1 */ be_nested_str_literal("find"), - /* K2 */ be_nested_str_literal("_attr_map"), - /* K3 */ be_nested_str_literal("contains"), - /* K4 */ be_nested_str_literal("string"), - /* K5 */ be_nested_str_literal("introspect"), - /* K6 */ be_nested_str_literal("get"), - /* K7 */ be_nested_str_literal("_lv_obj"), - /* K8 */ be_nested_str_literal("set_"), - /* K9 */ be_nested_str_literal("is_color_attribute"), - /* K10 */ be_nested_str_literal("parse_color"), - /* K11 */ be_nested_str_literal("function"), - /* K12 */ be_nested_str_literal("style_"), - /* K13 */ be_const_int(0), - /* K14 */ be_nested_str_literal("HSP: Could not find function set_"), - /* K15 */ be_nested_str_literal("HSP: unknown attribute:"), - }), - be_str_literal("setmember"), - &be_const_str_solidified, - ( &(const binstruction[82]) { /* code */ - 0x880C0100, // 0000 GETMBR R3 R0 K0 - 0x8C0C0701, // 0001 GETMET R3 R3 K1 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C0C0400, // 0003 CALL R3 2 - 0x4C100000, // 0004 LDNIL R4 - 0x200C0604, // 0005 NE R3 R3 R4 - 0x780E0000, // 0006 JMPF R3 #0008 - 0x80000600, // 0007 RET 0 - 0x880C0102, // 0008 GETMBR R3 R0 K2 - 0x8C0C0703, // 0009 GETMET R3 R3 K3 - 0x5C140200, // 000A MOVE R5 R1 - 0x7C0C0400, // 000B CALL R3 2 - 0x780E003F, // 000C JMPF R3 #004D - 0xA40E0800, // 000D IMPORT R3 K4 - 0xA4120A00, // 000E IMPORT R4 K5 - 0x88140102, // 000F GETMBR R5 R0 K2 - 0x94140A01, // 0010 GETIDX R5 R5 R1 - 0x7816002B, // 0011 JMPF R5 #003E - 0x8C180906, // 0012 GETMET R6 R4 K6 - 0x88200107, // 0013 GETMBR R8 R0 K7 - 0x00261005, // 0014 ADD R9 K8 R5 - 0x7C180600, // 0015 CALL R6 3 - 0x601C0004, // 0016 GETGBL R7 G4 - 0x5C200A00, // 0017 MOVE R8 R5 - 0x7C1C0200, // 0018 CALL R7 1 - 0x1C1C0F04, // 0019 EQ R7 R7 K4 - 0x781E0007, // 001A JMPF R7 #0023 - 0x8C1C0109, // 001B GETMET R7 R0 K9 - 0x5C240A00, // 001C MOVE R9 R5 - 0x7C1C0400, // 001D CALL R7 2 - 0x781E0003, // 001E JMPF R7 #0023 - 0x8C1C010A, // 001F GETMET R7 R0 K10 - 0x5C240400, // 0020 MOVE R9 R2 - 0x7C1C0400, // 0021 CALL R7 2 - 0x5C080E00, // 0022 MOVE R2 R7 - 0x601C0004, // 0023 GETGBL R7 G4 - 0x5C200C00, // 0024 MOVE R8 R6 - 0x7C1C0200, // 0025 CALL R7 1 - 0x1C1C0F0B, // 0026 EQ R7 R7 K11 - 0x781E0011, // 0027 JMPF R7 #003A - 0x8C1C0701, // 0028 GETMET R7 R3 K1 - 0x5C240A00, // 0029 MOVE R9 R5 - 0x5828000C, // 002A LDCONST R10 K12 - 0x7C1C0600, // 002B CALL R7 3 - 0x1C1C0F0D, // 002C EQ R7 R7 K13 - 0x781E0005, // 002D JMPF R7 #0034 - 0x5C1C0C00, // 002E MOVE R7 R6 - 0x88200107, // 002F GETMBR R8 R0 K7 - 0x5C240400, // 0030 MOVE R9 R2 - 0x5828000D, // 0031 LDCONST R10 K13 - 0x7C1C0600, // 0032 CALL R7 3 - 0x70020003, // 0033 JMP #0038 - 0x5C1C0C00, // 0034 MOVE R7 R6 - 0x88200107, // 0035 GETMBR R8 R0 K7 - 0x5C240400, // 0036 MOVE R9 R2 - 0x7C1C0400, // 0037 CALL R7 2 - 0x80000E00, // 0038 RET 0 - 0x70020002, // 0039 JMP #003D - 0x601C0001, // 003A GETGBL R7 G1 - 0x00221C05, // 003B ADD R8 K14 R5 - 0x7C1C0200, // 003C CALL R7 1 - 0x7002000D, // 003D JMP #004C - 0x8C180906, // 003E GETMET R6 R4 K6 - 0x5C200000, // 003F MOVE R8 R0 - 0x00261001, // 0040 ADD R9 K8 R1 - 0x7C180600, // 0041 CALL R6 3 - 0x601C0004, // 0042 GETGBL R7 G4 - 0x5C200C00, // 0043 MOVE R8 R6 - 0x7C1C0200, // 0044 CALL R7 1 - 0x1C1C0F0B, // 0045 EQ R7 R7 K11 - 0x781E0004, // 0046 JMPF R7 #004C - 0x5C1C0C00, // 0047 MOVE R7 R6 - 0x5C200000, // 0048 MOVE R8 R0 - 0x5C240400, // 0049 MOVE R9 R2 - 0x7C1C0400, // 004A CALL R7 2 - 0x80000E00, // 004B RET 0 - 0x70020003, // 004C JMP #0051 - 0x600C0001, // 004D GETGBL R3 G1 - 0x5810000F, // 004E LDCONST R4 K15 - 0x5C140200, // 004F MOVE R5 R1 - 0x7C0C0400, // 0050 CALL R3 2 - 0x80000000, // 0051 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_text_color -********************************************************************/ -be_local_closure(lvh_obj_set_text_color, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("set_style_text_color"), - /* K2 */ be_nested_str_literal("parse_color"), - /* K3 */ be_const_int(0), - }), - be_str_literal("set_text_color"), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x8C100102, // 0002 GETMET R4 R0 K2 - 0x5C180200, // 0003 MOVE R6 R1 - 0x7C100400, // 0004 CALL R4 2 - 0x58140003, // 0005 LDCONST R5 K3 - 0x7C080600, // 0006 CALL R2 3 - 0x80000000, // 0007 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_toggle -********************************************************************/ -be_local_closure(lvh_obj_set_toggle, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str_literal("string"), - /* K1 */ be_nested_str_literal("toupper"), - /* K2 */ be_nested_str_literal("TRUE"), - /* K3 */ be_nested_str_literal("FALSE"), - /* K4 */ be_nested_str_literal("_lv_obj"), - /* K5 */ be_nested_str_literal("add_state"), - /* K6 */ be_nested_str_literal("lv"), - /* K7 */ be_nested_str_literal("STATE_CHECKED"), - /* K8 */ be_nested_str_literal("clear_state"), - }), - be_str_literal("set_toggle"), - &be_const_str_solidified, - ( &(const binstruction[26]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x8C0C0501, // 0001 GETMET R3 R2 K1 - 0x60140008, // 0002 GETGBL R5 G8 - 0x5C180200, // 0003 MOVE R6 R1 - 0x7C140200, // 0004 CALL R5 1 - 0x7C0C0400, // 0005 CALL R3 2 - 0x5C040600, // 0006 MOVE R1 R3 - 0x1C0C0302, // 0007 EQ R3 R1 K2 - 0x780E0000, // 0008 JMPF R3 #000A - 0x50040200, // 0009 LDBOOL R1 1 0 - 0x1C0C0303, // 000A EQ R3 R1 K3 - 0x780E0000, // 000B JMPF R3 #000D - 0x50040000, // 000C LDBOOL R1 0 0 - 0x78060005, // 000D JMPF R1 #0014 - 0x880C0104, // 000E GETMBR R3 R0 K4 - 0x8C0C0705, // 000F GETMET R3 R3 K5 - 0xB8160C00, // 0010 GETNGBL R5 K6 - 0x88140B07, // 0011 GETMBR R5 R5 K7 - 0x7C0C0400, // 0012 CALL R3 2 - 0x70020004, // 0013 JMP #0019 - 0x880C0104, // 0014 GETMBR R3 R0 K4 - 0x8C0C0708, // 0015 GETMET R3 R3 K8 - 0xB8160C00, // 0016 GETNGBL R5 K6 - 0x88140B07, // 0017 GETMBR R5 R5 K7 - 0x7C0C0400, // 0018 CALL R3 2 - 0x80000000, // 0019 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_toggle -********************************************************************/ -be_local_closure(lvh_obj_get_toggle, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("has_state"), - /* K2 */ be_nested_str_literal("lv"), - /* K3 */ be_nested_str_literal("STATE_CHECKED"), - }), - be_str_literal("get_toggle"), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 }) ) ); @@ -1116,9 +588,9 @@ be_local_closure(lvh_obj_get_toggle, /* name */ /******************************************************************** -** Solidified function: set_text +** Solidified function: set_value_ofs_x ********************************************************************/ -be_local_closure(lvh_obj_set_text, /* name */ +be_local_closure(lvh_obj_set_value_ofs_x, /* name */ be_nested_proto( 6, /* nstack */ 2, /* argc */ @@ -1131,16 +603,16 @@ be_local_closure(lvh_obj_set_text, /* name */ ( &(const bvalue[ 3]) { /* constants */ /* K0 */ be_nested_str_literal("check_label"), /* K1 */ be_nested_str_literal("_lv_label"), - /* K2 */ be_nested_str_literal("set_text"), + /* K2 */ be_nested_str_literal("set_x"), }), - be_str_literal("set_text"), + be_str_literal("set_value_ofs_x"), &be_const_str_solidified, ( &(const binstruction[ 9]) { /* code */ 0x8C080100, // 0000 GETMET R2 R0 K0 0x7C080200, // 0001 CALL R2 1 0x88080101, // 0002 GETMBR R2 R0 K1 0x8C080502, // 0003 GETMET R2 R2 K2 - 0x60100008, // 0004 GETGBL R4 G8 + 0x60100009, // 0004 GETGBL R4 G9 0x5C140200, // 0005 MOVE R5 R1 0x7C100200, // 0006 CALL R4 1 0x7C080400, // 0007 CALL R2 2 @@ -1151,300 +623,6 @@ be_local_closure(lvh_obj_set_text, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: val_rule_matched -********************************************************************/ -be_local_closure(lvh_obj_val_rule_matched, /* name */ - be_nested_proto( - 13, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_val_rule_function"), - /* K1 */ be_nested_str_literal("string"), - /* K2 */ be_nested_str_literal("format"), - /* K3 */ be_nested_str_literal("HSP: failed to run self._val_rule_function - %s (%s)"), - /* K4 */ be_nested_str_literal("val"), - }), - be_str_literal("val_rule_matched"), - &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ - 0x6008000A, // 0000 GETGBL R2 G10 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x880C0100, // 0003 GETMBR R3 R0 K0 - 0x4C100000, // 0004 LDNIL R4 - 0x20100604, // 0005 NE R4 R3 R4 - 0x78120012, // 0006 JMPF R4 #001A - 0xA8020005, // 0007 EXBLK 0 #000E - 0x5C100600, // 0008 MOVE R4 R3 - 0x5C140400, // 0009 MOVE R5 R2 - 0x7C100200, // 000A CALL R4 1 - 0x5C080800, // 000B MOVE R2 R4 - 0xA8040001, // 000C EXBLK 1 1 - 0x7002000B, // 000D JMP #001A - 0xAC100002, // 000E CATCH R4 0 2 - 0x70020008, // 000F JMP #0019 - 0xA41A0200, // 0010 IMPORT R6 K1 - 0x601C0001, // 0011 GETGBL R7 G1 - 0x8C200D02, // 0012 GETMET R8 R6 K2 - 0x58280003, // 0013 LDCONST R10 K3 - 0x5C2C0800, // 0014 MOVE R11 R4 - 0x5C300A00, // 0015 MOVE R12 R5 - 0x7C200800, // 0016 CALL R8 4 - 0x7C1C0200, // 0017 CALL R7 1 - 0x70020000, // 0018 JMP #001A - 0xB0080000, // 0019 RAISE 2 R0 R0 - 0x60100009, // 001A GETGBL R4 G9 - 0x5C140400, // 001B MOVE R5 R2 - 0x7C100200, // 001C CALL R4 1 - 0x90020804, // 001D SETMBR R0 K4 R4 - 0x50100000, // 001E LDBOOL R4 0 0 - 0x80040800, // 001F RET 1 R4 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_mode -********************************************************************/ -be_local_closure(lvh_obj_get_mode, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_literal("get_mode"), - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_value_str -********************************************************************/ -be_local_closure(lvh_obj_get_value_str, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("get_text"), - }), - be_str_literal("get_value_str"), - &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_pad_bottom2 -********************************************************************/ -be_local_closure(lvh_obj_set_pad_bottom2, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("set_style_pad_bottom"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("set_pad_bottom2"), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_text_rule_format -********************************************************************/ -be_local_closure(lvh_obj_set_text_rule_format, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_text_rule_format"), - }), - be_str_literal("set_text_rule_format"), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_value_font -********************************************************************/ -be_local_closure(lvh_obj_set_value_font, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("set_text_font"), - }), - be_str_literal("set_value_font"), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_text_font -********************************************************************/ -be_local_closure(lvh_obj_get_text_font, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_literal("get_text_font"), - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_action -********************************************************************/ -be_local_closure(lvh_obj_set_action, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_action"), - }), - be_str_literal("set_action"), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x80000000, // 0004 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_pad_all -********************************************************************/ -be_local_closure(lvh_obj_get_pad_all, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 0, /* has constants */ - NULL, /* no const */ - be_str_literal("get_pad_all"), - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: get_radius2 ********************************************************************/ @@ -1488,55 +666,11 @@ be_local_closure(lvh_obj_get_radius2, /* name */ /******************************************************************** -** Solidified function: set_pad_right2 +** Solidified function: get_text_rule ********************************************************************/ -be_local_closure(lvh_obj_set_pad_right2, /* name */ +be_local_closure(lvh_obj_get_text_rule, /* name */ be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("set_style_pad_right"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("set_pad_right2"), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_value_font -********************************************************************/ -be_local_closure(lvh_obj_get_value_font, /* name */ - be_nested_proto( - 3, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1545,14 +679,13 @@ be_local_closure(lvh_obj_get_value_font, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("get_text_font"), + /* K0 */ be_nested_str_literal("_text_rule"), }), - be_str_literal("get_value_font"), + be_str_literal("get_text_rule"), &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1560,9 +693,9 @@ be_local_closure(lvh_obj_get_value_font, /* name */ /******************************************************************** -** Solidified function: get_align +** Solidified function: get_pad_right ********************************************************************/ -be_local_closure(lvh_obj_get_align, /* name */ +be_local_closure(lvh_obj_get_pad_right, /* name */ be_nested_proto( 5, /* nstack */ 1, /* argc */ @@ -1572,53 +705,65 @@ be_local_closure(lvh_obj_get_align, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[10]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_label"), - /* K1 */ be_nested_str_literal("get_style_text_align"), - /* K2 */ be_const_int(0), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("get_style_pad_right"), /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("TEXT_ALIGN_LEFT"), - /* K5 */ be_nested_str_literal("left"), - /* K6 */ be_nested_str_literal("TEXT_ALIGN_CENTER"), - /* K7 */ be_nested_str_literal("center"), - /* K8 */ be_nested_str_literal("TEXT_ALIGN_RIGHT"), - /* K9 */ be_nested_str_literal("right"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), }), - be_str_literal("get_align"), + be_str_literal("get_pad_right"), &be_const_str_solidified, - ( &(const binstruction[32]) { /* code */ + ( &(const binstruction[13]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x78060001, // 0003 JMPF R1 #0006 - 0x4C040000, // 0004 LDNIL R1 - 0x80040200, // 0005 RET 1 R1 - 0x4C040000, // 0006 LDNIL R1 - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080501, // 0008 GETMET R2 R2 K1 - 0x58100002, // 0009 LDCONST R4 K2 - 0x7C080400, // 000A CALL R2 2 - 0xB80A0600, // 000B GETNGBL R2 K3 - 0x88080504, // 000C GETMBR R2 R2 K4 - 0x1C080202, // 000D EQ R2 R1 R2 - 0x780A0001, // 000E JMPF R2 #0011 - 0x80060A00, // 000F RET 1 K5 - 0x7002000D, // 0010 JMP #001F - 0xB80A0600, // 0011 GETNGBL R2 K3 - 0x88080506, // 0012 GETMBR R2 R2 K6 - 0x1C080202, // 0013 EQ R2 R1 R2 - 0x780A0001, // 0014 JMPF R2 #0017 - 0x80060E00, // 0015 RET 1 K7 - 0x70020007, // 0016 JMP #001F - 0xB80A0600, // 0017 GETNGBL R2 K3 - 0x88080508, // 0018 GETMBR R2 R2 K8 - 0x1C080202, // 0019 EQ R2 R1 R2 - 0x780A0001, // 001A JMPF R2 #001D - 0x80061200, // 001B RET 1 K9 - 0x70020001, // 001C JMP #001F - 0x4C080000, // 001D LDNIL R2 - 0x80040400, // 001E RET 1 R2 - 0x80000000, // 001F RET 0 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_value_ofs_y +********************************************************************/ +be_local_closure(lvh_obj_set_value_ofs_y, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("check_label"), + /* K1 */ be_nested_str_literal("_lv_label"), + /* K2 */ be_nested_str_literal("set_y"), + }), + be_str_literal("set_value_ofs_y"), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x60100009, // 0004 GETGBL R4 G9 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C100200, // 0006 CALL R4 1 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 }) ) ); @@ -1785,41 +930,148 @@ be_local_closure(lvh_obj_parse_color, /* name */ /******************************************************************** -** Solidified function: get_pad_left +** Solidified function: get_text_font ********************************************************************/ -be_local_closure(lvh_obj_get_pad_left, /* name */ +be_local_closure(lvh_obj_get_text_font, /* name */ be_nested_proto( - 5, /* nstack */ + 1, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_literal("get_text_font"), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: text_rule_matched +********************************************************************/ +be_local_closure(lvh_obj_text_rule_matched, /* name */ + be_nested_proto( + 12, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 8]) { /* constants */ + /* K0 */ be_nested_str_literal("int"), + /* K1 */ be_nested_str_literal("_text_rule_function"), + /* K2 */ be_nested_str_literal("string"), + /* K3 */ be_nested_str_literal("format"), + /* K4 */ be_nested_str_literal("HSP: failed to run self._text_rule_function - %s (%s)"), + /* K5 */ be_nested_str_literal("_text_rule_format"), + /* K6 */ be_nested_str_literal(""), + /* K7 */ be_nested_str_literal("text"), + }), + be_str_literal("text_rule_matched"), + &be_const_str_solidified, + ( &(const binstruction[49]) { /* code */ + 0x60080004, // 0000 GETGBL R2 G4 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x1C080500, // 0003 EQ R2 R2 K0 + 0x780A0003, // 0004 JMPF R2 #0009 + 0x6008000A, // 0005 GETGBL R2 G10 + 0x5C0C0200, // 0006 MOVE R3 R1 + 0x7C080200, // 0007 CALL R2 1 + 0x5C040400, // 0008 MOVE R1 R2 + 0x88080101, // 0009 GETMBR R2 R0 K1 + 0x4C0C0000, // 000A LDNIL R3 + 0x200C0403, // 000B NE R3 R2 R3 + 0x780E0012, // 000C JMPF R3 #0020 + 0xA8020005, // 000D EXBLK 0 #0014 + 0x5C0C0400, // 000E MOVE R3 R2 + 0x5C100200, // 000F MOVE R4 R1 + 0x7C0C0200, // 0010 CALL R3 1 + 0x5C040600, // 0011 MOVE R1 R3 + 0xA8040001, // 0012 EXBLK 1 1 + 0x7002000B, // 0013 JMP #0020 + 0xAC0C0002, // 0014 CATCH R3 0 2 + 0x70020008, // 0015 JMP #001F + 0xA4160400, // 0016 IMPORT R5 K2 + 0x60180001, // 0017 GETGBL R6 G1 + 0x8C1C0B03, // 0018 GETMET R7 R5 K3 + 0x58240004, // 0019 LDCONST R9 K4 + 0x5C280600, // 001A MOVE R10 R3 + 0x5C2C0800, // 001B MOVE R11 R4 + 0x7C1C0800, // 001C CALL R7 4 + 0x7C180200, // 001D CALL R6 1 + 0x70020000, // 001E JMP #0020 + 0xB0080000, // 001F RAISE 2 R0 R0 + 0x880C0105, // 0020 GETMBR R3 R0 K5 + 0x60100004, // 0021 GETGBL R4 G4 + 0x5C140600, // 0022 MOVE R5 R3 + 0x7C100200, // 0023 CALL R4 1 + 0x1C100902, // 0024 EQ R4 R4 K2 + 0x78120006, // 0025 JMPF R4 #002D + 0xA4120400, // 0026 IMPORT R4 K2 + 0x8C140903, // 0027 GETMET R5 R4 K3 + 0x5C1C0600, // 0028 MOVE R7 R3 + 0x5C200200, // 0029 MOVE R8 R1 + 0x7C140600, // 002A CALL R5 3 + 0x5C0C0A00, // 002B MOVE R3 R5 + 0x70020000, // 002C JMP #002E + 0x580C0006, // 002D LDCONST R3 K6 + 0x90020E03, // 002E SETMBR R0 K7 R3 + 0x50100000, // 002F LDBOOL R4 0 0 + 0x80040800, // 0030 RET 1 R4 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pad_bottom2 +********************************************************************/ +be_local_closure(lvh_obj_set_pad_bottom2, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_literal("_lv_part2_selector"), /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("get_style_pad_left"), + /* K2 */ be_nested_str_literal("set_style_pad_bottom"), /* K3 */ be_nested_str_literal("lv"), /* K4 */ be_nested_str_literal("STATE_DEFAULT"), }), - be_str_literal("get_pad_left"), + be_str_literal("set_pad_bottom2"), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 - 0x80000000, // 000C RET 0 + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 }) ) ); @@ -1827,9 +1079,136 @@ be_local_closure(lvh_obj_get_pad_left, /* name */ /******************************************************************** -** Solidified function: get_val_rule +** Solidified function: set_align ********************************************************************/ -be_local_closure(lvh_obj_get_val_rule, /* name */ +be_local_closure(lvh_obj_set_align, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[13]) { /* constants */ + /* K0 */ be_nested_str_literal("check_label"), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str_literal("left"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("TEXT_ALIGN_LEFT"), + /* K5 */ be_const_int(1), + /* K6 */ be_nested_str_literal("center"), + /* K7 */ be_nested_str_literal("TEXT_ALIGN_CENTER"), + /* K8 */ be_const_int(2), + /* K9 */ be_nested_str_literal("right"), + /* K10 */ be_nested_str_literal("TEXT_ALIGN_RIGHT"), + /* K11 */ be_nested_str_literal("_lv_label"), + /* K12 */ be_nested_str_literal("set_style_text_align"), + }), + be_str_literal("set_align"), + &be_const_str_solidified, + ( &(const binstruction[29]) { /* code */ + 0x4C080000, // 0000 LDNIL R2 + 0x8C0C0100, // 0001 GETMET R3 R0 K0 + 0x7C0C0200, // 0002 CALL R3 1 + 0x1C0C0301, // 0003 EQ R3 R1 K1 + 0x740E0001, // 0004 JMPT R3 #0007 + 0x1C0C0302, // 0005 EQ R3 R1 K2 + 0x780E0002, // 0006 JMPF R3 #000A + 0xB80E0600, // 0007 GETNGBL R3 K3 + 0x88080704, // 0008 GETMBR R2 R3 K4 + 0x7002000C, // 0009 JMP #0017 + 0x1C0C0305, // 000A EQ R3 R1 K5 + 0x740E0001, // 000B JMPT R3 #000E + 0x1C0C0306, // 000C EQ R3 R1 K6 + 0x780E0002, // 000D JMPF R3 #0011 + 0xB80E0600, // 000E GETNGBL R3 K3 + 0x88080707, // 000F GETMBR R2 R3 K7 + 0x70020005, // 0010 JMP #0017 + 0x1C0C0308, // 0011 EQ R3 R1 K8 + 0x740E0001, // 0012 JMPT R3 #0015 + 0x1C0C0309, // 0013 EQ R3 R1 K9 + 0x780E0001, // 0014 JMPF R3 #0017 + 0xB80E0600, // 0015 GETNGBL R3 K3 + 0x8808070A, // 0016 GETMBR R2 R3 K10 + 0x880C010B, // 0017 GETMBR R3 R0 K11 + 0x8C0C070C, // 0018 GETMET R3 R3 K12 + 0x5C140400, // 0019 MOVE R5 R2 + 0x58180001, // 001A LDCONST R6 K1 + 0x7C0C0600, // 001B CALL R3 3 + 0x80000000, // 001C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_text_rule_format +********************************************************************/ +be_local_closure(lvh_obj_set_text_rule_format, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("_text_rule_format"), + }), + be_str_literal("set_text_rule_format"), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_val +********************************************************************/ +be_local_closure(lvh_obj_set_val, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_value"), + }), + be_str_literal("set_val"), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_text_rule_format +********************************************************************/ +be_local_closure(lvh_obj_get_text_rule_format, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -1840,9 +1219,9 @@ be_local_closure(lvh_obj_get_val_rule, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_val_rule"), + /* K0 */ be_nested_str_literal("_text_rule_format"), }), - be_str_literal("get_val_rule"), + be_str_literal("get_text_rule_format"), &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -1854,11 +1233,11 @@ be_local_closure(lvh_obj_get_val_rule, /* name */ /******************************************************************** -** Solidified function: set_value_color +** Solidified function: set_action ********************************************************************/ -be_local_closure(lvh_obj_set_value_color, /* name */ +be_local_closure(lvh_obj_set_action, /* name */ be_nested_proto( - 5, /* nstack */ + 4, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1867,15 +1246,16 @@ be_local_closure(lvh_obj_set_value_color, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("set_text_color"), + /* K0 */ be_nested_str_literal("_action"), }), - be_str_literal("set_value_color"), + be_str_literal("set_action"), &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -1944,70 +1324,11 @@ be_local_closure(lvh_obj_set_text_rule_formula, /* name */ /******************************************************************** -** Solidified function: get_obj +** Solidified function: val_rule_matched ********************************************************************/ -be_local_closure(lvh_obj_get_obj, /* name */ +be_local_closure(lvh_obj_val_rule_matched, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - }), - be_str_literal("get_obj"), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_action -********************************************************************/ -be_local_closure(lvh_obj_get_action, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_literal("_action"), - /* K1 */ be_nested_str_literal(""), - }), - be_str_literal("get_action"), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x78060001, // 0001 JMPF R1 #0004 - 0x5C080200, // 0002 MOVE R2 R1 - 0x70020000, // 0003 JMP #0005 - 0x58080001, // 0004 LDCONST R2 K1 - 0x80040400, // 0005 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_enabled -********************************************************************/ -be_local_closure(lvh_obj_set_enabled, /* name */ - be_nested_proto( - 5, /* nstack */ + 13, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -2016,28 +1337,47 @@ be_local_closure(lvh_obj_set_enabled, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("add_flag"), - /* K2 */ be_nested_str_literal("lv"), - /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), - /* K4 */ be_nested_str_literal("clear_flag"), + /* K0 */ be_nested_str_literal("_val_rule_function"), + /* K1 */ be_nested_str_literal("string"), + /* K2 */ be_nested_str_literal("format"), + /* K3 */ be_nested_str_literal("HSP: failed to run self._val_rule_function - %s (%s)"), + /* K4 */ be_nested_str_literal("val"), }), - be_str_literal("set_enabled"), + be_str_literal("val_rule_matched"), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x78060005, // 0000 JMPF R1 #0007 - 0x88080100, // 0001 GETMBR R2 R0 K0 - 0x8C080501, // 0002 GETMET R2 R2 K1 - 0xB8120400, // 0003 GETNGBL R4 K2 - 0x88100903, // 0004 GETMBR R4 R4 K3 - 0x7C080400, // 0005 CALL R2 2 - 0x70020004, // 0006 JMP #000C - 0x88080100, // 0007 GETMBR R2 R0 K0 - 0x8C080504, // 0008 GETMET R2 R2 K4 - 0xB8120400, // 0009 GETNGBL R4 K2 - 0x88100903, // 000A GETMBR R4 R4 K3 - 0x7C080400, // 000B CALL R2 2 - 0x80000000, // 000C RET 0 + ( &(const binstruction[32]) { /* code */ + 0x6008000A, // 0000 GETGBL R2 G10 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x880C0100, // 0003 GETMBR R3 R0 K0 + 0x4C100000, // 0004 LDNIL R4 + 0x20100604, // 0005 NE R4 R3 R4 + 0x78120012, // 0006 JMPF R4 #001A + 0xA8020005, // 0007 EXBLK 0 #000E + 0x5C100600, // 0008 MOVE R4 R3 + 0x5C140400, // 0009 MOVE R5 R2 + 0x7C100200, // 000A CALL R4 1 + 0x5C080800, // 000B MOVE R2 R4 + 0xA8040001, // 000C EXBLK 1 1 + 0x7002000B, // 000D JMP #001A + 0xAC100002, // 000E CATCH R4 0 2 + 0x70020008, // 000F JMP #0019 + 0xA41A0200, // 0010 IMPORT R6 K1 + 0x601C0001, // 0011 GETGBL R7 G1 + 0x8C200D02, // 0012 GETMET R8 R6 K2 + 0x58280003, // 0013 LDCONST R10 K3 + 0x5C2C0800, // 0014 MOVE R11 R4 + 0x5C300A00, // 0015 MOVE R12 R5 + 0x7C200800, // 0016 CALL R8 4 + 0x7C1C0200, // 0017 CALL R7 1 + 0x70020000, // 0018 JMP #001A + 0xB0080000, // 0019 RAISE 2 R0 R0 + 0x60100009, // 001A GETGBL R4 G9 + 0x5C140400, // 001B MOVE R5 R2 + 0x7C100200, // 001C CALL R4 1 + 0x90020804, // 001D SETMBR R0 K4 R4 + 0x50100000, // 001E LDBOOL R4 0 0 + 0x80040800, // 001F RET 1 R4 }) ) ); @@ -2045,150 +1385,49 @@ be_local_closure(lvh_obj_set_enabled, /* name */ /******************************************************************** -** Solidified function: check_label +** Solidified function: remove_trailing_zeroes ********************************************************************/ -be_local_closure(lvh_obj_check_label, /* name */ +be_local_closure(lvh_obj_remove_trailing_zeroes, /* name */ be_nested_proto( - 5, /* nstack */ + 7, /* nstack */ 1, /* argc */ - 2, /* varg */ + 0, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_label"), - /* K1 */ be_nested_str_literal("lv"), - /* K2 */ be_nested_str_literal("label"), - /* K3 */ be_nested_str_literal("get_obj"), - /* K4 */ be_nested_str_literal("set_align"), - /* K5 */ be_nested_str_literal("ALIGN_CENTER"), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_const_int(1), + /* K2 */ be_nested_str_literal("resize"), }), - be_str_literal("check_label"), + be_str_literal("remove_trailing_zeroes"), &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x7806000A, // 0003 JMPF R1 #000F - 0xB8060200, // 0004 GETNGBL R1 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x8C0C0103, // 0006 GETMET R3 R0 K3 - 0x7C0C0200, // 0007 CALL R3 1 - 0x7C040400, // 0008 CALL R1 2 - 0x90020001, // 0009 SETMBR R0 K0 R1 - 0x88040100, // 000A GETMBR R1 R0 K0 - 0x8C040304, // 000B GETMET R1 R1 K4 - 0xB80E0200, // 000C GETNGBL R3 K1 - 0x880C0705, // 000D GETMBR R3 R3 K5 - 0x7C040400, // 000E CALL R1 2 - 0x80000000, // 000F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: register_event_cb -********************************************************************/ -be_local_closure(lvh_obj_register_event_cb, /* name */ - be_nested_proto( - 8, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str_literal("_page"), - /* K1 */ be_nested_str_literal("_oh"), - /* K2 */ be_nested_str_literal("_event_map"), - /* K3 */ be_nested_str_literal("keys"), - /* K4 */ be_nested_str_literal("register_event"), - /* K5 */ be_nested_str_literal("stop_iteration"), - }), - be_str_literal("register_event_cb"), - &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x60080010, // 0002 GETGBL R2 G16 - 0x880C0102, // 0003 GETMBR R3 R0 K2 - 0x8C0C0703, // 0004 GETMET R3 R3 K3 - 0x7C0C0200, // 0005 CALL R3 1 - 0x7C080200, // 0006 CALL R2 1 - 0xA8020006, // 0007 EXBLK 0 #000F - 0x5C0C0400, // 0008 MOVE R3 R2 - 0x7C0C0000, // 0009 CALL R3 0 - 0x8C100304, // 000A GETMET R4 R1 K4 - 0x5C180000, // 000B MOVE R6 R0 - 0x5C1C0600, // 000C MOVE R7 R3 - 0x7C100600, // 000D CALL R4 3 - 0x7001FFF8, // 000E JMP #0008 - 0x58080005, // 000F LDCONST R2 K5 - 0xAC080200, // 0010 CATCH R2 1 0 - 0xB0080000, // 0011 RAISE 2 R0 R0 - 0x80000000, // 0012 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_text_rule_format -********************************************************************/ -be_local_closure(lvh_obj_get_text_rule_format, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_text_rule_format"), - }), - be_str_literal("get_text_rule_format"), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_value_str -********************************************************************/ -be_local_closure(lvh_obj_set_value_str, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("set_text"), - }), - be_str_literal("set_value_str"), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C080400, // 0002 CALL R2 2 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[23]) { /* code */ + 0x6004000C, // 0000 GETGBL R1 G12 + 0x5C080000, // 0001 MOVE R2 R0 + 0x7C040200, // 0002 CALL R1 1 + 0x58080000, // 0003 LDCONST R2 K0 + 0x140C0401, // 0004 LT R3 R2 R1 + 0x780E0007, // 0005 JMPF R3 #000E + 0x540DFFFE, // 0006 LDINT R3 -1 + 0x040C0602, // 0007 SUB R3 R3 R2 + 0x940C0003, // 0008 GETIDX R3 R0 R3 + 0x200C0700, // 0009 NE R3 R3 K0 + 0x780E0000, // 000A JMPF R3 #000C + 0x70020001, // 000B JMP #000E + 0x00080501, // 000C ADD R2 R2 K1 + 0x7001FFF5, // 000D JMP #0004 + 0x240C0500, // 000E GT R3 R2 K0 + 0x780E0005, // 000F JMPF R3 #0016 + 0x8C0C0102, // 0010 GETMET R3 R0 K2 + 0x6014000C, // 0011 GETGBL R5 G12 + 0x5C180000, // 0012 MOVE R6 R0 + 0x7C140200, // 0013 CALL R5 1 + 0x04140A02, // 0014 SUB R5 R5 R2 + 0x7C0C0400, // 0015 CALL R3 2 + 0x80040000, // 0016 RET 1 R0 }) ) ); @@ -2224,486 +1463,23 @@ be_local_closure(lvh_obj_post_init, /* name */ /******************************************************************** -** Solidified function: get_adjustable +** Solidified function: get_mode ********************************************************************/ -be_local_closure(lvh_obj_get_adjustable, /* name */ +be_local_closure(lvh_obj_get_mode, /* name */ be_nested_proto( - 4, /* nstack */ + 1, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("has_flag"), - /* K2 */ be_nested_str_literal("lv"), - /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), - }), - be_str_literal("get_adjustable"), + 0, /* has constants */ + NULL, /* no const */ + be_str_literal("get_mode"), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_hidden -********************************************************************/ -be_local_closure(lvh_obj_get_hidden, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("has_flag"), - /* K2 */ be_nested_str_literal("lv"), - /* K3 */ be_nested_str_literal("OBJ_FLAG_HIDDEN"), - }), - be_str_literal("get_hidden"), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0xB80E0400, // 0002 GETNGBL R3 K2 - 0x880C0703, // 0003 GETMBR R3 R3 K3 - 0x7C040400, // 0004 CALL R1 2 - 0x80040200, // 0005 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_value_ofs_x -********************************************************************/ -be_local_closure(lvh_obj_get_value_ofs_x, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_label"), - /* K1 */ be_nested_str_literal("get_x"), - }), - be_str_literal("get_value_ofs_x"), - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_radius2 -********************************************************************/ -be_local_closure(lvh_obj_set_radius2, /* name */ - be_nested_proto( - 7, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("set_style_radius"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("set_radius2"), - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x4C0C0000, // 0001 LDNIL R3 - 0x20080403, // 0002 NE R2 R2 R3 - 0x780A0009, // 0003 JMPF R2 #000E - 0x88080101, // 0004 GETMBR R2 R0 K1 - 0x8C080502, // 0005 GETMET R2 R2 K2 - 0x60100009, // 0006 GETGBL R4 G9 - 0x5C140200, // 0007 MOVE R5 R1 - 0x7C100200, // 0008 CALL R4 1 - 0x88140100, // 0009 GETMBR R5 R0 K0 - 0xB81A0600, // 000A GETNGBL R6 K3 - 0x88180D04, // 000B GETMBR R6 R6 K4 - 0x30140A06, // 000C OR R5 R5 R6 - 0x7C080600, // 000D CALL R2 3 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_line_width -********************************************************************/ -be_local_closure(lvh_obj_get_line_width, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("get_style_line_width"), - /* K2 */ be_const_int(0), - }), - be_str_literal("get_line_width"), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x580C0002, // 0002 LDCONST R3 K2 - 0x7C040400, // 0003 CALL R1 2 - 0x80040200, // 0004 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_click -********************************************************************/ -be_local_closure(lvh_obj_get_click, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("get_enabled"), - }), - be_str_literal("get_click"), - &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x7C040200, // 0001 CALL R1 1 - 0x80040200, // 0002 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_value_ofs_x -********************************************************************/ -be_local_closure(lvh_obj_set_value_ofs_x, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_literal("check_label"), - /* K1 */ be_nested_str_literal("_lv_label"), - /* K2 */ be_nested_str_literal("set_x"), - }), - be_str_literal("set_value_ofs_x"), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x7C080200, // 0001 CALL R2 1 - 0x88080101, // 0002 GETMBR R2 R0 K1 - 0x8C080502, // 0003 GETMET R2 R2 K2 - 0x60100009, // 0004 GETGBL R4 G9 - 0x5C140200, // 0005 MOVE R5 R1 - 0x7C100200, // 0006 CALL R4 1 - 0x7C080400, // 0007 CALL R2 2 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_pad_right -********************************************************************/ -be_local_closure(lvh_obj_get_pad_right, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("get_style_pad_right"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("get_pad_right"), - &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 - 0x80000000, // 000C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_pad_bottom -********************************************************************/ -be_local_closure(lvh_obj_get_pad_bottom, /* name */ - be_nested_proto( - 5, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("get_style_pad_bottom"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), - }), - be_str_literal("get_pad_bottom"), - &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 - 0x80000000, // 000C RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_val_rule_formula -********************************************************************/ -be_local_closure(lvh_obj_get_val_rule_formula, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("_val_rule_formula"), - }), - be_str_literal("get_val_rule_formula"), - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: member -********************************************************************/ -be_local_closure(lvh_obj_member, /* name */ - be_nested_proto( - 10, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[14]) { /* constants */ - /* K0 */ be_nested_str_literal("string"), - /* K1 */ be_nested_str_literal("_attr_ignore"), - /* K2 */ be_nested_str_literal("find"), - /* K3 */ be_nested_str_literal("_attr_map"), - /* K4 */ be_nested_str_literal("contains"), - /* K5 */ be_nested_str_literal("introspect"), - /* K6 */ be_nested_str_literal("get"), - /* K7 */ be_nested_str_literal("get_"), - /* K8 */ be_nested_str_literal("function"), - /* K9 */ be_nested_str_literal("_lv_obj"), - /* K10 */ be_nested_str_literal("style_"), - /* K11 */ be_const_int(0), - /* K12 */ be_nested_str_literal("unknown attribute "), - /* K13 */ be_nested_str_literal("value_error"), - }), - be_str_literal("member"), - &be_const_str_solidified, - ( &(const binstruction[65]) { /* code */ - 0xA40A0000, // 0000 IMPORT R2 K0 - 0x880C0101, // 0001 GETMBR R3 R0 K1 - 0x8C0C0702, // 0002 GETMET R3 R3 K2 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C0C0400, // 0004 CALL R3 2 - 0x4C100000, // 0005 LDNIL R4 - 0x200C0604, // 0006 NE R3 R3 R4 - 0x780E0000, // 0007 JMPF R3 #0009 - 0x80000600, // 0008 RET 0 - 0x880C0103, // 0009 GETMBR R3 R0 K3 - 0x8C0C0704, // 000A GETMET R3 R3 K4 - 0x5C140200, // 000B MOVE R5 R1 - 0x7C0C0400, // 000C CALL R3 2 - 0x780E002C, // 000D JMPF R3 #003B - 0xA40E0A00, // 000E IMPORT R3 K5 - 0x88100103, // 000F GETMBR R4 R0 K3 - 0x94100801, // 0010 GETIDX R4 R4 R1 - 0x4C140000, // 0011 LDNIL R5 - 0x1C140805, // 0012 EQ R5 R4 R5 - 0x7816000D, // 0013 JMPF R5 #0022 - 0x8C140706, // 0014 GETMET R5 R3 K6 - 0x5C1C0000, // 0015 MOVE R7 R0 - 0x00220E01, // 0016 ADD R8 K7 R1 - 0x7C140600, // 0017 CALL R5 3 - 0x60180004, // 0018 GETGBL R6 G4 - 0x5C1C0A00, // 0019 MOVE R7 R5 - 0x7C180200, // 001A CALL R6 1 - 0x1C180D08, // 001B EQ R6 R6 K8 - 0x781A0003, // 001C JMPF R6 #0021 - 0x5C180A00, // 001D MOVE R6 R5 - 0x5C1C0000, // 001E MOVE R7 R0 - 0x7C180200, // 001F CALL R6 1 - 0x80040C00, // 0020 RET 1 R6 - 0x70020018, // 0021 JMP #003B - 0x8C140706, // 0022 GETMET R5 R3 K6 - 0x881C0109, // 0023 GETMBR R7 R0 K9 - 0x00220E04, // 0024 ADD R8 K7 R4 - 0x7C140600, // 0025 CALL R5 3 - 0x60180004, // 0026 GETGBL R6 G4 - 0x5C1C0A00, // 0027 MOVE R7 R5 - 0x7C180200, // 0028 CALL R6 1 - 0x1C180D08, // 0029 EQ R6 R6 K8 - 0x781A000F, // 002A JMPF R6 #003B - 0x8C180502, // 002B GETMET R6 R2 K2 - 0x5C200800, // 002C MOVE R8 R4 - 0x5824000A, // 002D LDCONST R9 K10 - 0x7C180600, // 002E CALL R6 3 - 0x1C180D0B, // 002F EQ R6 R6 K11 - 0x781A0005, // 0030 JMPF R6 #0037 - 0x5C180A00, // 0031 MOVE R6 R5 - 0x881C0109, // 0032 GETMBR R7 R0 K9 - 0x5820000B, // 0033 LDCONST R8 K11 - 0x7C180400, // 0034 CALL R6 2 - 0x80040C00, // 0035 RET 1 R6 - 0x70020003, // 0036 JMP #003B - 0x5C180A00, // 0037 MOVE R6 R5 - 0x881C0109, // 0038 GETMBR R7 R0 K9 - 0x7C180200, // 0039 CALL R6 1 - 0x80040C00, // 003A RET 1 R6 - 0x600C0008, // 003B GETGBL R3 G8 - 0x5C100200, // 003C MOVE R4 R1 - 0x7C0C0200, // 003D CALL R3 1 - 0x000E1803, // 003E ADD R3 K12 R3 - 0xB0061A03, // 003F RAISE 1 K13 R3 - 0x80000000, // 0040 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_line_width -********************************************************************/ -be_local_closure(lvh_obj_set_line_width, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("set_style_line_width"), - /* K2 */ be_const_int(0), - }), - be_str_literal("set_line_width"), - &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x60100009, // 0002 GETGBL R4 G9 - 0x5C140200, // 0003 MOVE R5 R1 - 0x7C100200, // 0004 CALL R4 1 - 0x58140002, // 0005 LDCONST R5 K2 - 0x7C080600, // 0006 CALL R2 3 - 0x80000000, // 0007 RET 0 + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 }) ) ); @@ -2755,35 +1531,28 @@ be_local_closure(lvh_obj_set_pad_top2, /* name */ /******************************************************************** -** Solidified function: get_text +** Solidified function: set_value_font ********************************************************************/ -be_local_closure(lvh_obj_get_text, /* name */ +be_local_closure(lvh_obj_set_value_font, /* name */ be_nested_proto( - 3, /* nstack */ - 1, /* argc */ + 5, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_label"), - /* K1 */ be_nested_str_literal("get_text"), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("set_text_font"), }), - be_str_literal("get_text"), + be_str_literal("set_value_font"), &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x1C040202, // 0002 EQ R1 R1 R2 - 0x78060001, // 0003 JMPF R1 #0006 - 0x4C040000, // 0004 LDNIL R1 - 0x80040200, // 0005 RET 1 R1 - 0x88040100, // 0006 GETMBR R1 R0 K0 - 0x8C040301, // 0007 GETMET R1 R1 K1 - 0x7C040200, // 0008 CALL R1 1 - 0x80040200, // 0009 RET 1 R1 + ( &(const binstruction[ 4]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x80000000, // 0003 RET 0 }) ) ); @@ -2791,9 +1560,9 @@ be_local_closure(lvh_obj_get_text, /* name */ /******************************************************************** -** Solidified function: set_adjustable +** Solidified function: set_enabled ********************************************************************/ -be_local_closure(lvh_obj_set_adjustable, /* name */ +be_local_closure(lvh_obj_set_enabled, /* name */ be_nested_proto( 5, /* nstack */ 2, /* argc */ @@ -2810,7 +1579,7 @@ be_local_closure(lvh_obj_set_adjustable, /* name */ /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), /* K4 */ be_nested_str_literal("clear_flag"), }), - be_str_literal("set_adjustable"), + be_str_literal("set_enabled"), &be_const_str_solidified, ( &(const binstruction[13]) { /* code */ 0x78060005, // 0000 JMPF R1 #0007 @@ -2832,6 +1601,114 @@ be_local_closure(lvh_obj_set_adjustable, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: get_align +********************************************************************/ +be_local_closure(lvh_obj_get_align, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[10]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_label"), + /* K1 */ be_nested_str_literal("get_style_text_align"), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("TEXT_ALIGN_LEFT"), + /* K5 */ be_nested_str_literal("left"), + /* K6 */ be_nested_str_literal("TEXT_ALIGN_CENTER"), + /* K7 */ be_nested_str_literal("center"), + /* K8 */ be_nested_str_literal("TEXT_ALIGN_RIGHT"), + /* K9 */ be_nested_str_literal("right"), + }), + be_str_literal("get_align"), + &be_const_str_solidified, + ( &(const binstruction[32]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060001, // 0003 JMPF R1 #0006 + 0x4C040000, // 0004 LDNIL R1 + 0x80040200, // 0005 RET 1 R1 + 0x4C040000, // 0006 LDNIL R1 + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080501, // 0008 GETMET R2 R2 K1 + 0x58100002, // 0009 LDCONST R4 K2 + 0x7C080400, // 000A CALL R2 2 + 0xB80A0600, // 000B GETNGBL R2 K3 + 0x88080504, // 000C GETMBR R2 R2 K4 + 0x1C080202, // 000D EQ R2 R1 R2 + 0x780A0001, // 000E JMPF R2 #0011 + 0x80060A00, // 000F RET 1 K5 + 0x7002000D, // 0010 JMP #001F + 0xB80A0600, // 0011 GETNGBL R2 K3 + 0x88080506, // 0012 GETMBR R2 R2 K6 + 0x1C080202, // 0013 EQ R2 R1 R2 + 0x780A0001, // 0014 JMPF R2 #0017 + 0x80060E00, // 0015 RET 1 K7 + 0x70020007, // 0016 JMP #001F + 0xB80A0600, // 0017 GETNGBL R2 K3 + 0x88080508, // 0018 GETMBR R2 R2 K8 + 0x1C080202, // 0019 EQ R2 R1 R2 + 0x780A0001, // 001A JMPF R2 #001D + 0x80061200, // 001B RET 1 K9 + 0x70020001, // 001C JMP #001F + 0x4C080000, // 001D LDNIL R2 + 0x80040400, // 001E RET 1 R2 + 0x80000000, // 001F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pad_left +********************************************************************/ +be_local_closure(lvh_obj_get_pad_left, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("get_style_pad_left"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + }), + be_str_literal("get_pad_left"), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: set_text_font ********************************************************************/ @@ -2987,6 +1864,456 @@ be_local_closure(lvh_obj_set_text_font, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: event_cb +********************************************************************/ +be_local_closure(lvh_obj_event_cb, /* name */ + be_nested_proto( + 14, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 1, /* has sup protos */ + ( &(const struct bproto*[ 2]) { + be_nested_proto( + 4, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 3]) { /* upvals */ + be_local_const_upval(1, 2), + be_local_const_upval(1, 0), + be_local_const_upval(1, 3), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("do_action"), + }), + be_str_literal(""), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x68000000, // 0000 GETUPV R0 U0 + 0x8C000100, // 0001 GETMET R0 R0 K0 + 0x68080001, // 0002 GETUPV R2 U1 + 0x680C0002, // 0003 GETUPV R3 U2 + 0x7C000600, // 0004 CALL R0 3 + 0x80040000, // 0005 RET 1 R0 + }) + ), + be_nested_proto( + 3, /* nstack */ + 0, /* argc */ + 0, /* varg */ + 1, /* has upvals */ + ( &(const bupvaldesc[ 1]) { /* upvals */ + be_local_const_upval(1, 7), + }), + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("tasmota"), + /* K1 */ be_nested_str_literal("publish_rule"), + }), + be_str_literal(""), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0xB8020000, // 0000 GETNGBL R0 K0 + 0x8C000101, // 0001 GETMET R0 R0 K1 + 0x68080000, // 0002 GETUPV R2 U0 + 0x7C000400, // 0003 CALL R0 2 + 0x80040000, // 0004 RET 1 R0 + }) + ), + }), + 1, /* has constants */ + ( &(const bvalue[24]) { /* constants */ + /* K0 */ be_nested_str_literal("_page"), + /* K1 */ be_nested_str_literal("_oh"), + /* K2 */ be_nested_str_literal("code"), + /* K3 */ be_nested_str_literal("action"), + /* K4 */ be_nested_str_literal(""), + /* K5 */ be_nested_str_literal("lv"), + /* K6 */ be_nested_str_literal("EVENT_CLICKED"), + /* K7 */ be_nested_str_literal("tasmota"), + /* K8 */ be_nested_str_literal("set_timer"), + /* K9 */ be_const_int(0), + /* K10 */ be_nested_str_literal("_event_map"), + /* K11 */ be_nested_str_literal("find"), + /* K12 */ be_nested_str_literal("string"), + /* K13 */ be_nested_str_literal("EVENT_VALUE_CHANGED"), + /* K14 */ be_nested_str_literal("val"), + /* K15 */ be_nested_str_literal("format"), + /* K16 */ be_nested_str_literal(",\"val\":%i"), + /* K17 */ be_nested_str_literal("text"), + /* K18 */ be_nested_str_literal("json"), + /* K19 */ be_nested_str_literal(",\"text\":"), + /* K20 */ be_nested_str_literal("dump"), + /* K21 */ be_nested_str_literal("{\"hasp\":{\"p%ib%i\":{\"event\":\"%s\"%s}}}"), + /* K22 */ be_nested_str_literal("_page_id"), + /* K23 */ be_nested_str_literal("id"), + }), + be_str_literal("event_cb"), + &be_const_str_solidified, + ( &(const binstruction[71]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x88080501, // 0001 GETMBR R2 R2 K1 + 0x880C0302, // 0002 GETMBR R3 R1 K2 + 0x88100103, // 0003 GETMBR R4 R0 K3 + 0x20100904, // 0004 NE R4 R4 K4 + 0x78120008, // 0005 JMPF R4 #000F + 0xB8120A00, // 0006 GETNGBL R4 K5 + 0x88100906, // 0007 GETMBR R4 R4 K6 + 0x1C100604, // 0008 EQ R4 R3 R4 + 0x78120004, // 0009 JMPF R4 #000F + 0xB8120E00, // 000A GETNGBL R4 K7 + 0x8C100908, // 000B GETMET R4 R4 K8 + 0x58180009, // 000C LDCONST R6 K9 + 0x841C0000, // 000D CLOSURE R7 P0 + 0x7C100600, // 000E CALL R4 3 + 0x8810010A, // 000F GETMBR R4 R0 K10 + 0x8C10090B, // 0010 GETMET R4 R4 K11 + 0x5C180600, // 0011 MOVE R6 R3 + 0x7C100400, // 0012 CALL R4 2 + 0x4C140000, // 0013 LDNIL R5 + 0x20140805, // 0014 NE R5 R4 R5 + 0x7816002E, // 0015 JMPF R5 #0045 + 0xA4161800, // 0016 IMPORT R5 K12 + 0x58180004, // 0017 LDCONST R6 K4 + 0x881C0302, // 0018 GETMBR R7 R1 K2 + 0xB8220A00, // 0019 GETNGBL R8 K5 + 0x8820110D, // 001A GETMBR R8 R8 K13 + 0x1C1C0E08, // 001B EQ R7 R7 R8 + 0x781E0019, // 001C JMPF R7 #0037 + 0xA8020014, // 001D EXBLK 0 #0033 + 0x881C010E, // 001E GETMBR R7 R0 K14 + 0x4C200000, // 001F LDNIL R8 + 0x20200E08, // 0020 NE R8 R7 R8 + 0x78220004, // 0021 JMPF R8 #0027 + 0x8C200B0F, // 0022 GETMET R8 R5 K15 + 0x58280010, // 0023 LDCONST R10 K16 + 0x5C2C0E00, // 0024 MOVE R11 R7 + 0x7C200600, // 0025 CALL R8 3 + 0x5C181000, // 0026 MOVE R6 R8 + 0x88200111, // 0027 GETMBR R8 R0 K17 + 0x4C240000, // 0028 LDNIL R9 + 0x20241009, // 0029 NE R9 R8 R9 + 0x78260005, // 002A JMPF R9 #0031 + 0xA4262400, // 002B IMPORT R9 K18 + 0x00180D13, // 002C ADD R6 R6 K19 + 0x8C281314, // 002D GETMET R10 R9 K20 + 0x5C301000, // 002E MOVE R12 R8 + 0x7C280400, // 002F CALL R10 2 + 0x00180C0A, // 0030 ADD R6 R6 R10 + 0xA8040001, // 0031 EXBLK 1 1 + 0x70020003, // 0032 JMP #0037 + 0xAC1C0000, // 0033 CATCH R7 0 0 + 0x70020000, // 0034 JMP #0036 + 0x70020000, // 0035 JMP #0037 + 0xB0080000, // 0036 RAISE 2 R0 R0 + 0x8C1C0B0F, // 0037 GETMET R7 R5 K15 + 0x58240015, // 0038 LDCONST R9 K21 + 0x88280100, // 0039 GETMBR R10 R0 K0 + 0x88281516, // 003A GETMBR R10 R10 K22 + 0x882C0117, // 003B GETMBR R11 R0 K23 + 0x5C300800, // 003C MOVE R12 R4 + 0x5C340C00, // 003D MOVE R13 R6 + 0x7C1C0C00, // 003E CALL R7 6 + 0xB8220E00, // 003F GETNGBL R8 K7 + 0x8C201108, // 0040 GETMET R8 R8 K8 + 0x58280009, // 0041 LDCONST R10 K9 + 0x842C0001, // 0042 CLOSURE R11 P1 + 0x7C200600, // 0043 CALL R8 3 + 0xA0140000, // 0044 CLOSE R5 + 0xA0000000, // 0045 CLOSE R0 + 0x80000000, // 0046 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_value_color +********************************************************************/ +be_local_closure(lvh_obj_get_value_color, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("get_value_color"), + }), + be_str_literal("get_value_color"), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_val_rule +********************************************************************/ +be_local_closure(lvh_obj_get_val_rule, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("_val_rule"), + }), + be_str_literal("get_val_rule"), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_val +********************************************************************/ +be_local_closure(lvh_obj_get_val, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_value"), + }), + be_str_literal("get_val"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_click +********************************************************************/ +be_local_closure(lvh_obj_get_click, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("get_enabled"), + }), + be_str_literal("get_click"), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_click +********************************************************************/ +be_local_closure(lvh_obj_set_click, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("set_enabled"), + }), + be_str_literal("set_click"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: member +********************************************************************/ +be_local_closure(lvh_obj_member, /* name */ + be_nested_proto( + 11, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[16]) { /* constants */ + /* K0 */ be_nested_str_literal("string"), + /* K1 */ be_nested_str_literal("introspect"), + /* K2 */ be_const_int(0), + /* K3 */ be_const_int(3), + /* K4 */ be_nested_str_literal("set_"), + /* K5 */ be_nested_str_literal("get_"), + /* K6 */ be_nested_str_literal("_attr_ignore"), + /* K7 */ be_nested_str_literal("find"), + /* K8 */ be_nested_str_literal("get"), + /* K9 */ be_nested_str_literal("function"), + /* K10 */ be_nested_str_literal("_attr_map"), + /* K11 */ be_nested_str_literal("contains"), + /* K12 */ be_nested_str_literal("_lv_obj"), + /* K13 */ be_nested_str_literal("style_"), + /* K14 */ be_nested_str_literal("unknown attribute "), + /* K15 */ be_nested_str_literal("value_error"), + }), + be_str_literal("member"), + &be_const_str_solidified, + ( &(const binstruction[69]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0xA40E0200, // 0001 IMPORT R3 K1 + 0x40120503, // 0002 CONNECT R4 K2 K3 + 0x94100204, // 0003 GETIDX R4 R1 R4 + 0x1C140904, // 0004 EQ R5 R4 K4 + 0x74160001, // 0005 JMPT R5 #0008 + 0x1C140905, // 0006 EQ R5 R4 K5 + 0x78160000, // 0007 JMPF R5 #0009 + 0x80000A00, // 0008 RET 0 + 0x88140106, // 0009 GETMBR R5 R0 K6 + 0x8C140B07, // 000A GETMET R5 R5 K7 + 0x5C1C0200, // 000B MOVE R7 R1 + 0x7C140400, // 000C CALL R5 2 + 0x4C180000, // 000D LDNIL R6 + 0x20140A06, // 000E NE R5 R5 R6 + 0x78160000, // 000F JMPF R5 #0011 + 0x80000A00, // 0010 RET 0 + 0x8C140708, // 0011 GETMET R5 R3 K8 + 0x5C1C0000, // 0012 MOVE R7 R0 + 0x00220A01, // 0013 ADD R8 K5 R1 + 0x7C140600, // 0014 CALL R5 3 + 0x60180004, // 0015 GETGBL R6 G4 + 0x5C1C0A00, // 0016 MOVE R7 R5 + 0x7C180200, // 0017 CALL R6 1 + 0x1C180D09, // 0018 EQ R6 R6 K9 + 0x781A0003, // 0019 JMPF R6 #001E + 0x5C180A00, // 001A MOVE R6 R5 + 0x5C1C0000, // 001B MOVE R7 R0 + 0x7C180200, // 001C CALL R6 1 + 0x80040C00, // 001D RET 1 R6 + 0x8818010A, // 001E GETMBR R6 R0 K10 + 0x8C180D0B, // 001F GETMET R6 R6 K11 + 0x5C200200, // 0020 MOVE R8 R1 + 0x7C180400, // 0021 CALL R6 2 + 0x781A001B, // 0022 JMPF R6 #003F + 0x8818010A, // 0023 GETMBR R6 R0 K10 + 0x94180C01, // 0024 GETIDX R6 R6 R1 + 0x8C1C0708, // 0025 GETMET R7 R3 K8 + 0x8824010C, // 0026 GETMBR R9 R0 K12 + 0x002A0A06, // 0027 ADD R10 K5 R6 + 0x7C1C0600, // 0028 CALL R7 3 + 0x5C140E00, // 0029 MOVE R5 R7 + 0x601C0004, // 002A GETGBL R7 G4 + 0x5C200A00, // 002B MOVE R8 R5 + 0x7C1C0200, // 002C CALL R7 1 + 0x1C1C0F09, // 002D EQ R7 R7 K9 + 0x781E000F, // 002E JMPF R7 #003F + 0x8C1C0507, // 002F GETMET R7 R2 K7 + 0x5C240C00, // 0030 MOVE R9 R6 + 0x5828000D, // 0031 LDCONST R10 K13 + 0x7C1C0600, // 0032 CALL R7 3 + 0x1C1C0F02, // 0033 EQ R7 R7 K2 + 0x781E0005, // 0034 JMPF R7 #003B + 0x5C1C0A00, // 0035 MOVE R7 R5 + 0x8820010C, // 0036 GETMBR R8 R0 K12 + 0x58240002, // 0037 LDCONST R9 K2 + 0x7C1C0400, // 0038 CALL R7 2 + 0x80040E00, // 0039 RET 1 R7 + 0x70020003, // 003A JMP #003F + 0x5C1C0A00, // 003B MOVE R7 R5 + 0x8820010C, // 003C GETMBR R8 R0 K12 + 0x7C1C0200, // 003D CALL R7 1 + 0x80040E00, // 003E RET 1 R7 + 0x60180008, // 003F GETGBL R6 G8 + 0x5C1C0200, // 0040 MOVE R7 R1 + 0x7C180200, // 0041 CALL R6 1 + 0x001A1C06, // 0042 ADD R6 K14 R6 + 0xB0061E06, // 0043 RAISE 1 K15 R6 + 0x80000000, // 0044 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_text_rule_formula +********************************************************************/ +be_local_closure(lvh_obj_get_text_rule_formula, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("_text_rule_formula"), + }), + be_str_literal("get_text_rule_formula"), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: get_value_ofs_y ********************************************************************/ @@ -3018,11 +2345,11 @@ be_local_closure(lvh_obj_get_value_ofs_y, /* name */ /******************************************************************** -** Solidified function: get_pad_top +** Solidified function: get_obj ********************************************************************/ -be_local_closure(lvh_obj_get_pad_top, /* name */ +be_local_closure(lvh_obj_get_obj, /* name */ be_nested_proto( - 5, /* nstack */ + 2, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -3030,29 +2357,14 @@ be_local_closure(lvh_obj_get_pad_top, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_literal("_lv_part2_selector"), - /* K1 */ be_nested_str_literal("_lv_obj"), - /* K2 */ be_nested_str_literal("get_style_pad_top"), - /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), }), - be_str_literal("get_pad_top"), + be_str_literal("get_obj"), &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ + ( &(const binstruction[ 2]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x4C080000, // 0001 LDNIL R2 - 0x20040202, // 0002 NE R1 R1 R2 - 0x78060007, // 0003 JMPF R1 #000C - 0x88040101, // 0004 GETMBR R1 R0 K1 - 0x8C040302, // 0005 GETMET R1 R1 K2 - 0x880C0100, // 0006 GETMBR R3 R0 K0 - 0xB8120600, // 0007 GETNGBL R4 K3 - 0x88100904, // 0008 GETMBR R4 R4 K4 - 0x300C0604, // 0009 OR R3 R3 R4 - 0x7C040400, // 000A CALL R1 2 - 0x80040200, // 000B RET 1 R1 - 0x80000000, // 000C RET 0 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -3096,42 +2408,6 @@ be_local_closure(lvh_obj_is_color_attribute, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: set_value_ofs_y -********************************************************************/ -be_local_closure(lvh_obj_set_value_ofs_y, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str_literal("check_label"), - /* K1 */ be_nested_str_literal("_lv_label"), - /* K2 */ be_nested_str_literal("set_y"), - }), - be_str_literal("set_value_ofs_y"), - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x7C080200, // 0001 CALL R2 1 - 0x88080101, // 0002 GETMBR R2 R0 K1 - 0x8C080502, // 0003 GETMET R2 R2 K2 - 0x60100009, // 0004 GETGBL R4 G9 - 0x5C140200, // 0005 MOVE R5 R1 - 0x7C100200, // 0006 CALL R4 1 - 0x7C080400, // 0007 CALL R2 2 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: set_mode ********************************************************************/ @@ -3218,11 +2494,11 @@ be_local_closure(lvh_obj_set_mode, /* name */ /******************************************************************** -** Solidified function: set_val_rule_formula +** Solidified function: set_value_color ********************************************************************/ -be_local_closure(lvh_obj_set_val_rule_formula, /* name */ +be_local_closure(lvh_obj_set_value_color, /* name */ be_nested_proto( - 13, /* nstack */ + 5, /* nstack */ 2, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -3230,48 +2506,16 @@ be_local_closure(lvh_obj_set_val_rule_formula, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str_literal("_val_rule_formula"), - /* K1 */ be_nested_str_literal("return / val -> ("), - /* K2 */ be_nested_str_literal(")"), - /* K3 */ be_nested_str_literal("_val_rule_function"), - /* K4 */ be_nested_str_literal("string"), - /* K5 */ be_nested_str_literal("format"), - /* K6 */ be_nested_str_literal("HSP: failed to compile '%s' - %s (%s)"), + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("set_text_color"), }), - be_str_literal("set_val_rule_formula"), + be_str_literal("set_value_color"), &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x60080008, // 0000 GETGBL R2 G8 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020002, // 0003 SETMBR R0 K0 R2 - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x000A0202, // 0005 ADD R2 K1 R2 - 0x00080502, // 0006 ADD R2 R2 K2 - 0xA8020007, // 0007 EXBLK 0 #0010 - 0x600C000D, // 0008 GETGBL R3 G13 - 0x5C100400, // 0009 MOVE R4 R2 - 0x7C0C0200, // 000A CALL R3 1 - 0x5C100600, // 000B MOVE R4 R3 - 0x7C100000, // 000C CALL R4 0 - 0x90020604, // 000D SETMBR R0 K3 R4 - 0xA8040001, // 000E EXBLK 1 1 - 0x7002000C, // 000F JMP #001D - 0xAC0C0002, // 0010 CATCH R3 0 2 - 0x70020009, // 0011 JMP #001C - 0xA4160800, // 0012 IMPORT R5 K4 - 0x60180001, // 0013 GETGBL R6 G1 - 0x8C1C0B05, // 0014 GETMET R7 R5 K5 - 0x58240006, // 0015 LDCONST R9 K6 - 0x5C280400, // 0016 MOVE R10 R2 - 0x5C2C0600, // 0017 MOVE R11 R3 - 0x5C300800, // 0018 MOVE R12 R4 - 0x7C1C0A00, // 0019 CALL R7 5 - 0x7C180200, // 001A CALL R6 1 - 0x70020000, // 001B JMP #001D - 0xB0080000, // 001C RAISE 2 R0 R0 - 0x80000000, // 001D RET 0 + ( &(const binstruction[ 4]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x80000000, // 0003 RET 0 }) ) ); @@ -3353,9 +2597,210 @@ be_local_closure(lvh_obj_set_text_rule, /* name */ /******************************************************************** -** Solidified function: get_text_color +** Solidified function: get_adjustable ********************************************************************/ -be_local_closure(lvh_obj_get_text_color, /* name */ +be_local_closure(lvh_obj_get_adjustable, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("has_flag"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), + }), + be_str_literal("get_adjustable"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_toggle +********************************************************************/ +be_local_closure(lvh_obj_get_toggle, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("has_state"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("STATE_CHECKED"), + }), + be_str_literal("get_toggle"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_value_str +********************************************************************/ +be_local_closure(lvh_obj_get_value_str, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("get_text"), + }), + be_str_literal("get_value_str"), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pad_right2 +********************************************************************/ +be_local_closure(lvh_obj_set_pad_right2, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("set_style_pad_right"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + }), + be_str_literal("set_pad_right2"), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_val_rule_formula +********************************************************************/ +be_local_closure(lvh_obj_set_val_rule_formula, /* name */ + be_nested_proto( + 13, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_literal("_val_rule_formula"), + /* K1 */ be_nested_str_literal("return / val -> ("), + /* K2 */ be_nested_str_literal(")"), + /* K3 */ be_nested_str_literal("_val_rule_function"), + /* K4 */ be_nested_str_literal("string"), + /* K5 */ be_nested_str_literal("format"), + /* K6 */ be_nested_str_literal("HSP: failed to compile '%s' - %s (%s)"), + }), + be_str_literal("set_val_rule_formula"), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0x60080008, // 0000 GETGBL R2 G8 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020002, // 0003 SETMBR R0 K0 R2 + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x000A0202, // 0005 ADD R2 K1 R2 + 0x00080502, // 0006 ADD R2 R2 K2 + 0xA8020007, // 0007 EXBLK 0 #0010 + 0x600C000D, // 0008 GETGBL R3 G13 + 0x5C100400, // 0009 MOVE R4 R2 + 0x7C0C0200, // 000A CALL R3 1 + 0x5C100600, // 000B MOVE R4 R3 + 0x7C100000, // 000C CALL R4 0 + 0x90020604, // 000D SETMBR R0 K3 R4 + 0xA8040001, // 000E EXBLK 1 1 + 0x7002000C, // 000F JMP #001D + 0xAC0C0002, // 0010 CATCH R3 0 2 + 0x70020009, // 0011 JMP #001C + 0xA4160800, // 0012 IMPORT R5 K4 + 0x60180001, // 0013 GETGBL R6 G1 + 0x8C1C0B05, // 0014 GETMET R7 R5 K5 + 0x58240006, // 0015 LDCONST R9 K6 + 0x5C280400, // 0016 MOVE R10 R2 + 0x5C2C0600, // 0017 MOVE R11 R3 + 0x5C300800, // 0018 MOVE R12 R4 + 0x7C1C0A00, // 0019 CALL R7 5 + 0x7C180200, // 001A CALL R6 1 + 0x70020000, // 001B JMP #001D + 0xB0080000, // 001C RAISE 2 R0 R0 + 0x80000000, // 001D RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_line_width +********************************************************************/ +be_local_closure(lvh_obj_get_line_width, /* name */ be_nested_proto( 4, /* nstack */ 1, /* argc */ @@ -3367,10 +2812,10 @@ be_local_closure(lvh_obj_get_text_color, /* name */ 1, /* has constants */ ( &(const bvalue[ 3]) { /* constants */ /* K0 */ be_nested_str_literal("_lv_obj"), - /* K1 */ be_nested_str_literal("get_style_text_color"), + /* K1 */ be_nested_str_literal("get_style_line_width"), /* K2 */ be_const_int(0), }), - be_str_literal("get_text_color"), + be_str_literal("get_line_width"), &be_const_str_solidified, ( &(const binstruction[ 5]) { /* code */ 0x88040100, // 0000 GETMBR R1 R0 K0 @@ -3385,141 +2830,9 @@ be_local_closure(lvh_obj_get_text_color, /* name */ /******************************************************************** -** Solidified function: event_cb +** Solidified function: set_pad_left2 ********************************************************************/ -be_local_closure(lvh_obj_event_cb, /* name */ - be_nested_proto( - 12, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 1, /* has sup protos */ - ( &(const struct bproto*[ 2]) { - be_nested_proto( - 4, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 3]) { /* upvals */ - be_local_const_upval(1, 2), - be_local_const_upval(1, 0), - be_local_const_upval(1, 3), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str_literal("do_action"), - }), - be_str_literal(""), - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x68000000, // 0000 GETUPV R0 U0 - 0x8C000100, // 0001 GETMET R0 R0 K0 - 0x68080001, // 0002 GETUPV R2 U1 - 0x680C0002, // 0003 GETUPV R3 U2 - 0x7C000600, // 0004 CALL R0 3 - 0x80040000, // 0005 RET 1 R0 - }) - ), - be_nested_proto( - 3, /* nstack */ - 0, /* argc */ - 0, /* varg */ - 1, /* has upvals */ - ( &(const bupvaldesc[ 1]) { /* upvals */ - be_local_const_upval(1, 6), - }), - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str_literal("tasmota"), - /* K1 */ be_nested_str_literal("publish_rule"), - }), - be_str_literal(""), - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0xB8020000, // 0000 GETNGBL R0 K0 - 0x8C000101, // 0001 GETMET R0 R0 K1 - 0x68080000, // 0002 GETUPV R2 U0 - 0x7C000400, // 0003 CALL R0 2 - 0x80040000, // 0004 RET 1 R0 - }) - ), - }), - 1, /* has constants */ - ( &(const bvalue[17]) { /* constants */ - /* K0 */ be_nested_str_literal("_page"), - /* K1 */ be_nested_str_literal("_oh"), - /* K2 */ be_nested_str_literal("code"), - /* K3 */ be_nested_str_literal("action"), - /* K4 */ be_nested_str_literal(""), - /* K5 */ be_nested_str_literal("lv"), - /* K6 */ be_nested_str_literal("EVENT_CLICKED"), - /* K7 */ be_nested_str_literal("tasmota"), - /* K8 */ be_nested_str_literal("set_timer"), - /* K9 */ be_const_int(0), - /* K10 */ be_nested_str_literal("_event_map"), - /* K11 */ be_nested_str_literal("find"), - /* K12 */ be_nested_str_literal("string"), - /* K13 */ be_nested_str_literal("format"), - /* K14 */ be_nested_str_literal("{\"hasp\":{\"p%ib%i\":\"%s\"}}"), - /* K15 */ be_nested_str_literal("_page_id"), - /* K16 */ be_nested_str_literal("id"), - }), - be_str_literal("event_cb"), - &be_const_str_solidified, - ( &(const binstruction[38]) { /* code */ - 0x88080100, // 0000 GETMBR R2 R0 K0 - 0x88080501, // 0001 GETMBR R2 R2 K1 - 0x880C0302, // 0002 GETMBR R3 R1 K2 - 0x88100103, // 0003 GETMBR R4 R0 K3 - 0x20100904, // 0004 NE R4 R4 K4 - 0x78120008, // 0005 JMPF R4 #000F - 0xB8120A00, // 0006 GETNGBL R4 K5 - 0x88100906, // 0007 GETMBR R4 R4 K6 - 0x1C100604, // 0008 EQ R4 R3 R4 - 0x78120004, // 0009 JMPF R4 #000F - 0xB8120E00, // 000A GETNGBL R4 K7 - 0x8C100908, // 000B GETMET R4 R4 K8 - 0x58180009, // 000C LDCONST R6 K9 - 0x841C0000, // 000D CLOSURE R7 P0 - 0x7C100600, // 000E CALL R4 3 - 0x8810010A, // 000F GETMBR R4 R0 K10 - 0x8C10090B, // 0010 GETMET R4 R4 K11 - 0x5C180600, // 0011 MOVE R6 R3 - 0x7C100400, // 0012 CALL R4 2 - 0x4C140000, // 0013 LDNIL R5 - 0x20140805, // 0014 NE R5 R4 R5 - 0x7816000D, // 0015 JMPF R5 #0024 - 0xA4161800, // 0016 IMPORT R5 K12 - 0x8C180B0D, // 0017 GETMET R6 R5 K13 - 0x5820000E, // 0018 LDCONST R8 K14 - 0x88240100, // 0019 GETMBR R9 R0 K0 - 0x8824130F, // 001A GETMBR R9 R9 K15 - 0x88280110, // 001B GETMBR R10 R0 K16 - 0x5C2C0800, // 001C MOVE R11 R4 - 0x7C180A00, // 001D CALL R6 5 - 0xB81E0E00, // 001E GETNGBL R7 K7 - 0x8C1C0F08, // 001F GETMET R7 R7 K8 - 0x58240009, // 0020 LDCONST R9 K9 - 0x84280001, // 0021 CLOSURE R10 P1 - 0x7C1C0600, // 0022 CALL R7 3 - 0xA0140000, // 0023 CLOSE R5 - 0xA0000000, // 0024 CLOSE R0 - 0x80000000, // 0025 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_align -********************************************************************/ -be_local_closure(lvh_obj_set_align, /* name */ +be_local_closure(lvh_obj_set_pad_left2, /* name */ be_nested_proto( 7, /* nstack */ 2, /* argc */ @@ -3529,53 +2842,714 @@ be_local_closure(lvh_obj_set_align, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ - /* K0 */ be_nested_str_literal("check_label"), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str_literal("left"), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("set_style_pad_left"), /* K3 */ be_nested_str_literal("lv"), - /* K4 */ be_nested_str_literal("TEXT_ALIGN_LEFT"), - /* K5 */ be_const_int(1), - /* K6 */ be_nested_str_literal("center"), - /* K7 */ be_nested_str_literal("TEXT_ALIGN_CENTER"), - /* K8 */ be_const_int(2), - /* K9 */ be_nested_str_literal("right"), - /* K10 */ be_nested_str_literal("TEXT_ALIGN_RIGHT"), - /* K11 */ be_nested_str_literal("_lv_label"), - /* K12 */ be_nested_str_literal("set_style_text_align"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), }), - be_str_literal("set_align"), + be_str_literal("set_pad_left2"), &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x4C080000, // 0000 LDNIL R2 - 0x8C0C0100, // 0001 GETMET R3 R0 K0 - 0x7C0C0200, // 0002 CALL R3 1 - 0x1C0C0301, // 0003 EQ R3 R1 K1 - 0x740E0001, // 0004 JMPT R3 #0007 - 0x1C0C0302, // 0005 EQ R3 R1 K2 - 0x780E0002, // 0006 JMPF R3 #000A - 0xB80E0600, // 0007 GETNGBL R3 K3 - 0x88080704, // 0008 GETMBR R2 R3 K4 - 0x7002000C, // 0009 JMP #0017 - 0x1C0C0305, // 000A EQ R3 R1 K5 - 0x740E0001, // 000B JMPT R3 #000E - 0x1C0C0306, // 000C EQ R3 R1 K6 - 0x780E0002, // 000D JMPF R3 #0011 - 0xB80E0600, // 000E GETNGBL R3 K3 - 0x88080707, // 000F GETMBR R2 R3 K7 - 0x70020005, // 0010 JMP #0017 - 0x1C0C0308, // 0011 EQ R3 R1 K8 - 0x740E0001, // 0012 JMPT R3 #0015 - 0x1C0C0309, // 0013 EQ R3 R1 K9 - 0x780E0001, // 0014 JMPF R3 #0017 - 0xB80E0600, // 0015 GETNGBL R3 K3 - 0x8808070A, // 0016 GETMBR R2 R3 K10 - 0x880C010B, // 0017 GETMBR R3 R0 K11 - 0x8C0C070C, // 0018 GETMET R3 R3 K12 - 0x5C140400, // 0019 MOVE R5 R2 - 0x58180001, // 001A LDCONST R6 K1 - 0x7C0C0600, // 001B CALL R3 3 - 0x80000000, // 001C RET 0 + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_val_rule_formula +********************************************************************/ +be_local_closure(lvh_obj_get_val_rule_formula, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("_val_rule_formula"), + }), + be_str_literal("get_val_rule_formula"), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: check_label +********************************************************************/ +be_local_closure(lvh_obj_check_label, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_label"), + /* K1 */ be_nested_str_literal("lv"), + /* K2 */ be_nested_str_literal("label"), + /* K3 */ be_nested_str_literal("get_obj"), + /* K4 */ be_nested_str_literal("set_align"), + /* K5 */ be_nested_str_literal("ALIGN_CENTER"), + }), + be_str_literal("check_label"), + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x7806000A, // 0003 JMPF R1 #000F + 0xB8060200, // 0004 GETNGBL R1 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x8C0C0103, // 0006 GETMET R3 R0 K3 + 0x7C0C0200, // 0007 CALL R3 1 + 0x7C040400, // 0008 CALL R1 2 + 0x90020001, // 0009 SETMBR R0 K0 R1 + 0x88040100, // 000A GETMBR R1 R0 K0 + 0x8C040304, // 000B GETMET R1 R1 K4 + 0xB80E0200, // 000C GETNGBL R3 K1 + 0x880C0705, // 000D GETMBR R3 R3 K5 + 0x7C040400, // 000E CALL R1 2 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_text +********************************************************************/ +be_local_closure(lvh_obj_get_text, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_label"), + /* K1 */ be_nested_str_literal("get_text"), + }), + be_str_literal("get_text"), + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x1C040202, // 0002 EQ R1 R1 R2 + 0x78060001, // 0003 JMPF R1 #0006 + 0x4C040000, // 0004 LDNIL R1 + 0x80040200, // 0005 RET 1 R1 + 0x88040100, // 0006 GETMBR R1 R0 K0 + 0x8C040301, // 0007 GETMET R1 R1 K1 + 0x7C040200, // 0008 CALL R1 1 + 0x80040200, // 0009 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_hidden +********************************************************************/ +be_local_closure(lvh_obj_set_hidden, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("add_flag"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("OBJ_FLAG_HIDDEN"), + /* K4 */ be_nested_str_literal("clear_flag"), + }), + be_str_literal("set_hidden"), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x78060005, // 0000 JMPF R1 #0007 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0xB8120400, // 0003 GETNGBL R4 K2 + 0x88100903, // 0004 GETMBR R4 R4 K3 + 0x7C080400, // 0005 CALL R2 2 + 0x70020004, // 0006 JMP #000C + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080504, // 0008 GETMET R2 R2 K4 + 0xB8120400, // 0009 GETNGBL R4 K2 + 0x88100903, // 000A GETMBR R4 R4 K3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pad_all2 +********************************************************************/ +be_local_closure(lvh_obj_set_pad_all2, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("set_style_pad_all"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + }), + be_str_literal("set_pad_all2"), + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x4C0C0000, // 0001 LDNIL R3 + 0x20080403, // 0002 NE R2 R2 R3 + 0x780A0009, // 0003 JMPF R2 #000E + 0x88080101, // 0004 GETMBR R2 R0 K1 + 0x8C080502, // 0005 GETMET R2 R2 K2 + 0x60100009, // 0006 GETGBL R4 G9 + 0x5C140200, // 0007 MOVE R5 R1 + 0x7C100200, // 0008 CALL R4 1 + 0x88140100, // 0009 GETMBR R5 R0 K0 + 0xB81A0600, // 000A GETNGBL R6 K3 + 0x88180D04, // 000B GETMBR R6 R6 K4 + 0x30140A06, // 000C OR R5 R5 R6 + 0x7C080600, // 000D CALL R2 3 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_text_color +********************************************************************/ +be_local_closure(lvh_obj_set_text_color, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_style_text_color"), + /* K2 */ be_nested_str_literal("parse_color"), + /* K3 */ be_const_int(0), + }), + be_str_literal("set_text_color"), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x8C100102, // 0002 GETMET R4 R0 K2 + 0x5C180200, // 0003 MOVE R6 R1 + 0x7C100400, // 0004 CALL R4 2 + 0x58140003, // 0005 LDCONST R5 K3 + 0x7C080600, // 0006 CALL R2 3 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pad_bottom +********************************************************************/ +be_local_closure(lvh_obj_get_pad_bottom, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("get_style_pad_bottom"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + }), + be_str_literal("get_pad_bottom"), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pad_top +********************************************************************/ +be_local_closure(lvh_obj_get_pad_top, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_part2_selector"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("get_style_pad_top"), + /* K3 */ be_nested_str_literal("lv"), + /* K4 */ be_nested_str_literal("STATE_DEFAULT"), + }), + be_str_literal("get_pad_top"), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x4C080000, // 0001 LDNIL R2 + 0x20040202, // 0002 NE R1 R1 R2 + 0x78060007, // 0003 JMPF R1 #000C + 0x88040101, // 0004 GETMBR R1 R0 K1 + 0x8C040302, // 0005 GETMET R1 R1 K2 + 0x880C0100, // 0006 GETMBR R3 R0 K0 + 0xB8120600, // 0007 GETNGBL R4 K3 + 0x88100904, // 0008 GETMBR R4 R4 K4 + 0x300C0604, // 0009 OR R3 R3 R4 + 0x7C040400, // 000A CALL R1 2 + 0x80040200, // 000B RET 1 R1 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_adjustable +********************************************************************/ +be_local_closure(lvh_obj_set_adjustable, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("add_flag"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), + /* K4 */ be_nested_str_literal("clear_flag"), + }), + be_str_literal("set_adjustable"), + &be_const_str_solidified, + ( &(const binstruction[13]) { /* code */ + 0x78060005, // 0000 JMPF R1 #0007 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0xB8120400, // 0003 GETNGBL R4 K2 + 0x88100903, // 0004 GETMBR R4 R4 K3 + 0x7C080400, // 0005 CALL R2 2 + 0x70020004, // 0006 JMP #000C + 0x88080100, // 0007 GETMBR R2 R0 K0 + 0x8C080504, // 0008 GETMET R2 R2 K4 + 0xB8120400, // 0009 GETNGBL R4 K2 + 0x88100903, // 000A GETMBR R4 R4 K3 + 0x7C080400, // 000B CALL R2 2 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_enabled +********************************************************************/ +be_local_closure(lvh_obj_get_enabled, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("has_flag"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("OBJ_FLAG_CLICKABLE"), + }), + be_str_literal("get_enabled"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: setmember +********************************************************************/ +be_local_closure(lvh_obj_setmember, /* name */ + be_nested_proto( + 12, /* nstack */ + 3, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[18]) { /* constants */ + /* K0 */ be_nested_str_literal("string"), + /* K1 */ be_nested_str_literal("introspect"), + /* K2 */ be_const_int(0), + /* K3 */ be_const_int(3), + /* K4 */ be_nested_str_literal("set_"), + /* K5 */ be_nested_str_literal("get_"), + /* K6 */ be_nested_str_literal("_attr_ignore"), + /* K7 */ be_nested_str_literal("find"), + /* K8 */ be_nested_str_literal("get"), + /* K9 */ be_nested_str_literal("function"), + /* K10 */ be_nested_str_literal("_attr_map"), + /* K11 */ be_nested_str_literal("contains"), + /* K12 */ be_nested_str_literal("_lv_obj"), + /* K13 */ be_nested_str_literal("is_color_attribute"), + /* K14 */ be_nested_str_literal("parse_color"), + /* K15 */ be_nested_str_literal("style_"), + /* K16 */ be_nested_str_literal("HSP: Could not find function set_"), + /* K17 */ be_nested_str_literal("HSP: unknown attribute:"), + }), + be_str_literal("setmember"), + &be_const_str_solidified, + ( &(const binstruction[83]) { /* code */ + 0xA40E0000, // 0000 IMPORT R3 K0 + 0xA4120200, // 0001 IMPORT R4 K1 + 0x40160503, // 0002 CONNECT R5 K2 K3 + 0x94140205, // 0003 GETIDX R5 R1 R5 + 0x1C180B04, // 0004 EQ R6 R5 K4 + 0x741A0001, // 0005 JMPT R6 #0008 + 0x1C180B05, // 0006 EQ R6 R5 K5 + 0x781A0000, // 0007 JMPF R6 #0009 + 0x80000C00, // 0008 RET 0 + 0x88180106, // 0009 GETMBR R6 R0 K6 + 0x8C180D07, // 000A GETMET R6 R6 K7 + 0x5C200200, // 000B MOVE R8 R1 + 0x7C180400, // 000C CALL R6 2 + 0x4C1C0000, // 000D LDNIL R7 + 0x20180C07, // 000E NE R6 R6 R7 + 0x781A0000, // 000F JMPF R6 #0011 + 0x80000C00, // 0010 RET 0 + 0x8C180908, // 0011 GETMET R6 R4 K8 + 0x5C200000, // 0012 MOVE R8 R0 + 0x00260801, // 0013 ADD R9 K4 R1 + 0x7C180600, // 0014 CALL R6 3 + 0x601C0004, // 0015 GETGBL R7 G4 + 0x5C200C00, // 0016 MOVE R8 R6 + 0x7C1C0200, // 0017 CALL R7 1 + 0x1C1C0F09, // 0018 EQ R7 R7 K9 + 0x781E0004, // 0019 JMPF R7 #001F + 0x5C1C0C00, // 001A MOVE R7 R6 + 0x5C200000, // 001B MOVE R8 R0 + 0x5C240400, // 001C MOVE R9 R2 + 0x7C1C0400, // 001D CALL R7 2 + 0x80000E00, // 001E RET 0 + 0x881C010A, // 001F GETMBR R7 R0 K10 + 0x8C1C0F0B, // 0020 GETMET R7 R7 K11 + 0x5C240200, // 0021 MOVE R9 R1 + 0x7C1C0400, // 0022 CALL R7 2 + 0x781E0029, // 0023 JMPF R7 #004E + 0x881C010A, // 0024 GETMBR R7 R0 K10 + 0x941C0E01, // 0025 GETIDX R7 R7 R1 + 0x8C200908, // 0026 GETMET R8 R4 K8 + 0x8828010C, // 0027 GETMBR R10 R0 K12 + 0x002E0807, // 0028 ADD R11 K4 R7 + 0x7C200600, // 0029 CALL R8 3 + 0x5C181000, // 002A MOVE R6 R8 + 0x8C20010D, // 002B GETMET R8 R0 K13 + 0x5C280E00, // 002C MOVE R10 R7 + 0x7C200400, // 002D CALL R8 2 + 0x78220003, // 002E JMPF R8 #0033 + 0x8C20010E, // 002F GETMET R8 R0 K14 + 0x5C280400, // 0030 MOVE R10 R2 + 0x7C200400, // 0031 CALL R8 2 + 0x5C081000, // 0032 MOVE R2 R8 + 0x60200004, // 0033 GETGBL R8 G4 + 0x5C240C00, // 0034 MOVE R9 R6 + 0x7C200200, // 0035 CALL R8 1 + 0x1C201109, // 0036 EQ R8 R8 K9 + 0x78220011, // 0037 JMPF R8 #004A + 0x8C200707, // 0038 GETMET R8 R3 K7 + 0x5C280E00, // 0039 MOVE R10 R7 + 0x582C000F, // 003A LDCONST R11 K15 + 0x7C200600, // 003B CALL R8 3 + 0x1C201102, // 003C EQ R8 R8 K2 + 0x78220005, // 003D JMPF R8 #0044 + 0x5C200C00, // 003E MOVE R8 R6 + 0x8824010C, // 003F GETMBR R9 R0 K12 + 0x5C280400, // 0040 MOVE R10 R2 + 0x582C0002, // 0041 LDCONST R11 K2 + 0x7C200600, // 0042 CALL R8 3 + 0x70020003, // 0043 JMP #0048 + 0x5C200C00, // 0044 MOVE R8 R6 + 0x8824010C, // 0045 GETMBR R9 R0 K12 + 0x5C280400, // 0046 MOVE R10 R2 + 0x7C200400, // 0047 CALL R8 2 + 0x80001000, // 0048 RET 0 + 0x70020002, // 0049 JMP #004D + 0x60200001, // 004A GETGBL R8 G1 + 0x00262007, // 004B ADD R9 K16 R7 + 0x7C200200, // 004C CALL R8 1 + 0x70020003, // 004D JMP #0052 + 0x601C0001, // 004E GETGBL R7 G1 + 0x58200011, // 004F LDCONST R8 K17 + 0x5C240200, // 0050 MOVE R9 R1 + 0x7C1C0400, // 0051 CALL R7 2 + 0x80000000, // 0052 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(lvh_obj_init, /* name */ + be_nested_proto( + 8, /* nstack */ + 5, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_page"), + /* K1 */ be_nested_str_literal("_lv_class"), + /* K2 */ be_nested_str_literal("_lv_obj"), + /* K3 */ be_nested_str_literal("post_init"), + }), + be_str_literal("init"), + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0x90020002, // 0000 SETMBR R0 K0 R2 + 0x4C140000, // 0001 LDNIL R5 + 0x1C140805, // 0002 EQ R5 R4 R5 + 0x78160007, // 0003 JMPF R5 #000C + 0x88140101, // 0004 GETMBR R5 R0 K1 + 0x78160005, // 0005 JMPF R5 #000C + 0x88140101, // 0006 GETMBR R5 R0 K1 + 0x5C180A00, // 0007 MOVE R6 R5 + 0x5C1C0200, // 0008 MOVE R7 R1 + 0x7C180200, // 0009 CALL R6 1 + 0x90020406, // 000A SETMBR R0 K2 R6 + 0x70020000, // 000B JMP #000D + 0x90020404, // 000C SETMBR R0 K2 R4 + 0x8C140103, // 000D GETMET R5 R0 K3 + 0x7C140200, // 000E CALL R5 1 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_value_str +********************************************************************/ +be_local_closure(lvh_obj_set_value_str, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("set_text"), + }), + be_str_literal("set_value_str"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C080400, // 0002 CALL R2 2 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_line_width +********************************************************************/ +be_local_closure(lvh_obj_set_line_width, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_style_line_width"), + /* K2 */ be_const_int(0), + }), + be_str_literal("set_line_width"), + &be_const_str_solidified, + ( &(const binstruction[ 8]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x60100009, // 0002 GETGBL R4 G9 + 0x5C140200, // 0003 MOVE R5 R1 + 0x7C100200, // 0004 CALL R4 1 + 0x58140002, // 0005 LDCONST R5 K2 + 0x7C080600, // 0006 CALL R2 3 + 0x80000000, // 0007 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_toggle +********************************************************************/ +be_local_closure(lvh_obj_set_toggle, /* name */ + be_nested_proto( + 7, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str_literal("string"), + /* K1 */ be_nested_str_literal("toupper"), + /* K2 */ be_nested_str_literal("TRUE"), + /* K3 */ be_nested_str_literal("FALSE"), + /* K4 */ be_nested_str_literal("_lv_obj"), + /* K5 */ be_nested_str_literal("add_state"), + /* K6 */ be_nested_str_literal("lv"), + /* K7 */ be_nested_str_literal("STATE_CHECKED"), + /* K8 */ be_nested_str_literal("clear_state"), + }), + be_str_literal("set_toggle"), + &be_const_str_solidified, + ( &(const binstruction[26]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x8C0C0501, // 0001 GETMET R3 R2 K1 + 0x60140008, // 0002 GETGBL R5 G8 + 0x5C180200, // 0003 MOVE R6 R1 + 0x7C140200, // 0004 CALL R5 1 + 0x7C0C0400, // 0005 CALL R3 2 + 0x5C040600, // 0006 MOVE R1 R3 + 0x1C0C0302, // 0007 EQ R3 R1 K2 + 0x780E0000, // 0008 JMPF R3 #000A + 0x50040200, // 0009 LDBOOL R1 1 0 + 0x1C0C0303, // 000A EQ R3 R1 K3 + 0x780E0000, // 000B JMPF R3 #000D + 0x50040000, // 000C LDBOOL R1 0 0 + 0x78060005, // 000D JMPF R1 #0014 + 0x880C0104, // 000E GETMBR R3 R0 K4 + 0x8C0C0705, // 000F GETMET R3 R3 K5 + 0xB8160C00, // 0010 GETNGBL R5 K6 + 0x88140B07, // 0011 GETMBR R5 R5 K7 + 0x7C0C0400, // 0012 CALL R3 2 + 0x70020004, // 0013 JMP #0019 + 0x880C0104, // 0014 GETMBR R3 R0 K4 + 0x8C0C0708, // 0015 GETMET R3 R3 K8 + 0xB8160C00, // 0016 GETNGBL R5 K6 + 0x88140B07, // 0017 GETMBR R5 R5 K7 + 0x7C0C0400, // 0018 CALL R3 2 + 0x80000000, // 0019 RET 0 }) ) ); @@ -3656,65 +3630,206 @@ be_local_closure(lvh_obj_set_val_rule, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: set_text +********************************************************************/ +be_local_closure(lvh_obj_set_text, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("check_label"), + /* K1 */ be_nested_str_literal("_lv_label"), + /* K2 */ be_nested_str_literal("set_text"), + }), + be_str_literal("set_text"), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x8C080100, // 0000 GETMET R2 R0 K0 + 0x7C080200, // 0001 CALL R2 1 + 0x88080101, // 0002 GETMBR R2 R0 K1 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x60100008, // 0004 GETGBL R4 G8 + 0x5C140200, // 0005 MOVE R5 R1 + 0x7C100200, // 0006 CALL R4 1 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_action +********************************************************************/ +be_local_closure(lvh_obj_get_action, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_action"), + /* K1 */ be_nested_str_literal(""), + }), + be_str_literal("get_action"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x78060001, // 0001 JMPF R1 #0004 + 0x5C080200, // 0002 MOVE R2 R1 + 0x70020000, // 0003 JMP #0005 + 0x58080001, // 0004 LDCONST R2 K1 + 0x80040400, // 0005 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_value_font +********************************************************************/ +be_local_closure(lvh_obj_get_value_font, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str_literal("get_text_font"), + }), + be_str_literal("get_value_font"), + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x7C040200, // 0001 CALL R1 1 + 0x80040200, // 0002 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_hidden +********************************************************************/ +be_local_closure(lvh_obj_get_hidden, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("has_flag"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("OBJ_FLAG_HIDDEN"), + }), + be_str_literal("get_hidden"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0xB80E0400, // 0002 GETNGBL R3 K2 + 0x880C0703, // 0003 GETMBR R3 R3 K3 + 0x7C040400, // 0004 CALL R1 2 + 0x80040200, // 0005 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pad_all +********************************************************************/ +be_local_closure(lvh_obj_get_pad_all, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 0, /* has constants */ + NULL, /* no const */ + be_str_literal("get_pad_all"), + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_text_color +********************************************************************/ +be_local_closure(lvh_obj_get_text_color, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_style_text_color"), + /* K2 */ be_const_int(0), + }), + be_str_literal("get_text_color"), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x580C0002, // 0002 LDCONST R3 K2 + 0x7C040400, // 0003 CALL R1 2 + 0x80040200, // 0004 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: lvh_obj ********************************************************************/ be_local_class(lvh_obj, 12, NULL, - be_nested_map(85, + be_nested_map(88, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_literal("get_enabled", -1), be_const_closure(lvh_obj_get_enabled_closure) }, - { be_const_key_literal("set_val_rule", -1), be_const_closure(lvh_obj_set_val_rule_closure) }, - { be_const_key_literal("get_value_color", -1), be_const_closure(lvh_obj_get_value_color_closure) }, - { be_const_key_literal("set_click", 29), be_const_closure(lvh_obj_set_click_closure) }, - { be_const_key_literal("set_align", -1), be_const_closure(lvh_obj_set_align_closure) }, - { be_const_key_literal("set_hidden", 38), be_const_closure(lvh_obj_set_hidden_closure) }, - { be_const_key_literal("get_mode", -1), be_const_closure(lvh_obj_get_mode_closure) }, - { be_const_key_literal("get_text_rule_formula", 50), be_const_closure(lvh_obj_get_text_rule_formula_closure) }, - { be_const_key_literal("set_pad_all2", -1), be_const_closure(lvh_obj_set_pad_all2_closure) }, - { be_const_key_literal("text_rule_matched", -1), be_const_closure(lvh_obj_text_rule_matched_closure) }, - { be_const_key_literal("_val_rule", -1), be_const_var(5) }, - { be_const_key_literal("setmember", 63), be_const_closure(lvh_obj_setmember_closure) }, - { be_const_key_literal("get_text_font", -1), be_const_closure(lvh_obj_get_text_font_closure) }, - { be_const_key_literal("set_toggle", -1), be_const_closure(lvh_obj_set_toggle_closure) }, - { be_const_key_literal("get_toggle", 6), be_const_closure(lvh_obj_get_toggle_closure) }, - { be_const_key_literal("init", 31), be_const_closure(lvh_obj_init_closure) }, - { be_const_key_literal("id", -1), be_const_var(0) }, - { be_const_key_literal("val_rule_matched", -1), be_const_closure(lvh_obj_val_rule_matched_closure) }, - { be_const_key_literal("set_text_rule", 76), be_const_closure(lvh_obj_set_text_rule_closure) }, - { be_const_key_literal("get_value_str", 59), be_const_closure(lvh_obj_get_value_str_closure) }, - { be_const_key_literal("set_val_rule_formula", -1), be_const_closure(lvh_obj_set_val_rule_formula_closure) }, - { be_const_key_literal("set_value_color", -1), be_const_closure(lvh_obj_set_value_color_closure) }, - { be_const_key_literal("_lv_class", -1), be_const_class(be_class_lv_obj) }, - { be_const_key_literal("_text_rule_format", -1), be_const_var(11) }, - { be_const_key_literal("_val_rule_formula", 12), be_const_var(6) }, - { be_const_key_literal("set_action", -1), be_const_closure(lvh_obj_set_action_closure) }, - { be_const_key_literal("set_text_color", 79), be_const_closure(lvh_obj_set_text_color_closure) }, - { be_const_key_literal("_lv_part2_selector", -1), be_const_nil() }, - { be_const_key_literal("set_value_font", 71), be_const_closure(lvh_obj_set_value_font_closure) }, - { be_const_key_literal("get_obj", -1), be_const_closure(lvh_obj_get_obj_closure) }, - { be_const_key_literal("get_value_font", -1), be_const_closure(lvh_obj_get_value_font_closure) }, - { be_const_key_literal("set_text", -1), be_const_closure(lvh_obj_set_text_closure) }, - { be_const_key_literal("post_init", -1), be_const_closure(lvh_obj_post_init_closure) }, - { be_const_key_literal("_action", -1), be_const_var(4) }, - { be_const_key_literal("get_val_rule", 61), be_const_closure(lvh_obj_get_val_rule_closure) }, - { be_const_key_literal("get_align", 21), be_const_closure(lvh_obj_get_align_closure) }, - { be_const_key_literal("get_pad_top", 60), be_const_closure(lvh_obj_get_pad_top_closure) }, - { be_const_key_literal("parse_color", 18), be_const_static_closure(lvh_obj_parse_color_closure) }, - { be_const_key_literal("set_text_rule_format", -1), be_const_closure(lvh_obj_set_text_rule_format_closure) }, - { be_const_key_literal("get_action", -1), be_const_closure(lvh_obj_get_action_closure) }, - { be_const_key_literal("get_line_width", -1), be_const_closure(lvh_obj_get_line_width_closure) }, - { be_const_key_literal("check_label", -1), be_const_closure(lvh_obj_check_label_closure) }, - { be_const_key_literal("set_value_ofs_x", -1), be_const_closure(lvh_obj_set_value_ofs_x_closure) }, + { be_const_key_literal("set_radius2", 68), be_const_closure(lvh_obj_set_radius2_closure) }, + { be_const_key_literal("register_event_cb", -1), be_const_closure(lvh_obj_register_event_cb_closure) }, { be_const_key_literal("get_text_rule_format", -1), be_const_closure(lvh_obj_get_text_rule_format_closure) }, - { be_const_key_literal("set_value_str", -1), be_const_closure(lvh_obj_set_value_str_closure) }, - { be_const_key_literal("get_pad_left", 32), be_const_closure(lvh_obj_get_pad_left_closure) }, - { be_const_key_literal("get_adjustable", -1), be_const_closure(lvh_obj_get_adjustable_closure) }, - { be_const_key_literal("_page", -1), be_const_var(3) }, - { be_const_key_literal("get_value_ofs_x", -1), be_const_closure(lvh_obj_get_value_ofs_x_closure) }, - { be_const_key_literal("set_radius2", 36), be_const_closure(lvh_obj_set_radius2_closure) }, - { be_const_key_literal("_attr_ignore", -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + { be_const_key_literal("set_value_ofs_x", -1), be_const_closure(lvh_obj_set_value_ofs_x_closure) }, + { be_const_key_literal("get_radius2", -1), be_const_closure(lvh_obj_get_radius2_closure) }, + { be_const_key_literal("_attr_ignore", 30), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { be_const_list( * be_nested_list(10, ( (struct bvalue*) &(const bvalue[]) { be_nested_str_literal("tostring"), @@ -3728,100 +3843,95 @@ be_local_class(lvh_obj, be_nested_str_literal("back"), be_nested_str_literal("berry_run"), })) ) } )) }, - { be_const_key_literal("set_pad_bottom2", 40), be_const_closure(lvh_obj_set_pad_bottom2_closure) }, - { be_const_key_literal("get_click", -1), be_const_closure(lvh_obj_get_click_closure) }, - { be_const_key_literal("register_event_cb", 42), be_const_closure(lvh_obj_register_event_cb_closure) }, - { be_const_key_literal("get_pad_right", -1), be_const_closure(lvh_obj_get_pad_right_closure) }, - { be_const_key_literal("get_pad_bottom", -1), be_const_closure(lvh_obj_get_pad_bottom_closure) }, - { be_const_key_literal("_lv_obj", -1), be_const_var(1) }, - { be_const_key_literal("get_val_rule_formula", -1), be_const_closure(lvh_obj_get_val_rule_formula_closure) }, - { be_const_key_literal("_lv_label", 57), be_const_var(2) }, - { be_const_key_literal("get_text", 62), be_const_closure(lvh_obj_get_text_closure) }, - { be_const_key_literal("_text_rule_formula", -1), be_const_var(9) }, - { be_const_key_literal("set_pad_top2", 55), be_const_closure(lvh_obj_set_pad_top2_closure) }, - { be_const_key_literal("set_line_width", -1), be_const_closure(lvh_obj_set_line_width_closure) }, - { be_const_key_literal("member", -1), be_const_closure(lvh_obj_member_closure) }, + { be_const_key_literal("val_rule_matched", -1), be_const_closure(lvh_obj_val_rule_matched_closure) }, + { be_const_key_literal("set_pad_top2", -1), be_const_closure(lvh_obj_set_pad_top2_closure) }, + { be_const_key_literal("get_value_font", -1), be_const_closure(lvh_obj_get_value_font_closure) }, { be_const_key_literal("_text_rule_function", -1), be_const_var(10) }, - { be_const_key_literal("set_adjustable", -1), be_const_closure(lvh_obj_set_adjustable_closure) }, - { be_const_key_literal("set_text_font", 23), be_const_closure(lvh_obj_set_text_font_closure) }, - { be_const_key_literal("set_pad_left2", 47), be_const_closure(lvh_obj_set_pad_left2_closure) }, + { be_const_key_literal("_text_rule_format", -1), be_const_var(11) }, + { be_const_key_literal("set_text_font", -1), be_const_closure(lvh_obj_set_text_font_closure) }, + { be_const_key_literal("parse_color", -1), be_const_static_closure(lvh_obj_parse_color_closure) }, + { be_const_key_literal("get_text_font", -1), be_const_closure(lvh_obj_get_text_font_closure) }, + { be_const_key_literal("text_rule_matched", 70), be_const_closure(lvh_obj_text_rule_matched_closure) }, + { be_const_key_literal("_lv_class", -1), be_const_class(be_class_lv_obj) }, + { be_const_key_literal("set_text", 78), be_const_closure(lvh_obj_set_text_closure) }, + { be_const_key_literal("set_align", -1), be_const_closure(lvh_obj_set_align_closure) }, + { be_const_key_literal("set_val_rule", 35), be_const_closure(lvh_obj_set_val_rule_closure) }, + { be_const_key_literal("set_val", -1), be_const_closure(lvh_obj_set_val_closure) }, + { be_const_key_literal("get_pad_right", 80), be_const_closure(lvh_obj_get_pad_right_closure) }, + { be_const_key_literal("_text_rule_formula", 79), be_const_var(9) }, + { be_const_key_literal("set_action", -1), be_const_closure(lvh_obj_set_action_closure) }, + { be_const_key_literal("get_value_ofs_x", 86), be_const_closure(lvh_obj_get_value_ofs_x_closure) }, + { be_const_key_literal("set_value_ofs_y", 6), be_const_closure(lvh_obj_set_value_ofs_y_closure) }, + { be_const_key_literal("remove_trailing_zeroes", 41), be_const_static_closure(lvh_obj_remove_trailing_zeroes_closure) }, + { be_const_key_literal("post_init", 18), be_const_closure(lvh_obj_post_init_closure) }, + { be_const_key_literal("get_mode", -1), be_const_closure(lvh_obj_get_mode_closure) }, + { be_const_key_literal("_action", -1), be_const_var(4) }, + { be_const_key_literal("_lv_label", 7), be_const_var(2) }, + { be_const_key_literal("set_toggle", 31), be_const_closure(lvh_obj_set_toggle_closure) }, { be_const_key_literal("_attr_map", -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(65, + be_const_map( * be_nested_map(26, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_literal("x", -1), be_nested_str_literal("x") }, - { be_const_key_literal("pad_left2", -1), be_const_nil() }, - { be_const_key_literal("end_angle", -1), be_nested_str_literal("bg_end_angle") }, { be_const_key_literal("rotation", -1), be_nested_str_literal("rotation") }, - { be_const_key_literal("radius", -1), be_nested_str_literal("style_radius") }, - { be_const_key_literal("value_ofs_y", -1), be_const_nil() }, - { be_const_key_literal("val", 38), be_nested_str_literal("value") }, - { be_const_key_literal("line_width", -1), be_const_nil() }, - { be_const_key_literal("speed", 57), be_const_nil() }, - { be_const_key_literal("radius2", -1), be_const_nil() }, - { be_const_key_literal("qr_text", -1), be_const_nil() }, - { be_const_key_literal("text_rule_formula", 42), be_const_nil() }, - { be_const_key_literal("bg_grad_dir", -1), be_nested_str_literal("style_bg_grad_dir") }, - { be_const_key_literal("mode", 59), be_const_nil() }, { be_const_key_literal("bg_opa", -1), be_nested_str_literal("style_bg_opa") }, - { be_const_key_literal("text", -1), be_const_nil() }, - { be_const_key_literal("value_color", -1), be_const_nil() }, - { be_const_key_literal("enabled", 29), be_const_nil() }, - { be_const_key_literal("text_font", -1), be_const_nil() }, - { be_const_key_literal("text_rule_format", -1), be_const_nil() }, - { be_const_key_literal("value_str", 3), be_const_nil() }, - { be_const_key_literal("border_width", 62), be_nested_str_literal("style_border_width") }, - { be_const_key_literal("max", -1), be_const_nil() }, - { be_const_key_literal("angle", -1), be_const_nil() }, - { be_const_key_literal("text_rule", 21), be_const_nil() }, - { be_const_key_literal("min", 19), be_const_nil() }, - { be_const_key_literal("start_angle", 32), be_nested_str_literal("bg_start_angle") }, - { be_const_key_literal("qr_light_color", -1), be_const_nil() }, + { be_const_key_literal("end_angle", 3), be_nested_str_literal("bg_end_angle") }, + { be_const_key_literal("w", 18), be_nested_str_literal("width") }, + { be_const_key_literal("src", 6), be_nested_str_literal("src") }, + { be_const_key_literal("x", -1), be_nested_str_literal("x") }, + { be_const_key_literal("border_color", -1), be_nested_str_literal("style_border_color") }, + { be_const_key_literal("bg_grad_color", 0), be_nested_str_literal("style_bg_grad_color") }, + { be_const_key_literal("pad_all", -1), be_nested_str_literal("style_pad_all") }, + { be_const_key_literal("bg_color", 20), be_nested_str_literal("style_bg_color") }, + { be_const_key_literal("y", 8), be_nested_str_literal("y") }, + { be_const_key_literal("line_color", -1), be_nested_str_literal("style_line_color") }, + { be_const_key_literal("image_recolor_opa", 10), be_nested_str_literal("style_img_recolor_opa") }, + { be_const_key_literal("start_angle", 5), be_nested_str_literal("bg_start_angle") }, + { be_const_key_literal("end_angle1", 11), be_nested_str_literal("end_angle") }, { be_const_key_literal("border_side", -1), be_nested_str_literal("style_border_side") }, - { be_const_key_literal("src", -1), be_nested_str_literal("src") }, - { be_const_key_literal("w", 35), be_nested_str_literal("width") }, - { be_const_key_literal("value_font", 18), be_const_nil() }, - { be_const_key_literal("pad_bottom2", -1), be_const_nil() }, - { be_const_key_literal("value_ofs_x", -1), be_const_nil() }, - { be_const_key_literal("pad_right", 23), be_nested_str_literal("style_pad_right") }, + { be_const_key_literal("pad_bottom", 9), be_nested_str_literal("style_pad_bottom") }, + { be_const_key_literal("radius", 4), be_nested_str_literal("style_radius") }, { be_const_key_literal("pad_left", -1), be_nested_str_literal("style_pad_left") }, - { be_const_key_literal("h", -1), be_nested_str_literal("height") }, - { be_const_key_literal("line_color", 43), be_nested_str_literal("style_line_color") }, { be_const_key_literal("image_recolor", -1), be_nested_str_literal("style_img_recolor") }, - { be_const_key_literal("qr_dark_color", 22), be_const_nil() }, + { be_const_key_literal("border_width", -1), be_nested_str_literal("style_border_width") }, + { be_const_key_literal("pad_right", -1), be_nested_str_literal("style_pad_right") }, { be_const_key_literal("start_angle1", -1), be_nested_str_literal("start_angle") }, - { be_const_key_literal("align", 30), be_const_nil() }, - { be_const_key_literal("text_color", -1), be_const_nil() }, - { be_const_key_literal("y", -1), be_nested_str_literal("y") }, - { be_const_key_literal("val_rule", 15), be_const_nil() }, - { be_const_key_literal("qr_size", 49), be_const_nil() }, - { be_const_key_literal("bg_grad_color", -1), be_nested_str_literal("style_bg_grad_color") }, - { be_const_key_literal("asjustable", 54), be_const_nil() }, - { be_const_key_literal("hidden", 40), be_const_nil() }, - { be_const_key_literal("pad_top2", -1), be_const_nil() }, - { be_const_key_literal("pad_top", -1), be_nested_str_literal("style_pad_top") }, - { be_const_key_literal("end_angle1", 37), be_nested_str_literal("end_angle") }, - { be_const_key_literal("click", -1), be_const_nil() }, - { be_const_key_literal("pad_right2", -1), be_const_nil() }, - { be_const_key_literal("action", -1), be_const_nil() }, - { be_const_key_literal("image_recolor_opa", -1), be_nested_str_literal("style_img_recolor_opa") }, - { be_const_key_literal("border_color", 33), be_nested_str_literal("style_border_color") }, - { be_const_key_literal("toggle", -1), be_const_nil() }, - { be_const_key_literal("pad_all2", -1), be_const_nil() }, - { be_const_key_literal("type", -1), be_const_nil() }, - { be_const_key_literal("line_width1", -1), be_const_nil() }, - { be_const_key_literal("val_rule_formula", -1), be_const_nil() }, - { be_const_key_literal("pad_bottom", -1), be_nested_str_literal("style_pad_bottom") }, - { be_const_key_literal("bg_color", -1), be_nested_str_literal("style_bg_color") }, - { be_const_key_literal("pad_all", 55), be_nested_str_literal("style_pad_all") }, + { be_const_key_literal("h", -1), be_nested_str_literal("height") }, + { be_const_key_literal("pad_top", 16), be_nested_str_literal("style_pad_top") }, + { be_const_key_literal("bg_grad_dir", 14), be_nested_str_literal("style_bg_grad_dir") }, })) ) } )) }, + { be_const_key_literal("set_line_width", -1), be_const_closure(lvh_obj_set_line_width_closure) }, + { be_const_key_literal("set_value_str", 72), be_const_closure(lvh_obj_set_value_str_closure) }, + { be_const_key_literal("is_color_attribute", -1), be_const_static_closure(lvh_obj_is_color_attribute_closure) }, + { be_const_key_literal("_lv_obj", -1), be_const_var(1) }, + { be_const_key_literal("set_value_color", -1), be_const_closure(lvh_obj_set_value_color_closure) }, + { be_const_key_literal("get_value_color", -1), be_const_closure(lvh_obj_get_value_color_closure) }, + { be_const_key_literal("get_val_rule", -1), be_const_closure(lvh_obj_get_val_rule_closure) }, + { be_const_key_literal("get_val", -1), be_const_closure(lvh_obj_get_val_closure) }, + { be_const_key_literal("get_click", -1), be_const_closure(lvh_obj_get_click_closure) }, + { be_const_key_literal("get_enabled", 81), be_const_closure(lvh_obj_get_enabled_closure) }, + { be_const_key_literal("set_adjustable", -1), be_const_closure(lvh_obj_set_adjustable_closure) }, + { be_const_key_literal("get_pad_left", 16), be_const_closure(lvh_obj_get_pad_left_closure) }, { be_const_key_literal("get_value_ofs_y", -1), be_const_closure(lvh_obj_get_value_ofs_y_closure) }, - { be_const_key_literal("_text_rule", -1), be_const_var(8) }, - { be_const_key_literal("get_hidden", 78), be_const_closure(lvh_obj_get_hidden_closure) }, - { be_const_key_literal("set_pad_right2", 33), be_const_closure(lvh_obj_set_pad_right2_closure) }, - { be_const_key_literal("is_color_attribute", 20), be_const_static_closure(lvh_obj_is_color_attribute_closure) }, - { be_const_key_literal("set_value_ofs_y", -1), be_const_closure(lvh_obj_set_value_ofs_y_closure) }, - { be_const_key_literal("set_mode", -1), be_const_closure(lvh_obj_set_mode_closure) }, - { be_const_key_literal("set_text_rule_formula", -1), be_const_closure(lvh_obj_set_text_rule_formula_closure) }, + { be_const_key_literal("_val_rule_formula", 76), be_const_var(6) }, + { be_const_key_literal("get_text_rule", 34), be_const_closure(lvh_obj_get_text_rule_closure) }, + { be_const_key_literal("set_value_font", 74), be_const_closure(lvh_obj_set_value_font_closure) }, + { be_const_key_literal("_val_rule", -1), be_const_var(5) }, + { be_const_key_literal("event_cb", 58), be_const_closure(lvh_obj_event_cb_closure) }, + { be_const_key_literal("set_text_rule", -1), be_const_closure(lvh_obj_set_text_rule_closure) }, + { be_const_key_literal("get_adjustable", -1), be_const_closure(lvh_obj_get_adjustable_closure) }, + { be_const_key_literal("get_toggle", -1), be_const_closure(lvh_obj_get_toggle_closure) }, + { be_const_key_literal("get_value_str", -1), be_const_closure(lvh_obj_get_value_str_closure) }, + { be_const_key_literal("set_pad_right2", -1), be_const_closure(lvh_obj_set_pad_right2_closure) }, + { be_const_key_literal("set_val_rule_formula", 66), be_const_closure(lvh_obj_set_val_rule_formula_closure) }, + { be_const_key_literal("id", 5), be_const_var(0) }, + { be_const_key_literal("set_pad_bottom2", 33), be_const_closure(lvh_obj_set_pad_bottom2_closure) }, + { be_const_key_literal("get_pad_top", 36), be_const_closure(lvh_obj_get_pad_top_closure) }, + { be_const_key_literal("get_val_rule_formula", -1), be_const_closure(lvh_obj_get_val_rule_formula_closure) }, + { be_const_key_literal("set_hidden", -1), be_const_closure(lvh_obj_set_hidden_closure) }, + { be_const_key_literal("_page", -1), be_const_var(3) }, + { be_const_key_literal("check_label", -1), be_const_closure(lvh_obj_check_label_closure) }, + { be_const_key_literal("get_text", -1), be_const_closure(lvh_obj_get_text_closure) }, + { be_const_key_literal("set_text_rule_format", 60), be_const_closure(lvh_obj_set_text_rule_format_closure) }, + { be_const_key_literal("set_pad_all2", -1), be_const_closure(lvh_obj_set_pad_all2_closure) }, { be_const_key_literal("_event_map", -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { be_const_map( * be_nested_map(7, ( (struct bmapnode*) &(const bmapnode[]) { @@ -3833,13 +3943,27 @@ be_local_class(lvh_obj, { be_const_key_int(5, -1), be_nested_str_literal("long") }, { be_const_key_int(6, -1), be_nested_str_literal("hold") }, })) ) } )) }, - { be_const_key_literal("get_radius2", -1), be_const_closure(lvh_obj_get_radius2_closure) }, + { be_const_key_literal("set_text_color", -1), be_const_closure(lvh_obj_set_text_color_closure) }, + { be_const_key_literal("_text_rule", -1), be_const_var(8) }, + { be_const_key_literal("get_pad_bottom", -1), be_const_closure(lvh_obj_get_pad_bottom_closure) }, + { be_const_key_literal("_lv_part2_selector", -1), be_const_nil() }, + { be_const_key_literal("set_pad_left2", 42), be_const_closure(lvh_obj_set_pad_left2_closure) }, + { be_const_key_literal("get_line_width", 11), be_const_closure(lvh_obj_get_line_width_closure) }, + { be_const_key_literal("setmember", -1), be_const_closure(lvh_obj_setmember_closure) }, + { be_const_key_literal("set_mode", -1), be_const_closure(lvh_obj_set_mode_closure) }, + { be_const_key_literal("init", -1), be_const_closure(lvh_obj_init_closure) }, + { be_const_key_literal("get_obj", -1), be_const_closure(lvh_obj_get_obj_closure) }, + { be_const_key_literal("set_enabled", 32), be_const_closure(lvh_obj_set_enabled_closure) }, + { be_const_key_literal("get_text_rule_formula", -1), be_const_closure(lvh_obj_get_text_rule_formula_closure) }, + { be_const_key_literal("get_align", -1), be_const_closure(lvh_obj_get_align_closure) }, + { be_const_key_literal("set_click", 2), be_const_closure(lvh_obj_set_click_closure) }, + { be_const_key_literal("_val_rule_function", -1), be_const_var(7) }, + { be_const_key_literal("get_action", -1), be_const_closure(lvh_obj_get_action_closure) }, + { be_const_key_literal("member", 8), be_const_closure(lvh_obj_member_closure) }, + { be_const_key_literal("get_hidden", -1), be_const_closure(lvh_obj_get_hidden_closure) }, { be_const_key_literal("get_pad_all", -1), be_const_closure(lvh_obj_get_pad_all_closure) }, + { be_const_key_literal("set_text_rule_formula", -1), be_const_closure(lvh_obj_set_text_rule_formula_closure) }, { be_const_key_literal("get_text_color", -1), be_const_closure(lvh_obj_get_text_color_closure) }, - { be_const_key_literal("_val_rule_function", 10), be_const_var(7) }, - { be_const_key_literal("event_cb", -1), be_const_closure(lvh_obj_event_cb_closure) }, - { be_const_key_literal("get_text_rule", 4), be_const_closure(lvh_obj_get_text_rule_closure) }, - { be_const_key_literal("set_enabled", 1), be_const_closure(lvh_obj_set_enabled_closure) }, })), be_str_literal("lvh_obj") ); @@ -4275,6 +4399,210 @@ void be_load_lvh_img_class(bvm *vm) { be_pop(vm, 1); } +/******************************************************************** +** Solidified function: set_options +********************************************************************/ +be_local_closure(lvh_roller_set_options, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_options"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("ROLLER_MODE_NORMAL"), + }), + be_str_literal("set_options"), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0xB8160400, // 0003 GETNGBL R5 K2 + 0x88140B03, // 0004 GETMBR R5 R5 K3 + 0x7C080600, // 0005 CALL R2 3 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_text +********************************************************************/ +be_local_closure(lvh_roller_get_text, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str_literal("resize"), + /* K1 */ be_nested_str_literal("_lv_obj"), + /* K2 */ be_nested_str_literal("get_selected_str"), + /* K3 */ be_nested_str_literal("_buffer"), + /* K4 */ be_nested_str_literal("remove_trailing_zeroes"), + /* K5 */ be_nested_str_literal("asstring"), + }), + be_str_literal("get_text"), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x60040015, // 0000 GETGBL R1 G21 + 0x7C040000, // 0001 CALL R1 0 + 0x8C040300, // 0002 GETMET R1 R1 K0 + 0x540E00FF, // 0003 LDINT R3 256 + 0x7C040400, // 0004 CALL R1 2 + 0x88080101, // 0005 GETMBR R2 R0 K1 + 0x8C080502, // 0006 GETMET R2 R2 K2 + 0x8C100303, // 0007 GETMET R4 R1 K3 + 0x7C100200, // 0008 CALL R4 1 + 0x541600FF, // 0009 LDINT R5 256 + 0x7C080600, // 000A CALL R2 3 + 0x8C080104, // 000B GETMET R2 R0 K4 + 0x5C100200, // 000C MOVE R4 R1 + 0x7C080400, // 000D CALL R2 2 + 0x5C040400, // 000E MOVE R1 R2 + 0x8C080305, // 000F GETMET R2 R1 K5 + 0x7C080200, // 0010 CALL R2 1 + 0x80040400, // 0011 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_options +********************************************************************/ +be_local_closure(lvh_roller_get_options, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_options"), + }), + be_str_literal("get_options"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_val +********************************************************************/ +be_local_closure(lvh_roller_set_val, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_selected"), + /* K2 */ be_const_int(0), + }), + be_str_literal("set_val"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x58140002, // 0003 LDCONST R5 K2 + 0x7C080600, // 0004 CALL R2 3 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_text +********************************************************************/ +be_local_closure(lvh_roller_set_text, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("attribute_error"), + /* K1 */ be_nested_str_literal("set_text unsupported on roller"), + }), + be_str_literal("set_text"), + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0xB0060101, // 0000 RAISE 1 K0 K1 + 0x80000000, // 0001 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_val +********************************************************************/ +be_local_closure(lvh_roller_get_val, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_selected"), + }), + be_str_literal("get_val"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: lvh_roller ********************************************************************/ @@ -4282,9 +4610,15 @@ extern const bclass be_class_lvh_obj; be_local_class(lvh_roller, 0, &be_class_lvh_obj, - be_nested_map(1, + be_nested_map(7, ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_literal("set_options", 2), be_const_closure(lvh_roller_set_options_closure) }, + { be_const_key_literal("get_text", -1), be_const_closure(lvh_roller_get_text_closure) }, + { be_const_key_literal("get_options", -1), be_const_closure(lvh_roller_get_options_closure) }, { be_const_key_literal("_lv_class", -1), be_const_class(be_class_lv_roller) }, + { be_const_key_literal("set_text", -1), be_const_closure(lvh_roller_set_text_closure) }, + { be_const_key_literal("set_val", 4), be_const_closure(lvh_roller_set_val_closure) }, + { be_const_key_literal("get_val", -1), be_const_closure(lvh_roller_get_val_closure) }, })), be_str_literal("lvh_roller") ); @@ -4338,6 +4672,39 @@ void be_load_lvh_bar_class(bvm *vm) { be_pop(vm, 1); } +/******************************************************************** +** Solidified function: set_val +********************************************************************/ +be_local_closure(lvh_slider_set_val, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_value"), + /* K2 */ be_const_int(0), + }), + be_str_literal("set_val"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x58140002, // 0003 LDCONST R5 K2 + 0x7C080600, // 0004 CALL R2 3 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: lvh_slider ********************************************************************/ @@ -4345,9 +4712,10 @@ extern const bclass be_class_lvh_obj; be_local_class(lvh_slider, 0, &be_class_lvh_obj, - be_nested_map(1, + be_nested_map(2, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_literal("_lv_class", -1), be_const_class(be_class_lv_slider) }, + { be_const_key_literal("set_val", -1), be_const_closure(lvh_slider_set_val_closure) }, + { be_const_key_literal("_lv_class", 0), be_const_class(be_class_lv_slider) }, })), be_str_literal("lvh_slider") ); @@ -4776,6 +5144,370 @@ void be_load_lvh_textarea_class(bvm *vm) { be_pop(vm, 1); } +/******************************************************************** +** Solidified function: get_val +********************************************************************/ +be_local_closure(lvh_dropdown_get_val, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_selected"), + }), + be_str_literal("get_val"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_direction +********************************************************************/ +be_local_closure(lvh_dropdown_set_direction, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_dir"), + /* K2 */ be_nested_str_literal("_dir"), + }), + be_str_literal("set_direction"), + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x60100009, // 0002 GETGBL R4 G9 + 0x5C140200, // 0003 MOVE R5 R1 + 0x7C100200, // 0004 CALL R4 1 + 0x88140102, // 0005 GETMBR R5 R0 K2 + 0x94100A04, // 0006 GETIDX R4 R5 R4 + 0x7C080400, // 0007 CALL R2 2 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_options +********************************************************************/ +be_local_closure(lvh_dropdown_set_options, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_options"), + /* K2 */ be_nested_str_literal("lv"), + /* K3 */ be_nested_str_literal("ROLLER_MODE_NORMAL"), + }), + be_str_literal("set_options"), + &be_const_str_solidified, + ( &(const binstruction[ 7]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0xB8160400, // 0003 GETNGBL R5 K2 + 0x88140B03, // 0004 GETMBR R5 R5 K3 + 0x7C080600, // 0005 CALL R2 3 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_val +********************************************************************/ +be_local_closure(lvh_dropdown_set_val, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_selected"), + /* K2 */ be_const_int(0), + }), + be_str_literal("set_val"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x58140002, // 0003 LDCONST R5 K2 + 0x7C080600, // 0004 CALL R2 3 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_text +********************************************************************/ +be_local_closure(lvh_dropdown_get_text, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_text"), + /* K2 */ be_nested_str_literal("resize"), + /* K3 */ be_nested_str_literal("get_selected_str"), + /* K4 */ be_nested_str_literal("_buffer"), + /* K5 */ be_nested_str_literal("remove_trailing_zeroes"), + /* K6 */ be_nested_str_literal("asstring"), + }), + be_str_literal("get_text"), + &be_const_str_solidified, + ( &(const binstruction[27]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x4C080000, // 0003 LDNIL R2 + 0x1C080202, // 0004 EQ R2 R1 R2 + 0x780A0012, // 0005 JMPF R2 #0019 + 0x60080015, // 0006 GETGBL R2 G21 + 0x7C080000, // 0007 CALL R2 0 + 0x8C080502, // 0008 GETMET R2 R2 K2 + 0x541200FF, // 0009 LDINT R4 256 + 0x7C080400, // 000A CALL R2 2 + 0x880C0100, // 000B GETMBR R3 R0 K0 + 0x8C0C0703, // 000C GETMET R3 R3 K3 + 0x8C140504, // 000D GETMET R5 R2 K4 + 0x7C140200, // 000E CALL R5 1 + 0x541A00FF, // 000F LDINT R6 256 + 0x7C0C0600, // 0010 CALL R3 3 + 0x8C0C0105, // 0011 GETMET R3 R0 K5 + 0x5C140400, // 0012 MOVE R5 R2 + 0x7C0C0400, // 0013 CALL R3 2 + 0x5C080600, // 0014 MOVE R2 R3 + 0x8C0C0506, // 0015 GETMET R3 R2 K6 + 0x7C0C0200, // 0016 CALL R3 1 + 0x80040600, // 0017 RET 1 R3 + 0x70020000, // 0018 JMP #001A + 0x80040200, // 0019 RET 1 R1 + 0x80000000, // 001A RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_direction +********************************************************************/ +be_local_closure(lvh_dropdown_get_direction, /* name */ + be_nested_proto( + 5, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_dir"), + /* K2 */ be_const_int(0), + /* K3 */ be_nested_str_literal("_dir"), + /* K4 */ be_const_int(1), + }), + be_str_literal("get_direction"), + &be_const_str_solidified, + ( &(const binstruction[18]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x58080002, // 0003 LDCONST R2 K2 + 0x600C000C, // 0004 GETGBL R3 G12 + 0x88100103, // 0005 GETMBR R4 R0 K3 + 0x7C0C0200, // 0006 CALL R3 1 + 0x140C0403, // 0007 LT R3 R2 R3 + 0x780E0006, // 0008 JMPF R3 #0010 + 0x880C0103, // 0009 GETMBR R3 R0 K3 + 0x940C0602, // 000A GETIDX R3 R3 R2 + 0x1C0C0203, // 000B EQ R3 R1 R3 + 0x780E0000, // 000C JMPF R3 #000E + 0x80040400, // 000D RET 1 R2 + 0x00080504, // 000E ADD R2 R2 K4 + 0x7001FFF3, // 000F JMP #0004 + 0x540DFFFE, // 0010 LDINT R3 -1 + 0x80040600, // 0011 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_show_selected +********************************************************************/ +be_local_closure(lvh_dropdown_set_show_selected, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_text"), + }), + be_str_literal("set_show_selected"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x78060003, // 0000 JMPF R1 #0005 + 0x88080100, // 0001 GETMBR R2 R0 K0 + 0x8C080501, // 0002 GETMET R2 R2 K1 + 0x4C100000, // 0003 LDNIL R4 + 0x7C080400, // 0004 CALL R2 2 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_text +********************************************************************/ +be_local_closure(lvh_dropdown_set_text, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("set_text"), + }), + be_str_literal("set_text"), + &be_const_str_solidified, + ( &(const binstruction[ 5]) { /* code */ + 0x88080100, // 0000 GETMBR R2 R0 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100200, // 0002 MOVE R4 R1 + 0x7C080400, // 0003 CALL R2 2 + 0x80000000, // 0004 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_options +********************************************************************/ +be_local_closure(lvh_dropdown_get_options, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_options"), + }), + be_str_literal("get_options"), + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_show_selected +********************************************************************/ +be_local_closure(lvh_dropdown_get_show_selected, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str_literal("_lv_obj"), + /* K1 */ be_nested_str_literal("get_text"), + }), + be_str_literal("get_show_selected"), + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x4C080000, // 0003 LDNIL R2 + 0x1C080202, // 0004 EQ R2 R1 R2 + 0x80040400, // 0005 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified class: lvh_dropdown ********************************************************************/ @@ -4783,9 +5515,27 @@ extern const bclass be_class_lvh_obj; be_local_class(lvh_dropdown, 0, &be_class_lvh_obj, - be_nested_map(1, + be_nested_map(12, ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_literal("get_show_selected", 8), be_const_closure(lvh_dropdown_get_show_selected_closure) }, + { be_const_key_literal("set_direction", -1), be_const_closure(lvh_dropdown_set_direction_closure) }, + { be_const_key_literal("set_options", -1), be_const_closure(lvh_dropdown_set_options_closure) }, + { be_const_key_literal("set_val", 4), be_const_closure(lvh_dropdown_set_val_closure) }, + { be_const_key_literal("get_text", -1), be_const_closure(lvh_dropdown_get_text_closure) }, + { be_const_key_literal("get_direction", 9), be_const_closure(lvh_dropdown_get_direction_closure) }, { be_const_key_literal("_lv_class", -1), be_const_class(be_class_lv_dropdown) }, + { be_const_key_literal("set_show_selected", 6), be_const_closure(lvh_dropdown_set_show_selected_closure) }, + { be_const_key_literal("set_text", -1), be_const_closure(lvh_dropdown_set_text_closure) }, + { be_const_key_literal("_dir", -1), be_const_simple_instance(be_nested_simple_instance(&be_class_list, { + be_const_list( * be_nested_list(4, + ( (struct bvalue*) &(const bvalue[]) { + be_const_int(8), + be_const_int(4), + be_const_int(1), + be_const_int(2), + })) ) } )) }, + { be_const_key_literal("get_options", -1), be_const_closure(lvh_dropdown_get_options_closure) }, + { be_const_key_literal("get_val", 0), be_const_closure(lvh_dropdown_get_val_closure) }, })), be_str_literal("lvh_dropdown") ); diff --git a/lib/libesp32/berry_tasmota/src/be_partition_core_module.c b/lib/libesp32/berry_tasmota/src/be_partition_core_module.c index d894bbede..68de711f5 100644 --- a/lib/libesp32/berry_tasmota/src/be_partition_core_module.c +++ b/lib/libesp32/berry_tasmota/src/be_partition_core_module.c @@ -696,8 +696,8 @@ be_local_closure(Partition_get_active, /* name */ ********************************************************************/ be_local_closure(Partition_switch_factory, /* name */ be_nested_proto( - 4, /* nstack */ - 1, /* argc */ + 6, /* nstack */ + 2, /* argc */ 2, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -706,15 +706,16 @@ be_local_closure(Partition_switch_factory, /* name */ 1, /* has constants */ ( &(const bvalue[ 2]) { /* constants */ /* K0 */ be_nested_str(flash), - /* K1 */ be_nested_str(rollback), + /* K1 */ be_nested_str(factory), }), &be_const_str_switch_factory, &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x80000000, // 0003 RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0xA40A0000, // 0000 IMPORT R2 K0 + 0x8C0C0501, // 0001 GETMET R3 R2 K1 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C0C0400, // 0003 CALL R3 2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -837,44 +838,47 @@ be_local_closure(Partition_ota_max, /* name */ NULL, /* no sub protos */ 1, /* has constants */ ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str(slots), - /* K2 */ be_nested_str(type), + /* K0 */ be_nested_str(slots), + /* K1 */ be_nested_str(type), + /* K2 */ be_const_int(0), /* K3 */ be_nested_str(subtype), /* K4 */ be_nested_str(stop_iteration), }), &be_const_str_ota_max, &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 + ( &(const binstruction[32]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 0x60080010, // 0001 GETGBL R2 G16 - 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x880C0100, // 0002 GETMBR R3 R0 K0 0x7C080200, // 0003 CALL R2 1 - 0xA8020013, // 0004 EXBLK 0 #0019 + 0xA8020016, // 0004 EXBLK 0 #001C 0x5C0C0400, // 0005 MOVE R3 R2 0x7C0C0000, // 0006 CALL R3 0 - 0x88100702, // 0007 GETMBR R4 R3 K2 - 0x1C100900, // 0008 EQ R4 R4 K0 - 0x7812000D, // 0009 JMPF R4 #0018 + 0x88100701, // 0007 GETMBR R4 R3 K1 + 0x1C100902, // 0008 EQ R4 R4 K2 + 0x78120010, // 0009 JMPF R4 #001B 0x88100703, // 000A GETMBR R4 R3 K3 0x5416000F, // 000B LDINT R5 16 0x28100805, // 000C GE R4 R4 R5 - 0x78120009, // 000D JMPF R4 #0018 + 0x7812000C, // 000D JMPF R4 #001B 0x88100703, // 000E GETMBR R4 R3 K3 0x5416001F, // 000F LDINT R5 32 0x14100805, // 0010 LT R4 R4 R5 - 0x78120005, // 0011 JMPF R4 #0018 + 0x78120008, // 0011 JMPF R4 #001B 0x88100703, // 0012 GETMBR R4 R3 K3 0x5416000F, // 0013 LDINT R5 16 0x04100805, // 0014 SUB R4 R4 R5 - 0x24140801, // 0015 GT R5 R4 R1 - 0x78160000, // 0016 JMPF R5 #0018 - 0x5C040800, // 0017 MOVE R1 R4 - 0x7001FFEB, // 0018 JMP #0005 - 0x58080004, // 0019 LDCONST R2 K4 - 0xAC080200, // 001A CATCH R2 1 0 - 0xB0080000, // 001B RAISE 2 R0 R0 - 0x80040200, // 001C RET 1 R1 + 0x4C140000, // 0015 LDNIL R5 + 0x1C140205, // 0016 EQ R5 R1 R5 + 0x74160001, // 0017 JMPT R5 #001A + 0x24140801, // 0018 GT R5 R4 R1 + 0x78160000, // 0019 JMPF R5 #001B + 0x5C040800, // 001A MOVE R1 R4 + 0x7001FFE8, // 001B JMP #0005 + 0x58080004, // 001C LDCONST R2 K4 + 0xAC080200, // 001D CATCH R2 1 0 + 0xB0080000, // 001E RAISE 2 R0 R0 + 0x80040200, // 001F RET 1 R1 }) ) ); @@ -1842,7 +1846,7 @@ be_local_closure(Partition_info_is_ota, /* name */ ********************************************************************/ be_local_closure(Partition_info_get_image_size, /* name */ be_nested_proto( - 13, /* nstack */ + 14, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -1850,24 +1854,25 @@ be_local_closure(Partition_info_get_image_size, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[13]) { /* constants */ + ( &(const bvalue[14]) { /* constants */ /* K0 */ be_nested_str(flash), /* K1 */ be_nested_str(is_ota), /* K2 */ be_nested_str(is_factory), /* K3 */ be_nested_str(start), - /* K4 */ be_nested_str(read), - /* K5 */ be_const_int(1), - /* K6 */ be_nested_str(get), - /* K7 */ be_const_int(0), - /* K8 */ be_nested_str(tasmota), - /* K9 */ be_nested_str(log), - /* K10 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27), - /* K11 */ be_nested_str(_X27_X20_X2D_X20), - /* K12 */ be_const_int(2), + /* K4 */ be_nested_str(size), + /* K5 */ be_nested_str(read), + /* K6 */ be_const_int(1), + /* K7 */ be_nested_str(get), + /* K8 */ be_const_int(0), + /* K9 */ be_nested_str(tasmota), + /* K10 */ be_nested_str(log), + /* K11 */ be_nested_str(BRY_X3A_X20Exception_X3E_X20_X27), + /* K12 */ be_nested_str(_X27_X20_X2D_X20), + /* K13 */ be_const_int(2), }), &be_const_str_get_image_size, &be_const_str_solidified, - ( &(const binstruction[78]) { /* code */ + ( &(const binstruction[85]) { /* code */ 0xA4060000, // 0000 IMPORT R1 K0 0x8C080101, // 0001 GETMET R2 R0 K1 0x7C080200, // 0002 CALL R2 1 @@ -1879,73 +1884,80 @@ be_local_closure(Partition_info_get_image_size, /* name */ 0x740A0001, // 0008 JMPT R2 #000B 0x5409FFFE, // 0009 LDINT R2 -1 0x80040400, // 000A RET 1 R2 - 0xA8020033, // 000B EXBLK 0 #0040 + 0xA802003A, // 000B EXBLK 0 #0047 0x88080103, // 000C GETMBR R2 R0 K3 - 0x8C0C0304, // 000D GETMET R3 R1 K4 - 0x5C140400, // 000E MOVE R5 R2 - 0x58180005, // 000F LDCONST R6 K5 - 0x7C0C0600, // 0010 CALL R3 3 - 0x8C0C0706, // 0011 GETMET R3 R3 K6 - 0x58140007, // 0012 LDCONST R5 K7 - 0x58180005, // 0013 LDCONST R6 K5 - 0x7C0C0600, // 0014 CALL R3 3 - 0x541200E8, // 0015 LDINT R4 233 - 0x20100604, // 0016 NE R4 R3 R4 - 0x78120002, // 0017 JMPF R4 #001B - 0x5411FFFE, // 0018 LDINT R4 -1 - 0xA8040001, // 0019 EXBLK 1 1 - 0x80040800, // 001A RET 1 R4 - 0x8C100304, // 001B GETMET R4 R1 K4 - 0x00180505, // 001C ADD R6 R2 K5 - 0x581C0005, // 001D LDCONST R7 K5 - 0x7C100600, // 001E CALL R4 3 - 0x8C100906, // 001F GETMET R4 R4 K6 - 0x58180007, // 0020 LDCONST R6 K7 - 0x581C0005, // 0021 LDCONST R7 K5 - 0x7C100600, // 0022 CALL R4 3 - 0x5416001F, // 0023 LDINT R5 32 - 0x00140405, // 0024 ADD R5 R2 R5 - 0x58180007, // 0025 LDCONST R6 K7 - 0x141C0C04, // 0026 LT R7 R6 R4 - 0x781E0011, // 0027 JMPF R7 #003A - 0x8C1C0304, // 0028 GETMET R7 R1 K4 - 0x54260007, // 0029 LDINT R9 8 - 0x04240A09, // 002A SUB R9 R5 R9 - 0x542A0007, // 002B LDINT R10 8 - 0x7C1C0600, // 002C CALL R7 3 - 0x8C200F06, // 002D GETMET R8 R7 K6 - 0x58280007, // 002E LDCONST R10 K7 - 0x542E0003, // 002F LDINT R11 4 - 0x7C200600, // 0030 CALL R8 3 - 0x8C240F06, // 0031 GETMET R9 R7 K6 - 0x542E0003, // 0032 LDINT R11 4 + 0x880C0104, // 000D GETMBR R3 R0 K4 + 0x8C100305, // 000E GETMET R4 R1 K5 + 0x5C180400, // 000F MOVE R6 R2 + 0x581C0006, // 0010 LDCONST R7 K6 + 0x7C100600, // 0011 CALL R4 3 + 0x8C100907, // 0012 GETMET R4 R4 K7 + 0x58180008, // 0013 LDCONST R6 K8 + 0x581C0006, // 0014 LDCONST R7 K6 + 0x7C100600, // 0015 CALL R4 3 + 0x541600E8, // 0016 LDINT R5 233 + 0x20140805, // 0017 NE R5 R4 R5 + 0x78160002, // 0018 JMPF R5 #001C + 0x5415FFFE, // 0019 LDINT R5 -1 + 0xA8040001, // 001A EXBLK 1 1 + 0x80040A00, // 001B RET 1 R5 + 0x8C140305, // 001C GETMET R5 R1 K5 + 0x001C0506, // 001D ADD R7 R2 K6 + 0x58200006, // 001E LDCONST R8 K6 + 0x7C140600, // 001F CALL R5 3 + 0x8C140B07, // 0020 GETMET R5 R5 K7 + 0x581C0008, // 0021 LDCONST R7 K8 + 0x58200006, // 0022 LDCONST R8 K6 + 0x7C140600, // 0023 CALL R5 3 + 0x541A001F, // 0024 LDINT R6 32 + 0x00180406, // 0025 ADD R6 R2 R6 + 0x581C0008, // 0026 LDCONST R7 K8 + 0x14200E05, // 0027 LT R8 R7 R5 + 0x78220017, // 0028 JMPF R8 #0041 + 0x8C200305, // 0029 GETMET R8 R1 K5 + 0x542A0007, // 002A LDINT R10 8 + 0x04280C0A, // 002B SUB R10 R6 R10 + 0x542E0007, // 002C LDINT R11 8 + 0x7C200600, // 002D CALL R8 3 + 0x8C241107, // 002E GETMET R9 R8 K7 + 0x582C0008, // 002F LDCONST R11 K8 + 0x54320003, // 0030 LDINT R12 4 + 0x7C240600, // 0031 CALL R9 3 + 0x8C281107, // 0032 GETMET R10 R8 K7 0x54320003, // 0033 LDINT R12 4 - 0x7C240600, // 0034 CALL R9 3 - 0x542A0007, // 0035 LDINT R10 8 - 0x0028120A, // 0036 ADD R10 R9 R10 - 0x00140A0A, // 0037 ADD R5 R5 R10 - 0x00180D05, // 0038 ADD R6 R6 K5 - 0x7001FFEB, // 0039 JMP #0026 - 0x041C0A02, // 003A SUB R7 R5 R2 - 0x001C0F05, // 003B ADD R7 R7 K5 - 0xA8040001, // 003C EXBLK 1 1 - 0x80040E00, // 003D RET 1 R7 - 0xA8040001, // 003E EXBLK 1 1 - 0x7002000C, // 003F JMP #004D - 0xAC080002, // 0040 CATCH R2 0 2 - 0x70020009, // 0041 JMP #004C - 0xB8121000, // 0042 GETNGBL R4 K8 - 0x8C100909, // 0043 GETMET R4 R4 K9 - 0x001A1402, // 0044 ADD R6 K10 R2 - 0x00180D0B, // 0045 ADD R6 R6 K11 - 0x00180C03, // 0046 ADD R6 R6 R3 - 0x581C000C, // 0047 LDCONST R7 K12 - 0x7C100600, // 0048 CALL R4 3 - 0x5411FFFE, // 0049 LDINT R4 -1 - 0x80040800, // 004A RET 1 R4 - 0x70020000, // 004B JMP #004D - 0xB0080000, // 004C RAISE 2 R0 R0 - 0x80000000, // 004D RET 0 + 0x54360003, // 0034 LDINT R13 4 + 0x7C280600, // 0035 CALL R10 3 + 0x542E0007, // 0036 LDINT R11 8 + 0x002C140B, // 0037 ADD R11 R10 R11 + 0x00180C0B, // 0038 ADD R6 R6 R11 + 0x002C0403, // 0039 ADD R11 R2 R3 + 0x282C0C0B, // 003A GE R11 R6 R11 + 0x782E0002, // 003B JMPF R11 #003F + 0x542DFFFE, // 003C LDINT R11 -1 + 0xA8040001, // 003D EXBLK 1 1 + 0x80041600, // 003E RET 1 R11 + 0x001C0F06, // 003F ADD R7 R7 K6 + 0x7001FFE5, // 0040 JMP #0027 + 0x04200C02, // 0041 SUB R8 R6 R2 + 0x00201106, // 0042 ADD R8 R8 K6 + 0xA8040001, // 0043 EXBLK 1 1 + 0x80041000, // 0044 RET 1 R8 + 0xA8040001, // 0045 EXBLK 1 1 + 0x7002000C, // 0046 JMP #0054 + 0xAC080002, // 0047 CATCH R2 0 2 + 0x70020009, // 0048 JMP #0053 + 0xB8121200, // 0049 GETNGBL R4 K9 + 0x8C10090A, // 004A GETMET R4 R4 K10 + 0x001A1602, // 004B ADD R6 K11 R2 + 0x00180D0C, // 004C ADD R6 R6 K12 + 0x00180C03, // 004D ADD R6 R6 R3 + 0x581C000D, // 004E LDCONST R7 K13 + 0x7C100600, // 004F CALL R4 3 + 0x5411FFFE, // 0050 LDINT R4 -1 + 0x80040800, // 0051 RET 1 R4 + 0x70020000, // 0052 JMP #0054 + 0xB0080000, // 0053 RAISE 2 R0 R0 + 0x80000000, // 0054 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be index 0bf67f0cd..f72ace0ad 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be +++ b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be @@ -109,6 +109,7 @@ class Partition_info if self.is_ota() == nil && !self.is_factory() return -1 end try var addr = self.start + var size = self.size var magic_byte = flash.read(addr, 1).get(0, 1) if magic_byte != 0xE9 return -1 end @@ -126,6 +127,7 @@ class Partition_info # print(string.format("Segment %i: flash_offset=0x%08X start_addr=0x%08X size=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size)) seg_offset += seg_size + 8 # add segment_length + sizeof(esp_image_segment_header_t) + if seg_offset >= (addr + size) return -1 end seg_num += 1 end @@ -420,11 +422,11 @@ class Partition #- compute the highest ota partition -# def ota_max() - var ota_max = 0 + var ota_max = nil for slot:self.slots if slot.type == 0 && (slot.subtype >= 0x10 && slot.subtype < 0x20) var ota_num = slot.subtype - 0x10 - if ota_num > ota_max ota_max = ota_num end + if (ota_max == nil) || (ota_num > ota_max) ota_max = ota_num end end end return ota_max @@ -513,9 +515,9 @@ class Partition end # switch to safeboot `factory` partition - def switch_factory() + def switch_factory(force_ota) import flash - flash.rollback() + flash.factory(force_ota) end end partition_core.Partition = Partition diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h index 3b18a9a2a..aac9f4a35 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lv_c_mapping.h @@ -875,7 +875,7 @@ const be_ntv_func_def_t lv_dropdown_func[] = { { "get_options", { (const void*) &lv_dropdown_get_options, "s", "(lv.lv_obj)" } }, { "get_selected", { (const void*) &lv_dropdown_get_selected, "i", "(lv.lv_obj)" } }, { "get_selected_highlight", { (const void*) &lv_dropdown_get_selected_highlight, "b", "(lv.lv_obj)" } }, - { "get_selected_str", { (const void*) &lv_dropdown_get_selected_str, "", "(lv.lv_obj)si" } }, + { "get_selected_str", { (const void*) &lv_dropdown_get_selected_str, "", "(lv.lv_obj)ci" } }, { "get_symbol", { (const void*) &lv_dropdown_get_symbol, "s", "(lv.lv_obj)" } }, { "get_text", { (const void*) &lv_dropdown_get_text, "s", "(lv.lv_obj)" } }, { "is_open", { (const void*) &lv_dropdown_is_open, "b", "(lv.lv_obj)" } }, @@ -898,7 +898,7 @@ const be_ntv_func_def_t lv_label_func[] = { { "get_letter_pos", { (const void*) &lv_label_get_letter_pos, "", "(lv.lv_obj)i(lv.lv_point)" } }, { "get_long_mode", { (const void*) &lv_label_get_long_mode, "i", "(lv.lv_obj)" } }, { "get_recolor", { (const void*) &lv_label_get_recolor, "b", "(lv.lv_obj)" } }, - { "get_text", { (const void*) &lv_label_get_text, "s", "(lv.lv_obj)" } }, + { "get_text", { (const void*) &lv_label_get_text, "c", "(lv.lv_obj)" } }, { "get_text_selection_end", { (const void*) &lv_label_get_text_selection_end, "i", "(lv.lv_obj)" } }, { "get_text_selection_start", { (const void*) &lv_label_get_text_selection_start, "i", "(lv.lv_obj)" } }, { "ins_text", { (const void*) &lv_label_ins_text, "", "(lv.lv_obj)is" } }, @@ -928,7 +928,7 @@ const be_ntv_func_def_t lv_roller_func[] = { { "get_option_cnt", { (const void*) &lv_roller_get_option_cnt, "i", "(lv.lv_obj)" } }, { "get_options", { (const void*) &lv_roller_get_options, "s", "(lv.lv_obj)" } }, { "get_selected", { (const void*) &lv_roller_get_selected, "i", "(lv.lv_obj)" } }, - { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.lv_obj)si" } }, + { "get_selected_str", { (const void*) &lv_roller_get_selected_str, "", "(lv.lv_obj)ci" } }, { "set_options", { (const void*) &lv_roller_set_options, "", "(lv.lv_obj)s(lv.lv_roller_mode)" } }, { "set_selected", { (const void*) &lv_roller_set_selected, "", "(lv.lv_obj)ii" } }, { "set_visible_row_count", { (const void*) &lv_roller_set_visible_row_count, "", "(lv.lv_obj)i" } }, diff --git a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c index 14707d20b..aec4cbf45 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c +++ b/lib/libesp32_lvgl/lv_binding_berry/generate/be_lvgl_module.c @@ -75,7 +75,7 @@ const be_ntv_func_def_t lv_func[] = { { "draw_arc_dsc_init", { (const void*) &lv_draw_arc_dsc_init, "", "(lv.lv_draw_arc_dsc)" } }, { "draw_arc_get_area", { (const void*) &lv_draw_arc_get_area, "", "iiiiiib(lv.lv_area)" } }, { "draw_img", { (const void*) &lv_draw_img, "", "(lv.lv_draw_ctx)(lv.lv_draw_img_dsc)(lv.lv_area)." } }, - { "draw_img_decoded", { (const void*) &lv_draw_img_decoded, "", "(lv.lv_draw_ctx)(lv.lv_draw_img_dsc)(lv.lv_area)(lv.uint8)i" } }, + { "draw_img_decoded", { (const void*) &lv_draw_img_decoded, "", "(lv.lv_draw_ctx)(lv.lv_draw_img_dsc)(lv.lv_area)ci" } }, { "draw_img_dsc_init", { (const void*) &lv_draw_img_dsc_init, "", "(lv.lv_draw_img_dsc)" } }, { "draw_init", { (const void*) &lv_draw_init, "", "" } }, { "draw_label", { (const void*) &lv_draw_label, "", "(lv.lv_draw_ctx)(lv.lv_draw_label_dsc)(lv.lv_area)s(lv.lv_draw_label_hint)" } }, @@ -109,6 +109,7 @@ const be_ntv_func_def_t lv_func[] = { { "event_stop_bubbling", { (const void*) &lv_event_stop_bubbling, "", "(lv.lv_event)" } }, { "event_stop_processing", { (const void*) &lv_event_stop_processing, "", "(lv.lv_event)" } }, { "flex_init", { (const void*) &lv_flex_init, "", "" } }, + { "font_get_glyph_bitmap", { (const void*) &lv_font_get_glyph_bitmap, "c", "(lv.lv_font)i" } }, { "font_get_glyph_dsc", { (const void*) &lv_font_get_glyph_dsc, "b", "(lv.lv_font)(lv.lv_font_glyph_dsc)ii" } }, { "font_get_glyph_width", { (const void*) &lv_font_get_glyph_width, "i", "(lv.lv_font)ii" } }, { "font_get_line_height", { (const void*) &lv_font_get_line_height, "i", "(lv.lv_font)" } }, diff --git a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py index bb36141e3..c305bdc34 100644 --- a/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py +++ b/lib/libesp32_lvgl/lv_binding_berry/tools/convert.py @@ -35,8 +35,10 @@ return_types = { "int32_t": "i", "void *": ".", "const void *": ".", - "char *": "s", + "char *": "c", + "uint8_t *": "c", "const char *": "s", + "constchar *": "s", # special construct "lv_obj_user_data_t": "i", "lv_objmask_mask_t *": ".", @@ -122,6 +124,7 @@ return_types = { "lv_anim_start_cb_t": "c", # arrays + "constchar * []": "str_arr", "char * []": "str_arr", "lv_coord_t []": "lv_coord_arr", "lv_point_t []": "lv_point_arr", @@ -161,6 +164,7 @@ return_types = { "lv_timer_t *": "lv_timer", "lv_coord_t *": "c", # treat as a simple pointer, decoding needs to be done at Berry level "char **": "c", # treat as a simple pointer, decoding needs to be done at Berry level + "constchar **": "c", # treat as a simple pointer, decoding needs to be done at Berry level # callbacks "lv_group_focus_cb_t": "lv_group_focus_cb", @@ -229,6 +233,7 @@ with open(lv_widgets_file) as f: l_raw = l_raw.strip(" \t\n\r") # remove leading or trailing spaces l_raw = re.sub('static ', '', l_raw) l_raw = re.sub('inline ', '', l_raw) + l_raw = re.sub('const\s+char\s*\*', 'constchar *', l_raw) l_raw = re.sub('const ', '', l_raw) l_raw = re.sub('struct ', '', l_raw) if (len(l_raw) == 0): continue diff --git a/esp32_partition_app1572k_fs983k.csv b/partitions/esp32_partition_app1572k_fs983k.csv similarity index 100% rename from esp32_partition_app1572k_fs983k.csv rename to partitions/esp32_partition_app1572k_fs983k.csv diff --git a/esp32_partition_app1856k_fs1344k.csv b/partitions/esp32_partition_app1856k_fs1344k.csv similarity index 100% rename from esp32_partition_app1856k_fs1344k.csv rename to partitions/esp32_partition_app1856k_fs1344k.csv diff --git a/esp32_partition_app1856k_fs320k.csv b/partitions/esp32_partition_app1856k_fs320k.csv similarity index 100% rename from esp32_partition_app1856k_fs320k.csv rename to partitions/esp32_partition_app1856k_fs320k.csv diff --git a/esp32_partition_app2880k_fs320k.csv b/partitions/esp32_partition_app2880k_fs320k.csv similarity index 100% rename from esp32_partition_app2880k_fs320k.csv rename to partitions/esp32_partition_app2880k_fs320k.csv diff --git a/esp32_partition_app2944k_fs10M.csv b/partitions/esp32_partition_app2944k_fs10M.csv similarity index 100% rename from esp32_partition_app2944k_fs10M.csv rename to partitions/esp32_partition_app2944k_fs10M.csv diff --git a/esp32_partition_app2944k_fs2M.csv b/partitions/esp32_partition_app2944k_fs2M.csv similarity index 100% rename from esp32_partition_app2944k_fs2M.csv rename to partitions/esp32_partition_app2944k_fs2M.csv diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index 5bb057fab..2e919391b 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -14,7 +14,9 @@ # - 0x1000 | ~\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\bin\bootloader_dout_40m.bin # - 0x8000 | ~\Tasmota\.pio\build\\partitions.bin # - 0xe000 | ~\.platformio\packages\framework-arduinoespressif32\tools\partitions\boot_app0.bin -# - 0x10000 | ~\Tasmota\.pio\build\/firmware.bin +# - 0x10000 | ~\.platformio/packages/framework-arduinoespressif32/variants/tasmota/\-safeboot.bin +# - 0xe0000 | ~\Tasmota\.pio\build\/firmware.bin +# - 0x3b0000| ~\Tasmota\.pio\build\/littlefs.bin Import("env") @@ -28,6 +30,7 @@ from os.path import join import csv import requests import shutil +import subprocess sys.path.append(join(platform.get_package_dir("tool-esptoolpy"))) import esptool @@ -35,9 +38,36 @@ import esptool FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") variants_dir = join(FRAMEWORK_DIR, "variants", "tasmota") -def esp32_fetch_safeboot_bin(chip): - safeboot_fw_url = "https://github.com/arendst/Tasmota-firmware/raw/main/firmware/tasmota32/tasmota" + ("32solo1" if "solo1" in env.subst("$BUILD_DIR") else chip[3:]) + "-safeboot.bin" - safeboot_fw_name = join(variants_dir,"tasmota" + ("32solo1" if "solo1" in env.subst("$BUILD_DIR") else chip[3:]) + "-safeboot.bin") +def esp32_create_chip_string(chip): + tasmota_platform = env.subst("$BUILD_DIR").split('/')[-1] + tasmota_platform = tasmota_platform.split('-')[0] + if 'tasmota' and chip[3:] not in tasmota_platform: # quick check for a valid name like 'tasmota' + '32c3' + print('Unexpected naming conventions in this build environment -> Undefined behavior for further build process!!') + return tasmota_platform + +def esp32_build_filesystem(fs_size): + files = env.GetProjectOption("custom_files_upload").splitlines() + filesystem_dir = join(env.subst("$BUILD_DIR"),"littlefs_data") + if not os.path.exists(filesystem_dir): + os.makedirs(filesystem_dir) + print("Creating filesystem with content:") + for file in files: + if "no_files" in file: + continue + shutil.copy(file, filesystem_dir) + if not os.listdir(filesystem_dir): + print("No files added -> will NOT create littlefs.bin and NOT overwrite fs partition!") + return False + env.Replace( MKSPIFFSTOOL=platform.get_package_dir("tool-mklittlefs") + '/mklittlefs' ) + tool = env.subst(env["MKSPIFFSTOOL"]) + cmd = (tool,"-c",filesystem_dir,"-s",fs_size,join(env.subst("$BUILD_DIR"),"littlefs.bin")) + returncode = subprocess.call(cmd, shell=False) + # print(returncode) + return True + +def esp32_fetch_safeboot_bin(tasmota_platform): + safeboot_fw_url = "https://github.com/arendst/Tasmota-firmware/raw/main/firmware/tasmota32/" + tasmota_platform + "-safeboot.bin" + safeboot_fw_name = join(variants_dir, tasmota_platform + "-safeboot.bin") if(exists(safeboot_fw_name)): print("safeboot binary already in place.") return @@ -47,9 +77,9 @@ def esp32_fetch_safeboot_bin(chip): open(safeboot_fw_name, "wb").write(response.content) print("safeboot binary written to variants dir.") -def esp32_copy_new_safeboot_bin(chip,new_local_safeboot_fw): +def esp32_copy_new_safeboot_bin(tasmota_platform,new_local_safeboot_fw): print("Copy new local safeboot firmware to variants dir -> using it for further flashing operations") - safeboot_fw_name = join(variants_dir,"tasmota" + ("32solo1" if "solo1" in env.subst("$BUILD_DIR") else chip[3:]) + "-safeboot.bin") + safeboot_fw_name = join(variants_dir, tasmota_platform + "-safeboot.bin") if os.path.exists(variants_dir): shutil.copy(new_local_safeboot_fw, safeboot_fw_name) @@ -58,9 +88,9 @@ def esp32_create_combined_bin(source, target, env): # The offset from begin of the file where the app0 partition starts # This is defined in the partition .csv file - factory_offset = -1 # error code value + # factory_offset = -1 # error code value - currently unused app_offset = 0x10000 # default value for "old" scheme - spiffs_offset = -1 # error code value + fs_offset = -1 # error code value with open(env.BoardConfig().get("build.partitions")) as csv_file: print("Read partitions from ",env.BoardConfig().get("build.partitions")) csv_reader = csv.reader(csv_file, delimiter=',') @@ -76,20 +106,22 @@ def esp32_create_combined_bin(source, target, env): app_offset = int(row[3],base=16) # elif(row[0] == 'factory'): # factory_offset = int(row[3],base=16) - # elif(row[0] == 'spiffs'): - # spiffs_offset = int(row[3],base=16) + elif(row[0] == 'spiffs'): + if esp32_build_filesystem(row[4]): + fs_offset = int(row[3],base=16) new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin") sections = env.subst(env.get("FLASH_EXTRA_IMAGES")) firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin") chip = env.get("BOARD_MCU") + tasmota_platform = esp32_create_chip_string(chip) if not os.path.exists(variants_dir): os.makedirs(variants_dir) if("safeboot" in firmware_name): - esp32_copy_new_safeboot_bin(chip,firmware_name) + esp32_copy_new_safeboot_bin(tasmota_platform,firmware_name) else: - esp32_fetch_safeboot_bin(chip) + esp32_fetch_safeboot_bin(tasmota_platform) flash_size = env.BoardConfig().get("upload.flash_size", "4MB") cmd = [ "--chip", @@ -111,10 +143,32 @@ def esp32_create_combined_bin(source, target, env): if("safeboot" not in firmware_name): print(f" - {hex(app_offset)} | {firmware_name}") cmd += [hex(app_offset), firmware_name] + else: print("Upload new safeboot binary only") - #print('Using esptool.py arguments: %s' % ' '.join(cmd)) + if(fs_offset != -1): + fs_bin = join(env.subst("$BUILD_DIR"),"littlefs.bin") + if exists(fs_bin): + print(f" - {hex(fs_offset)}| {fs_bin}") + cmd += [hex(fs_offset), fs_bin] + env.Replace( + UPLOADERFLAGS=[ + "--chip", chip, + "--port", '"$UPLOAD_PORT"', + "--baud", "$UPLOAD_SPEED", + "--before", "default_reset", + "--after", "hard_reset", + "write_flash", "-z", + "--flash_mode", "${__get_board_flash_mode(__env__)}", + "--flash_freq", "${__get_board_f_flash(__env__)}", + "--flash_size", flash_size + ], + UPLOADCMD='"$PYTHONEXE" "$UPLOADER" $UPLOADERFLAGS ' + " ".join(cmd[7:]) + ) + print("Will use custom upload command for flashing operation to add file system defined for this build target.") + + # print('Using esptool.py arguments: %s' % ' '.join(cmd)) esptool.main(cmd) diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index 629f03e67..e78d20cdb 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -36,6 +36,7 @@ default_envs = ; tasmota32solo1 ; tasmota32c3 ; tasmota32s2 +; tasmota32s3 ; tasmota32-odroidgo ; tasmota32-core2 @@ -90,8 +91,8 @@ lib_extra_dirs = ${library.lib_extra_dirs} [env:tasmota32_base] ; *** Uncomment next lines ";" to enable development Tasmota Arduino version ESP32 -;platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.3rc1/platform-espressif32-2.0.3new.zip -;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/825/framework-arduinoespressif32-v4.4_work-c4b83228a5.tar.gz +;platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.3/platform-espressif32-v.2.0.3.zip +;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/837/framework-arduinoespressif32-v4.4_dev-6fa4526c0d.tar.gz build_unflags = ${esp32_defaults.build_unflags} build_flags = ${esp32_defaults.build_flags} diff --git a/platformio_tasmota_cenv_sample.ini b/platformio_tasmota_cenv_sample.ini index b4b2438aa..d2ac59086 100644 --- a/platformio_tasmota_cenv_sample.ini +++ b/platformio_tasmota_cenv_sample.ini @@ -12,6 +12,14 @@ build_flags = ${env:tasmota32_base.build_flags} -D USE_WIFI_RANGE_EXTENDER -D USE_WIFI_RANGE_EXTENDER_NAPT +[env:tasmota32s3] +extends = env:tasmota32_base +board = esp32s3 +build_flags = ${env:tasmota32_base.build_flags} -D FIRMWARE_TASMOTA32 +; example for custom file upload in Tasmota Filesystem +; custom_files_upload = ${env:tasmota32_base.custom_files_upload} +; tasmota/berry/modules/Partition_wizard.tapp + ; *** Debug version used for PlatformIO Home Project Inspection [env:tasmota-debug] build_type = debug @@ -52,25 +60,3 @@ debug_init_break = tbreak setup build_unflags = ${core32solo1.build_unflags} build_flags = ${core32solo1.build_flags} monitor_filters = esp32_exception_decoder - -; *** alpha S3 Version -[env:tasmota32s3] -extends = env:tasmota32_base -board = esp32s3 -build_flags = ${env:tasmota32_base.build_flags} -D FIRMWARE_BLUETOOTH -lib_extra_dirs = - lib/lib_basic - lib/lib_ssl - lib/lib_i2c - lib/lib_rf - lib/lib_div - lib/lib_display - lib/lib_audio - lib/libesp32 - lib/libesp32_lvgl - lib/libesp32_div - lib/libesp32_eink -lib_ignore = - TTGO TWatch Library - Micro-RTSP - epdiy diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 18e1fa60a..ee7be6bd1 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -34,6 +34,11 @@ lib_ignore = BluetoothSerial ; Disable next if you want to use ArduinoOTA in Tasmota32 (default disabled) ArduinoOTA +; Add files to Filesystem for all env (global). Remove no files entry and add add a line with the file to include +; Example for adding the Partition Manager +; custom_files_upload = +; tasmota/berry/modules/Partition_Manager.tapp +custom_files_upload = no_files [env:tasmota32] extends = env:tasmota32_base @@ -105,6 +110,9 @@ lib_ignore = TTGO TWatch Library Micro-RTSP epdiy +[env:tasmota32c3usb] +extends = env:tasmota32c3 +board = esp32c3usb [env:tasmota32s2] extends = env:tasmota32_base @@ -176,6 +184,21 @@ lib_ignore = Micro-RTSP epdiy +[env:tasmota32c3usb-safeboot] +extends = env:tasmota32_base +board = esp32c3usb +build_unflags = ${env:tasmota32_base.build_unflags} + -flto + -mtarget-align +build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_SAFEBOOT + -fno-lto +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = + TTGO TWatch Library + NimBLE-Arduino + Micro-RTSP + epdiy + [env:tasmota32-AF] extends = env:tasmota32_base build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=af_AF -DFIRMWARE_TASMOTA32 diff --git a/tasmota/berry/modules/Partition_Manager.tapp b/tasmota/berry/modules/Partition_Manager.tapp index 8e2c8b91b..282490659 100644 Binary files a/tasmota/berry/modules/Partition_Manager.tapp and b/tasmota/berry/modules/Partition_Manager.tapp differ diff --git a/tasmota/berry/modules/Partition_Manager/autoexec.be b/tasmota/berry/modules/Partition_Manager/autoexec.be index 87af9edd9..e934b0715 100644 --- a/tasmota/berry/modules/Partition_Manager/autoexec.be +++ b/tasmota/berry/modules/Partition_Manager/autoexec.be @@ -1,2 +1,3 @@ # start Partition Manager +# rm Partition_Manager.tapp; zip Partition_Manager.tapp -j -0 Partition_Manager/* import partition diff --git a/tasmota/berry/modules/Partition_Manager/partition.bec b/tasmota/berry/modules/Partition_Manager/partition.bec index 6483625e5..30064881a 100644 Binary files a/tasmota/berry/modules/Partition_Manager/partition.bec and b/tasmota/berry/modules/Partition_Manager/partition.bec differ diff --git a/tasmota/berry/modules/Partition_Wizard.tapp b/tasmota/berry/modules/Partition_Wizard.tapp new file mode 100644 index 000000000..f98760d4f Binary files /dev/null and b/tasmota/berry/modules/Partition_Wizard.tapp differ diff --git a/tasmota/berry/modules/Partition_Wizard/autoexec.be b/tasmota/berry/modules/Partition_Wizard/autoexec.be new file mode 100644 index 000000000..968e1a502 --- /dev/null +++ b/tasmota/berry/modules/Partition_Wizard/autoexec.be @@ -0,0 +1,2 @@ +# rm Partition_wizard.tapp; zip -j -0 Partition_wizard.tapp Partition_Wizard/* +import partition_wizard diff --git a/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec b/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec new file mode 100644 index 000000000..843fe128c Binary files /dev/null and b/tasmota/berry/modules/Partition_Wizard/partition_wizard.bec differ diff --git a/tasmota/berry/modules/partition.be b/tasmota/berry/modules/partition.be index b6aacc781..e039f3723 100644 --- a/tasmota/berry/modules/partition.be +++ b/tasmota/berry/modules/partition.be @@ -22,27 +22,154 @@ var partition = module('partition') # } esp_partition_info_t_simplified; # ####################################################################### -# class Partition_info -# -# def init(raw) -# - # # check if the parition is an OTA partition -# # if yes, return OTA number (starting at 0) -# # if no, return nil -# def is_ota() -# -# # # check if the parition is a SPIFFS partition -# # returns bool -# def is_spiffs() -# -# # get the actual image size give of the partition -# # returns -1 if the partition is not an app ota partition -# def get_image_size() -# -# def tostring() -# -# def tobytes() -#end +class Partition_info + var type + var subtype + var start + var size + var label + var flags + + #- remove trailing NULL chars from a buffer before converting to string -# + #- Berry strings can contain NULL, but this messes up C-Berry interface -# + static def remove_trailing_zeroes(b) + while size(b) > 0 + if b[-1] == 0 b.resize(size(b)-1) + else break end + end + return b + end + + # + def init(raw) + if raw == nil || !issubclass(bytes, raw) # no payload, empty partition information + self.type = 0 + self.subtype = 0 + self.start = 0 + self.size = 0 + self.label = '' + self.flags = 0 + return + end + + #- we have a payload, parse it -# + var magic = raw.get(0,2) + if magic == 0x50AA #- partition entry -# + + self.type = raw.get(2,1) + self.subtype = raw.get(3,1) + self.start = raw.get(4,4) + self.size = raw.get(8,4) + self.label = self.remove_trailing_zeroes(raw[12..27]).asstring() + self.flags = raw.get(28,4) + + elif magic == 0xEBEB #- MD5 -# + else + import string + raise "internal_error", string.format("invalid magic number %02X", magic) + end + + end + + # check if the parition is an OTA partition + # if yes, return OTA number (starting at 0) + # if no, return nil + def is_ota() + if self.type == 0 && (self.subtype >= 0x10 && self.subtype < 0x20) + return self.subtype - 0x10 + end + end + + # check if the parition is a SPIFFS partition + # returns bool + def is_spiffs() + return self.type == 1 && self.subtype == 130 + end + + # get the actual image size give of the partition + # returns -1 if the partition is not an app ota partition + def get_image_size() + import flash + if self.is_ota() == nil return -1 end + try + var addr = self.start + var magic_byte = flash.read(addr, 1).get(0, 1) + if magic_byte != 0xE9 return -1 end + + var seg_count = flash.read(addr+1, 1).get(0, 1) + # print("Segment count", seg_count) + + var seg_offset = addr + 0x20 # sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) = 24 + 8 + + for seg_num:0..seg_count-1 + # print(string.format("Reading 0x%08X", seg_offset)) + var segment_header = flash.read(seg_offset - 8, 8) + var seg_start_addr = segment_header.get(0, 4) + var seg_size = segment_header.get(4,4) + # print(string.format("Segment %i: flash_offset=0x%08X start_addr=0x%08X size=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size)) + + seg_offset += seg_size + 8 # add segment_length + sizeof(esp_image_segment_header_t) + end + var total_size = seg_offset - addr + 1 # add 1KB for safety + + # print(string.format("Total size = %i KB", total_size/1024)) + + return total_size + except .. as e, m + print("BRY: Exception> '" + e + "' - " + m) + return -1 + end + end + + def tostring() + import string + var type_s = "" + var subtype_s = "" + if self.type == 0 type_s = "app" + if self.subtype == 0 subtype_s = "factory" + elif self.subtype >= 0x10 && self.subtype < 0x20 subtype_s = "ota" + str(self.subtype - 0x10) + elif self.subtype == 0x20 subtype_s = "test" + end + elif self.type == 1 type_s = "data" + if self.subtype == 0x00 subtype_s = "otadata" + elif self.subtype == 0x01 subtype_s = "phy" + elif self.subtype == 0x02 subtype_s = "nvs" + elif self.subtype == 0x03 subtype_s = "coredump" + elif self.subtype == 0x04 subtype_s = "nvskeys" + elif self.subtype == 0x05 subtype_s = "efuse_em" + elif self.subtype == 0x80 subtype_s = "esphttpd" + elif self.subtype == 0x81 subtype_s = "fat" + elif self.subtype == 0x82 subtype_s = "spiffs" + end + end + + #- reformat strings -# + if type_s != "" type_s = " (" + type_s + ")" end + if subtype_s != "" subtype_s = " (" + subtype_s + ")" end + return string.format("", + self.type, type_s, + self.subtype, subtype_s, + self.start, self.size, + self.label, self.flags) + end + + def tobytes() + #- convert to raw bytes -# + var b = bytes('AA50') #- set magic number -# + b.resize(32).resize(2) #- pre-reserve 32 bytes -# + b.add(self.type, 1) + b.add(self.subtype, 1) + b.add(self.start, 4) + b.add(self.size, 4) + var label = bytes().fromstring(self.label) + label.resize(16) + b = b + label + b.add(self.flags, 4) + return b + end + +end +partition.Partition_info = Partition_info #------------------------------------------------------------- - OTA Data @@ -73,77 +200,302 @@ var partition = module('partition') so current ota app sub type id is x , dest bin subtype is y,total ota app count is n seq will add (x + n*1 + 1 - seq)%n -------------------------------------------------------------# -# class Partition_otadata -# var maxota #- number of highest OTA partition, default 1 (double ota0/ota1) -# -# var offset #- offset of the otadata partition (0x2000 in length), default 0xE000 -# -# var active_otadata #- which otadata block is active, 0 or 1, i.e. 0xE000 or 0xF000 -# -# var seq0 #- ota_seq of first block -# -# var seq1 #- ota_seq of second block -# -# -# #- crc32 for ota_seq as 32 bits unsigned, with init vector -1 -# -# static def crc32_ota_seq(seq) -# -# #---------------------------------------------------------------------# -# # Rest of the class -# #---------------------------------------------------------------------# -# def init(maxota, offset) -# -# #- update ota_max, needs to recompute everything -# -# def set_ota_max(n) -# -# # change the active OTA partition -# def set_active(n) -# -# #- load otadata from SPI Flash -# -# def load() -# -# # Save partition information to SPI Flash -# def save() -# -# # Produce a human-readable representation of the object with relevant information -# def tostring() -#end +class Partition_otadata + var maxota #- number of highest OTA partition, default 1 (double ota0/ota1) -# + var offset #- offset of the otadata partition (0x2000 in length), default 0xE000 -# + var active_otadata #- which otadata block is active, 0 or 1, i.e. 0xE000 or 0xF000 -# + var seq0 #- ota_seq of first block -# + var seq1 #- ota_seq of second block -# + + #------------------------------------------------------------- + - Simple CRC32 imple + - + - adapted from Python https://rosettacode.org/wiki/CRC-32#Python + -------------------------------------------------------------# + static def crc32_create_table() + var a = [] + for i:0..255 + var k = i + for j:0..7 + if k & 1 + k = (k >> 1) & 0x7FFFFFFF + k ^= 0xedb88320 + else + k = (k >> 1) & 0x7FFFFFFF + end + end + a.push(k) + end + return a + end + static crc32_table = Partition_otadata.crc32_create_table() + + static def crc32_update(buf, crc) + crc ^= 0xffffffff + for k:0..size(buf)-1 + crc = (crc >> 8 & 0x00FFFFFF) ^ Partition_otadata.crc32_table[(crc & 0xff) ^ buf[k]] + end + return crc ^ 0xffffffff + end + + #- crc32 for ota_seq as 32 bits unsigned, with init vector -1 -# + static def crc32_ota_seq(seq) + return Partition_otadata.crc32_update(bytes().add(seq, 4), 0xFFFFFFFF) + end + + #---------------------------------------------------------------------# + # Rest of the class + #---------------------------------------------------------------------# + def init(maxota, offset) + self.maxota = maxota + if self.maxota == nil self.maxota = 1 end + self.offset = offset + if self.offset == nil self.offset = 0xE000 end + self.active_otadata = 0 + self.load() + end + + #- update ota_max, needs to recompute everything -# + def set_ota_max(n) + self.maxota = n + end + + # change the active OTA partition + def set_active(n) + var seq_max = 0 #- current highest seq number -# + var block_act = 0 #- block number containing the highest seq number -# + + if self.seq0 != nil + seq_max = self.seq0 + block_act = 0 + end + if self.seq1 != nil && self.seq1 > seq_max + seq_max = self.seq1 + block_act = 1 + end + + #- compute the next sequence number -# + var actual_ota = (seq_max - 1) % (self.maxota + 1) + if actual_ota != n #- change only if different -# + if n > actual_ota seq_max += n - actual_ota + else seq_max += (self.maxota + 1) - actual_ota + n + end + + #- update internal structure -# + if block_act == 1 #- current block is 1, so update block 0 -# + self.seq0 = seq_max + else #- or write to block 1 -# + self.seq1 = seq_max + end + self._validate() + end + end + + #- load otadata from SPI Flash -# + def load() + import flash + var otadata0 = flash.read(0xE000, 32) + var otadata1 = flash.read(0xF000, 32) + self.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -# + self.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -# + var valid0 = otadata0.get(28, 4) == self.crc32_ota_seq(self.seq0) #- is CRC32 valid? -# + var valid1 = otadata1.get(28, 4) == self.crc32_ota_seq(self.seq1) #- is CRC32 valid? -# + if !valid0 self.seq0 = nil end + if !valid1 self.seq1 = nil end + + self._validate() + end + + #- internally used, validate data -# + def _validate() + self.active_otadata = 0 #- if none is valid, default to OTA0 -# + if self.seq0 != nil + self.active_otadata = (self.seq0 - 1) % (self.maxota + 1) + end + if self.seq1 != nil && (self.seq0 == nil || self.seq1 > self.seq0) + self.active_otadata = (self.seq1 - 1) % (self.maxota + 1) + end + end + + # Save partition information to SPI Flash + def save() + import flash + #- check the block number to save, 0 or 1. Choose the highest ota_seq -# + var block_to_save = -1 #- invalid -# + var seq_to_save = -1 #- invalid value -# + + # check seq0 + if self.seq0 != nil + seq_to_save = self.seq0 + block_to_save = 0 + end + if (self.seq1 != nil) && (self.seq1 > seq_to_save) + seq_to_save = self.seq1 + block_to_save = 1 + end + # if none was good + if block_to_save < 0 block_to_save = 0 end + if seq_to_save < 0 seq_to_save = 1 end + + var offset_to_save = self.offset + 0x1000 * block_to_save #- default 0xE000 or 0xF000 -# + + var bytes_to_save = bytes() + bytes_to_save.add(seq_to_save, 4) + bytes_to_save += bytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") + bytes_to_save.add(self.crc32_ota_seq(seq_to_save), 4) + + #- erase flash area and write -# + flash.erase(offset_to_save, 0x1000) + flash.write(offset_to_save, bytes_to_save) + end + + # Produce a human-readable representation of the object with relevant information + def tostring() + import string + return string.format("", + self.active_otadata, self.seq0, self.seq1, self.maxota) + end +end +partition.Partition_otadata = Partition_otadata #------------------------------------------------------------- - Class for a partition table entry -------------------------------------------------------------# -#class Partition -# var raw #- raw bytes of the partition table in flash -# -# var md5 #- md5 hash of partition list -# -# var slots -# var otadata #- instance of Partition_otadata() -# -# -# def init() -# -# # Load partition information from SPI Flash -# def load() -# -# def get_ota_slot(n) -# -# #- compute the highest ota partition -# -# def ota_max() -# -# def load_otadata() -# -# # get the active OTA app partition number -# def get_active() -# -# #- change the active partition -# -# def set_active(n) -# -# #- convert to human readble -# -# def tostring() -# -# #- convert the slots to raw bytes, ready to falsh to parition page -# -# def tobytes() -# -# #- write back to flash -# -# def save() -# -# #- invalidate SPIFFS partition to force format at next boot -# -# #- we simply erase the first byte of the first 2 blocks in the SPIFFS partition -# -# def invalidate_spiffs() -#end +class Partition + var raw #- raw bytes of the partition table in flash -# + var md5 #- md5 hash of partition list -# + var slots + var otadata #- instance of Partition_otadata() -# + + def init() + self.slots = [] + self.load() + self.parse() + self.load_otadata() + end + + # Load partition information from SPI Flash + def load() + import flash + self.raw = flash.read(0x8000,0x1000) + end + + #- parse the raw bytes to a structured list of partition items -# + def parse() + for i:0..94 # there are maximum 95 slots + md5 (0xC00) + var item_raw = self.raw[i*32..(i+1)*32-1] + var magic = item_raw.get(0,2) + if magic == 0x50AA #- partition entry -# + var slot = Partition_info(item_raw) + self.slots.push(slot) + elif magic == 0xEBEB #- MD5 -# + self.md5 = self.raw[i*32+16..i*33-1] + break + else + break + end + end + end + + def get_ota_slot(n) + for slot: self.slots + if slot.is_ota() == n return slot end + end + return nil + end + + #- compute the highest ota partition -# + def ota_max() + var ota_max = 0 + for slot:self.slots + if slot.type == 0 && (slot.subtype >= 0x10 && slot.subtype < 0x20) + var ota_num = slot.subtype - 0x10 + if ota_num > ota_max ota_max = ota_num end + end + end + return ota_max + end + + def load_otadata() + #- look for otadata partition offset, and max_ota -# + var otadata_offset = 0xE000 #- default value -# + var ota_max = self.ota_max() + for slot:self.slots + if slot.type == 1 && slot.subtype == 0 #- otadata -# + otadata_offset = slot.start + end + end + + self.otadata = Partition_otadata(ota_max, otadata_offset) + end + + # get the active OTA app partition number + def get_active() + return self.otadata.active_otadata + end + + #- change the active partition -# + def set_active(n) + if n < 0 || n > self.ota_max() raise "value_error", "Invalid ota partition number" end + self.otadata.set_ota_max(self.ota_max()) #- update ota_max if it changed -# + self.otadata.set_active(n) + end + + #- convert to human readble -# + def tostring() + var ret = " 95 raise "value_error", "Too many partiition slots" end + var b = bytes() + for slot: self.slots + b += slot.tobytes() + end + #- compute MD5 -# + var md5 = MD5() + md5.update(b) + #- add the last segment -# + b += bytes("EBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFF") + b += md5.finish() + #- complete -# + return b + end + + #- write back to flash -# + def save() + import flash + var b = self.tobytes() + #- erase flash area and write -# + flash.erase(0x8000, 0x1000) + flash.write(0x8000, b) + self.otadata.save() + end + + #- invalidate SPIFFS partition to force format at next boot -# + #- we simply erase the first byte of the first 2 blocks in the SPIFFS partition -# + def invalidate_spiffs() + import flash + #- we expect the SPIFFS partition to be the last one -# + var spiffs = self.slots[-1] + if !spiffs.is_spiffs() raise 'value_error', 'No FS partition found' end + + var b = bytes("00") #- flash memory: we can turn bits from '1' to '0' -# + flash.write(spiffs.start , b) #- block #0 -# + flash.write(spiffs.start + 0x1000, b) #- block #1 -# + end +end +partition.Partition = Partition ################################################################################# # Partition_manager_UI @@ -159,7 +511,7 @@ class Partition_manager_UI def web_add_button() import webserver webserver.content_send( - "
") + "

") end #- ---------------------------------------------------------------------- -# @@ -170,7 +522,7 @@ class Partition_manager_UI import string #- define `bdis` style for gray disabled buttons -# webserver.content_send("
") - webserver.content_send(string.format(" %s%s", + webserver.content_send(string.format(" %s%s ", slot.start / 0x1000, slot.label, active ? " (active)" : "")) webserver.content_send(string.format("

Partition size: %i KB

", slot.size / 1024)) @@ -212,8 +564,8 @@ class Partition_manager_UI def page_show_spiffs(slot, free_mem) import webserver import string - webserver.content_send(string.format("
 %s", - slot.start / 0x1000, slot.label)) + webserver.content_send(string.format("
 filesystem ", + slot.start / 0x1000)) webserver.content_send(string.format("

Partition size: %i KB

", slot.size / 1024)) @@ -226,8 +578,8 @@ class Partition_manager_UI webserver.content_send("

New size: (multiple of 16 KB)

") webserver.content_send("
") - webserver.content_send(string.format("", (slot.size + free_mem) / 1024, ((slot.size + free_mem) / 1024 / 16)*16)) - webserver.content_send("

") + webserver.content_send(string.format("", (slot.size + free_mem) / 1024, ((slot.size + free_mem) / 1024 / 16)*16)) + webserver.content_send("

") webserver.content_send("

") end @@ -272,7 +624,7 @@ class Partition_manager_UI var flash_size_kb = tasmota.memory()['flash'] - webserver.content_send("

Resize app Partitions.
It is highly recommended to set
both partition with the same size.
SPIFFS is adjusted accordinlgy.

") + webserver.content_send("

Resize app Partitions.
It is highly recommended to set
both partition with the same size.
Filesystem is adjusted accordinlgy.

") webserver.content_send("
") @@ -307,13 +659,13 @@ class Partition_manager_UI webserver.content_send_style() #- send standard Tasmota styles -# # webserver.content_send("

Warning: This can brick your device. Don't use unless you know what you are doing.

") - webserver.content_send("
 Partition Manager

") + webserver.content_send("
 Partition Manager 

") webserver.content_send("

Warning: This can brick your device.

") self.page_show_partitions(p) webserver.content_send("

") if p.otadata.maxota > 0 - webserver.content_send("
 Re-partition

") + webserver.content_send("
 Re-partition 

") self.page_show_repartition_asym(p) webserver.content_send("

") end @@ -359,19 +711,19 @@ class Partition_manager_UI #---------------------------------------------------------------------# # Resize the SPIFFS partition, generally to extend it to full free size #---------------------------------------------------------------------# - elif webserver.has_arg("spiffs_size") + elif webserver.has_arg("fs_size") #- SPIFFS size change -# - var spiffs_size_kb = int(webserver.arg("spiffs_size")) + var spiffs_size_kb = int(webserver.arg("fs_size")) var spiffs_slot = p.slots[-1] # last slot var spiffs_max_size = ((tasmota.memory()['flash'] - (spiffs_slot.start / 1024)) / 16) * 16 - if spiffs_slot == nil || !spiffs_slot.is_spiffs() raise "value_error", "Last slot is not SPIFFS type" end + if spiffs_slot == nil || !spiffs_slot.is_spiffs() raise "value_error", "Last slot is not FS type" end var flash_size_kb = tasmota.memory()['flash'] if spiffs_size_kb < 0 || spiffs_size_kb > spiffs_max_size - raise "value_error", string.format("Invalid spiffs_size %i, should be between 0 and %i", spiffs_size_kb, spiffs_max_size) + raise "value_error", string.format("Invalid fs_size %i, should be between 0 and %i", spiffs_size_kb, spiffs_max_size) end - if spiffs_size_kb == spiffs_slot.size/1024 raise "value_error", "SPIFFS size unchanged, abort" end + if spiffs_size_kb == spiffs_slot.size/1024 raise "value_error", "FS size unchanged, abort" end #- write the new SPIFFS partition size -# spiffs_slot.size = spiffs_size_kb * 1024 @@ -391,7 +743,7 @@ class Partition_manager_UI var app1 = p.get_ota_slot(1) var spiffs = p.slots[-1] - if !spiffs.is_spiffs() raise 'internal_error', 'No SPIFFS partition found' end + if !spiffs.is_spiffs() raise 'internal_error', 'No FS partition found' end if app0 == nil || app1 == nil raise "internal_error", "Unable to find partitions app0 and app1" end @@ -433,7 +785,7 @@ class Partition_manager_UI var app1 = p.get_ota_slot(1) var spiffs = p.slots[-1] - if !spiffs.is_spiffs() raise 'internal_error', 'No SPIFFS partition found' end + if !spiffs.is_spiffs() raise 'internal_error', 'No FS partition found' end if app0 == nil || app1 == nil raise "internal_error", "Unable to find partitions app0 and app1" end diff --git a/tasmota/berry/modules/partition_wizard.be b/tasmota/berry/modules/partition_wizard.be new file mode 100644 index 000000000..445a7a345 --- /dev/null +++ b/tasmota/berry/modules/partition_wizard.be @@ -0,0 +1,802 @@ +####################################################################### +# Partition Wizard for ESP32 - ESP32C3 - ESP32S2 +# +# use : `import partition_wizard` +# +# Provides low-level objects and a Web UI +# rm Partition_Wizard.tapp; zip Partition_Wizard.tapp -j -0 Partition_Wizard/* +####################################################################### + +var partition_wizard = module('partition_wizard') + +################################################################################# +# Partition_wizard_UI +# +# WebUI for the partition manager +################################################################################# +class Partition_wizard_UI + static app_size_min = 832 # Min OTA size - let's set it at a safe 896KB for minimal Tasmota32 with TLS + static app_size_max = 3072 # Max OTA size - (4096 - 896 - 128) + static _default_safeboot_URL = "https://raw.githubusercontent.com/arendst/Tasmota-firmware/main/firmware/tasmota32/tasmota32%s-safeboot.bin" + + def init() + import persist + + if persist.find("factory_migrate") == true + # remove marker to avoid bootloop if something goes wrong + persist.remove("factory_migrate") + persist.save() + + # continue the migration process 5 seconds after Wifi is connected + def continue_after_5s() + tasmota.remove_rule("parwiz_5s") # first remove rule to avoid firing it again at Wifi reconnect + tasmota.set_timer(5000, /-> self.do_safeboot_partitioning()) # delay by 5 s + end + tasmota.add_rule("Wifi#Connected=1", continue_after_5s, "parwiz_5s") + + end + end + + def default_safeboot_URL() + import string + var arch_sub = tasmota.arch() + if arch_sub[0..4] == "esp32" + arch_sub = arch_sub[5..] # get the esp32 variant + end + return string.format(self._default_safeboot_URL, arch_sub) + end + + # create a method for adding a button to the main menu + # the button 'Partition Wizard' redirects to '/part_wiz?' + def web_add_button() + import webserver + webserver.content_send( + "

") + end + + #- ---------------------------------------------------------------------- -# + #- Get fs unallocated size + #- ---------------------------------------------------------------------- -# + def get_unallocated_k(p) + var last_slot = p.slots[-1] + if last_slot.is_spiffs() + # verify that last slot is filesystem + var flash_size_k = self.get_max_flash_size_k(p) + var partition_end_k = (last_slot.start + last_slot.size) / 1024 # last kb used for fs + if partition_end_k < flash_size_k + return flash_size_k - partition_end_k + end + end + return 0 + end + + #- ---------------------------------------------------------------------- -# + #- Get max fs start address when expanded to maximum + #- ---------------------------------------------------------------------- -# + def get_max_fs_start_k(p) + var last_slot = p.slots[-1] + if last_slot.is_spiffs() # verify that last slot is filesystem + # get end of previous partition slot + var last_app = p.slots[-2] + # round upper 64kB + var max_fs_start_k = 64 * (((last_app.start + last_app.get_image_size() + 1023) / 1024 + 63) / 64) + return max_fs_start_k + end + return 0 + end + + #- ---------------------------------------------------------------------- -# + #- Get max falsh size + # + # Takes into account that the flash size written may not be accurate + # and the flash chip may be larger + #- ---------------------------------------------------------------------- -# + def get_max_flash_size_k(p) + var flash_size_k = tasmota.memory()['flash'] + var flash_size_real_k = tasmota.memory().find("flash_real", flash_size_k) + if (flash_size_k != flash_size_real_k) && self.get_flash_definition_sector(p) != nil + flash_size_k = flash_size_real_k # try to expand the flash size definition + end + return flash_size_k + end + + #- ---------------------------------------------------------------------- -# + #- Resize flash definition if needed + #- ---------------------------------------------------------------------- -# + def resize_max_flash_size_k(p) + var flash_size_k = tasmota.memory()['flash'] + var flash_size_real_k = tasmota.memory().find("flash_real", flash_size_k) + var flash_definition_sector = self.get_flash_definition_sector(p) + if (flash_size_k != flash_size_real_k) && flash_definition_sector != nil + import flash + import string + + flash_size_k = flash_size_real_k # try to expand the flash size definition + + var flash_def = flash.read(flash_definition_sector, 4) + var size_before = flash_def[3] + + var flash_size_code + var flash_size_real_m = flash_size_real_k / 1024 # size in MB + if flash_size_real_m == 1 flash_size_code = 0x00 + elif flash_size_real_m == 2 flash_size_code = 0x10 + elif flash_size_real_m == 4 flash_size_code = 0x20 + elif flash_size_real_m == 8 flash_size_code = 0x30 + elif flash_size_real_m == 16 flash_size_code = 0x40 + end + + if flash_size_code != nil + # apply the update + var old_def = flash_def[3] + flash_def[3] = (flash_def[3] & 0x0F) | flash_size_code + flash.write(flash_definition_sector, flash_def) + tasmota.log(string.format("UPL: changing flash definition from 0x02X to 0x%02X", old_def, flash_def[3]), 3) + else + raise "internal_error", "wrong flash size "+str(flash_size_real_m) + end + end + end + + #- ---------------------------------------------------------------------- -# + #- Get current fs size + #- ---------------------------------------------------------------------- -# + def get_cur_fs_size_k(p) + var last_slot = p.slots[-1] + if last_slot.is_spiffs() # verify that last slot is filesystem + return (last_slot.size + 1023) / 1024 + end + return 0 + end + + #- ---------------------------------------------------------------------- -# + #- Get flash sector for flash chip definition + # It appears to be at 0x1000 for ESP32, but at 0x0000 for ESP32C3/S3 + # + # returns offset of sector containing flash information + # or `nil` if not found + # + # Internally looks first at 0x0000 then at 0x1000 for magic byte + #- ---------------------------------------------------------------------- -# + def get_flash_definition_sector(p) + import flash + for i:0..1 + var offset = i * 0x1000 + if flash.read(offset, 1) == bytes('E9') return offset end + end + end + + #- ---------------------------------------------------------------------- -# + #- Propose to resize FS to max if some memory in unallocated + #- ---------------------------------------------------------------------- -# + def show_resize_fs(p) + import webserver + import string + var unallocated = self.get_unallocated_k(p) + + # if there is unallocated space, propose only to claim it + if unallocated > 0 + webserver.content_send("
 Resize FS to max 

") + + webserver.content_send(string.format("

You can expand the file system by %i KB.
Its content will be lost.

", unallocated)) + + webserver.content_send("
") + webserver.content_send("

") + + webserver.content_send("

") + elif self.has_factory_layout(p) + # else propose to expand or shrink the file system + var max_fs_start_k = self.get_max_fs_start_k(p) + var flash_size_k = self.get_max_flash_size_k() + var fs_max_size_k = flash_size_k - max_fs_start_k + var current_fs_size_k = self.get_cur_fs_size_k(p) + #print(string.format(">>> max_fs_start_k=0x%X flash_size_k=0x%X fs_max_size_k=%i current_fs_size_k=%i", max_fs_start_k, flash_size_k, fs_max_size_k, current_fs_size_k)) + + if max_fs_start_k > 0 && fs_max_size_k > 64 + webserver.content_send("
 Resize FS 

") + + webserver.content_send("

You can expand of shrink the file system.
Its content will be lost.

") + + webserver.content_send("
") + webserver.content_send(string.format("", fs_max_size_k, current_fs_size_k)) + webserver.content_send("

") + + webserver.content_send("

") + end + end + end + + #- ---------------------------------------------------------------------- -# + #- Tests for factory layout + #- ---------------------------------------------------------------------- -# + # Returns if the device already has a factory layout: + # devices has 1 factory partition + # device has at least 1 OTA partition + # last partition is FS + # + # returns true or false + def has_factory_layout(p) + return p.has_factory() && p.ota_max() != nil && p.slots[-1].is_spiffs() + end + + #- ---------------------------------------------------------------------- -# + #- Tests for factory migration + #- ---------------------------------------------------------------------- -# + # Returns if the device is eligible for a migration to factory layout: + # devices has 2x OTA partitions + # device has no factory partition + # + # returns true or false + def factory_migrate_eligible(p) + if p.ota_max() <= 0 return false end # device does not have 2x OTA + if p.get_factory_slot() != nil return false end + if !p.slots[-1].is_spiffs() return false end + return true # device does not have factory partition + end + + # ---------------------------------------------------------------------- + # Step 1: + # - pre-condition: + # factory_migrate_eligible(p) returns true + # - DONE state: + # boot on `app1` + # - READY state: + # boot on `app0` + # - Needed steps: + # check that `app1` is large enough for firmware in `app0` + # copy `app0` to `app1` + # restart on `app1` + # set continuation marker in persist to continue migration process at next boto + # + # Returns: + # - false if READY + # - true if DONE + # - string if ERROR, indicating the error + def test_step_1(p) + import string + if !self.factory_migrate_eligible(p) return "not eligible to migration" end + + var cur_part = p.otadata.active_otadata # -1=factory 0=ota_0 1=ota_1... + if cur_part == 1 return true end + if cur_part != 0 return string.format("active_otadata=%i", cur_part) end # unsupported configuration + # current partition is `app0` + # get size of firmware in `app0` and check if it fits on `app1` + var app0 = p.get_ota_slot(0) + var app1 = p.get_ota_slot(0) + var app0_firmware_size = (app0 != nil) ? app0.get_image_size() : -1 + var app1_size = (app1 != nil) ? app1.size : -1 + if app0_firmware_size < 0 || app1_size < 0 return "can't find app0/1 sizes" end + if app0_firmware_size >= app1_size return "`app1` is too small" end + return false + end + + # ---------------------------------------------------------------------- + # Step 2: + # - pre-condition: + # factory_migrate_eligible(p) returns true + # - DONE state: + # `safeboot` flashed to `app0` + # `safeboot` is smaller than 832KB + # - READY state: + # false `safeboot` to `app0` + # - Needed steps: + # get `safeboot` URL + # check that `app0` is large enough for `safeboot` + # check that `safeboot` is smaller than 832KB + # flash `safeboot` on `app0` + # + # Returns: + # - false if READY + # - true if DONE + # - string if ERROR, indicating the error + def test_step_2(p) + import string + if !self.factory_migrate_eligible(p) return "not eligible to migration" end + + var app0 = p.get_ota_slot(0) + if app0.size < (self.app_size_min * 1024) return "`app0` is too small for `safeboot`" end + var app0_image_size = app0.get_image_size() + if (app0_image_size > 0) && (app0_image_size < (self.app_size_min * 1024)) return true end + return false + end + + # ---------------------------------------------------------------------- + # Step 3: + # - pre-condition: + # booted on `app1` and `safeboot` flashed to `app0` + # - DONE state: + # Partition map is: + # `factory` with `safeboot` flashed, sized to 832KB + # `app0` resized to take all the remaining size but empty + # - READY state: + # `app0` is flashed with `safeboot` + # - Needed steps: + # `app0` renamed to `safeboot` + # `app0` changed subtype to `factory` + # `app1` moved to right after `factory` and resized + # `app1` chaned subtype to `app0` and renamed `app0` + # + # Returns: + # - false if READY + # - true if DONE + # - string if ERROR, indicating the error + def test_step_3(p) + import string + if !self.factory_migrate_eligible(p) return "not eligible to migration" end + + return false + # var app0 = p.get_ota_slot(0) + # if app0.get_image_size() > (self.app_size_min * 1024) return "`app0` is too small for `safeboot`" end + end + + + # ---------------------------------------------------------------------- + # Step 4: + # - pre-condition: + # + # Returns: + # - false if READY + # - true if DONE + # - string if ERROR, indicating the error + def test_step_4(p) + import string + + return false + # var app0 = p.get_ota_slot(0) + # if app0.get_image_size() > (self.app_size_min * 1024) return "`app0` is too small for `safeboot`" end + end + + static def copy_ota(from_addr, to_addr, size) + import flash + import string + var size_left = size + var offset = 0 + + tasmota.log(string.format("UPL: Copy flash from 0x%06X to 0x%06X (size: %ikB)", from_addr, to_addr, size / 1024), 2) + while size_left > 0 + var b = flash.read(from_addr + offset, 4096) + flash.erase(to_addr + offset, 4096) + flash.write(to_addr + offset, b, true) + size_left -= 4096 + offset += 4096 + if ((offset-4096) / 102400) < (offset / 102400) + tasmota.log(string.format("UPL: Progress %ikB", offset/1024), 3) + end + end + tasmota.log("UPL: done", 2) + end + + def do_step_1(p) + var step1_state = self.test_step_1(p) + if step1_state == true return true end + if type(step1_state) == 'string)' raise "internal_error", step1_state end + + # copy firmware frop `app0` to `app1` + var app0 = p.get_ota_slot(0) + var app1 = p.get_ota_slot(1) + var app0_size = app0.get_image_size() + if app0_size > app1.size raise "internal_error", "`app1` too small to copy firmware form `app0`" end + self.copy_ota(app0.start, app1.start, app0_size) + + p.set_active(1) + p.save() + + tasmota.log("UPL: restarting on `app1`", 2) + tasmota.cmd("Restart 1") + end + + def do_step_2(p, safeboot_url) + import string + if safeboot_url == nil || safeboot_url == "" + safeboot_url = self.default_safeboot_URL() + tasmota.log("UPL: no `safeboot` URL, defaulting to "+safeboot_url, 2) + end + + var step2_state = self.test_step_2(p) + if step2_state == true return true end + if type(step2_state) == 'string)' raise "internal_error", step2_state end + if safeboot_url == nil || size(safeboot_url) == 0 raise "internal_error", "wrong safeboot URL "+str(safeboot_url) end + + var cl = webclient() + cl.begin(safeboot_url) + var r = cl.GET() + if r != 200 raise "network_error", "GET returned "+str(r) end + var safeboot_size = cl.get_size() + if safeboot_size <= 500000 raise "internal_error", "wrong safeboot size "+str(safeboot_size) end + if safeboot_size > (self.app_size_min * 1024) raise "internal_error", "safeboot is too large "+str(safeboot_size / 1024)+"kB" end + tasmota.log(string.format("UPL: flashing `safeboot` from %s %ikB", safeboot_url, (safeboot_size / 1024) + 1), 2) + var app0 = p.get_ota_slot(0) + if app0.start != 0x10000 raise "internal_error", "`app0` offset is not 0x10000" end + cl.write_flash(app0.start) + cl.close() + return true + end + + + def do_step_3(p) + import string + import flash + + var step3_state = self.test_step_3(p) + if step3_state == true return true end + if type(step3_state) == 'string)' raise "internal_error", step3_state end + + var app0 = p.get_ota_slot(0) + var app1 = p.get_ota_slot(1) + if app0 == nil || app1 == nil raise "internal_error", "there are no `app0` or `app1` partitions" end + var factory_size = self.app_size_min * 1024 + + var firm0_size = app0.get_image_size() + if firm0_size <= 0 raise "internal_error", "invalid size in app0 partition" end + if firm0_size >= factory_size raise "internal_error", "app0 partition is too big for factory" end + + # do the change + app0.subtype = 0 # factory subtype + app0.size = factory_size + app0.label = 'safeboot' + + app1.subtype = 0x10 # app1 becomes app0 + app1.label = 'app0' + var f1_start = app1.start + app1.start = app0.start + factory_size + app1.size += f1_start - app1.start + + # swicth partitions + p.set_active(0) + p.save() + + p.switch_factory(true) + tasmota.cmd("Restart 1") + + return true + end + + + # display the step state DONE/READY/ERROR with color and either step description or error message + # arg + # state: true=DONE, false=READY, string=ERROR with message + # msg: description if DONE or READY + # returns HTML string + def display_step_state(state, msg) + if state == true + return "DONE "+msg + elif state == false + return "READY "+msg + else + return "ERROR "+str(state) + end + end + #- ---------------------------------------------------------------------- -# + #- Show page to migrate to factory layout + single OTA + #- ---------------------------------------------------------------------- -# + def show_migrate_to_factory(p) + # display ota partitions + import webserver + import string + + if !self.factory_migrate_eligible(p) return end + + webserver.content_send("
 Migrate to safeboot partition layout 

") + + webserver.content_send("

The `safeboot` layout allows for increased size
of firmware or file-system.

") + webserver.content_send("

Please see Safeboot layout documentation

") + webserver.content_send("

 

") + + webserver.content_send(string.format("

Step 1: %s

", self.display_step_state(self.test_step_1(p), "boot on `app1`"))) + webserver.content_send(string.format("

Step 2: %s

", self.display_step_state(self.test_step_2(p), "flash `safeboot` to `app0`"))) + webserver.content_send(string.format("

Step 3: %s

", self.display_step_state(self.test_step_3(p), "change partition map"))) + webserver.content_send(string.format("

Step 4: %s

", self.display_step_state(self.test_step_4(p), "flash final firmware"))) + + webserver.content_send("
") + var ota_url = tasmota.cmd("OtaUrl").find("OtaUrl", "") + webserver.content_send(string.format("
OTA Url

", + ota_url)) + + import persist + var safeboot_url = persist.find("safeboot_url", self.default_safeboot_URL()) + webserver.content_send(string.format("
SAFEBOOT Url (don't change)
", + safeboot_url)) + + webserver.content_send("

") + + webserver.content_send("

") + end + + #- ---------------------------------------------------------------------- -# + #- Show each partition one after the other - only OTA and SPIFFS + #- ---------------------------------------------------------------------- -# + def show_current_partitions(p) + # display ota partitions + import webserver + import string + var cur_part = p.otadata.active_otadata # -1=factory 0=ota_0 1=ota_1... + + webserver.content_send("
 Current partitions 

") + + # don't show portion + #webserver.content_send("") + + for slot:p.slots + var is_ota = slot.is_ota() + var is_factory = slot.is_factory() + if (is_ota != nil) || is_factory # display only partitions with app type + var current_boot_partition = (is_ota == cur_part) || (is_factory && cur_part == -1) + + var usage_str = "unknown" + var used = slot.get_image_size() + if (used >= 0) && (used <= slot.size) + usage_str = string.format("used %i%%", ((used / 1024) * 100) / (slot.size / 1024)) + end + var title = string.format("%ssubtype:%s offset:0x%06X size:0x%06X", current_boot_partition ? "booted " : "", slot.subtype_to_string(), slot.start, slot.size) + var col_before = "" + var col_after = "" + if current_boot_partition + col_before = "[" + col_after = "]" + end + # webserver.content_send(string.format("

%s [%s]: %i KB (%s)

", slot.label, slot.subtype_to_string(), slot.size / 1024, usage_str)) + webserver.content_send(string.format("", + title, col_before, slot.label, col_after, slot.size / 1024, usage_str)) + elif slot.is_spiffs() + # spiffs partition + var title = string.format("subtype:%s offset:0x%06X size:0x%06X", slot.subtype_to_string(), slot.start, slot.size) + webserver.content_send(string.format("", title, slot.size / 1024)) + end + end + + var unallocated = self.get_unallocated_k(p) + if unallocated > 0 + var last_slot = p.slots[-1] + # verify that last slot is file-system + var partition_end_k = (last_slot.start + last_slot.size) / 1024 # last kb used for fs + webserver.content_send(string.format("", + partition_end_k * 1024, unallocated * 1024, unallocated)) + end + webserver.content_send("
<sys>:  64 KB
%s%s%s %i KB  (%s)
fs %i KB
<free>:  %i KB
") + + # display if layout is factory + if self.has_factory_layout(p) + webserver.content_send("

This device uses the safeboot layout

") + end + + webserver.content_send("

") + + end + + ####################################################################### + # Display the complete page + ####################################################################### + def page_part_mgr() + import webserver + import string + import partition_core + if !webserver.check_privileged_access() return nil end + var p = partition_core.Partition() # load partition layout + + webserver.content_start("Partition Wizard") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + + if webserver.has_arg("wait") + webserver.content_send("

Migration process will start in 5 seconds
Magic is happening, leave device alone for 3 minutes.

") + webserver.content_button(webserver.BUTTON_MAIN) #- button back to main page -# + else + webserver.content_send("

Warning: actions below can brick your device.

") + self.show_current_partitions(p) + self.show_resize_fs(p) + # show page for migration to factory + self.show_migrate_to_factory(p) + webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -# + end + + webserver.content_stop() #- end of web page -# + end + + ####################################################################### + # Web Controller, called by POST to `/part_wiz` + ####################################################################### + def page_part_ctl() + import webserver + if !webserver.check_privileged_access() return nil end + + import string + import partition_core + import persist + + + #- check that the partition is valid -# + var p = partition_core.Partition() + + try + + #---------------------------------------------------------------------# + # Resize FS to max + #---------------------------------------------------------------------# + if webserver.has_arg("max_fs") + var unallocated = self.get_unallocated_k(p) + if unallocated <= 0 raise "value_error", "FS already at max size" end + + self.resize_max_flash_size_k(p) # resize if needed + + # since unallocated succeeded, we know the last slot is FS + var fs_slot = p.slots[-1] + fs_slot.size += unallocated * 1024 + p.save() + p.invalidate_spiffs() # erase SPIFFS or data is corrupt + + #- and force restart -# + webserver.redirect("/?rst=") + + #---------------------------------------------------------------------# + # Resize FS to arbitrary size + #---------------------------------------------------------------------# + elif webserver.has_arg("resize_fs") + if !self.has_factory_layout(p) raise "internal_error", "Device does not avec safeboot layout" end + + var fs = p.slots[-1] + var last_app = p.slots[-2] + if (last_app.get_image_size() <= 0) raise "internal_error", "last `app` partition has no firmware" end + + var max_fs_start_k = self.get_max_fs_start_k(p) + var flash_size_k = self.get_max_flash_size_k(p) + + var fs_max_size_k = flash_size_k - max_fs_start_k + var current_fs_size_k = self.get_cur_fs_size_k(p) + + var fs_target = int(webserver.arg("fs_size")) + if (fs_target < 64) || (fs_target > fs_max_size_k) raise "value_error", string.format("Invalid FS #%d", fs_target) end + + # apply the change + # shrink last OTA App + var delta = (fs_target * 1024) - fs.size + last_app.size -= delta + + # move fs + fs.start -= delta + fs.size += delta + p.save() + p.invalidate_spiffs() + + #- and force restart -# + webserver.redirect("/?rst=") + #---------------------------------------------------------------------# + # Switch OTA partition from one to another + #---------------------------------------------------------------------# + elif webserver.has_arg("factory") + var ota_url = webserver.arg("o1") + var safeboot_url = webserver.arg("o2") + + if safeboot_url != nil && safeboot_url != "" + persist.safeboot_url = safeboot_url + persist.save() + end + + if ota_url != nil && ota_url != "" + tasmota.cmd("OtaUrl "+ota_url) + end + + tasmota.set_timer(5000, /-> self.do_safeboot_partitioning()) + webserver.redirect("/part_wiz?wait=") + + else + raise "value_error", "Unknown command" + end + except .. as e, m + tasmota.log(string.format("BRY: Exception> '%s' - %s", e, m), 2) + #- display error page -# + webserver.content_start("Parameter error") #- title of the web page -# + webserver.content_send_style() #- send standard Tasmota styles -# + + webserver.content_send(string.format("

Exception:
'%s'
%s

", e, m)) + # webserver.content_send("

") + + webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -# + webserver.content_stop() #- end of web page -# + end + end + + + + #---------------------------------------------------------------------# + # Apply the repartitioning process + #---------------------------------------------------------------------# + # returns: + # `true`: already completed + # `false`: in progress + # string: error with description of error + def do_safeboot_partitioning() + import webserver + import string + import partition_core + + var p = partition_core.Partition() # load partition layout + if !self.factory_migrate_eligible(p) return true end + + # STEP 1 + var step1_state = self.test_step_1(p) + if type(step1_state) == 'string' return step1_state end + if step1_state == false + import persist + tasmota.log("UPL: Starting step 1", 2) + try + self.do_step_1(p) + except .. as e, m + tasmota.log(string.format("UPL: error (%s) %s", e, m), 2) + return m + end + persist.factory_migrate = true + persist.save() + return false + end + tasmota.log("UPL: Step 1 Done", 2) + + # STEP 2 + var step2_state = self.test_step_2(p) + if type(step2_state) == 'string' return step2_state end + if step2_state == false + tasmota.log("UPL: Starting step 2", 2) + import persist + var safeboot_url = persist.find("safeboot_url") + try + self.do_step_2(p, safeboot_url) + except .. as e, m + tasmota.log(string.format("UPL: error (%s) %s", e, m), 2) + return m + end + end + tasmota.log("UPL: Step 2 Done", 2) + + # STEP 3 + var step3_state = self.test_step_3(p) + if type(step3_state) == 'string' return step3_state end + if step3_state == false + tasmota.log("UPL: Starting step 3", 2) + try + self.do_step_3(p) + except .. as e, m + tasmota.log(string.format("UPL: error (%s) %s", e, m), 2) + return m + end + end + tasmota.log("UPL: Step 3 Done", 2) + + # STEP 4 + # Nothing to do, it's automatic + return false + end + + #- ---------------------------------------------------------------------- -# + # respond to web_add_handler() event to register web listeners + #- ---------------------------------------------------------------------- -# + #- this is called at Tasmota start-up, as soon as Wifi/Eth is up and web server running -# + def web_add_handler() + import webserver + #- we need to register a closure, not just a function, that captures the current instance -# + webserver.on("/part_wiz", / -> self.page_part_mgr(), webserver.HTTP_GET) + webserver.on("/part_wiz", / -> self.page_part_ctl(), webserver.HTTP_POST) + end +end +partition_wizard.Partition_wizard_UI = Partition_wizard_UI + + +#- create and register driver in Tasmota -# +if tasmota + import partition_core + var partition_wizard_ui = partition_wizard.Partition_wizard_UI() + tasmota.add_driver(partition_wizard_ui) + ## can be removed if put in 'autoexec.bat' + partition_wizard_ui.web_add_handler() +end + +return partition_wizard + +#- Example + +import partition + +# read +p = partition.Partition() +print(p) + +-# diff --git a/tasmota/berry/openhasp/openhasp.tapp b/tasmota/berry/openhasp/openhasp.tapp index 7d4138e9a..f14e88438 100644 Binary files a/tasmota/berry/openhasp/openhasp.tapp and b/tasmota/berry/openhasp/openhasp.tapp differ diff --git a/tasmota/berry/openhasp/openhasp_demo.tapp b/tasmota/berry/openhasp/openhasp_demo.tapp index 995db1faa..aac2e5967 100644 Binary files a/tasmota/berry/openhasp/openhasp_demo.tapp and b/tasmota/berry/openhasp/openhasp_demo.tapp differ diff --git a/tasmota/berry/openhasp_src/gen_openhasp.sh b/tasmota/berry/openhasp_src/gen_openhasp.sh new file mode 100755 index 000000000..711398637 --- /dev/null +++ b/tasmota/berry/openhasp_src/gen_openhasp.sh @@ -0,0 +1,5 @@ +# generate all openhasp tapp files +rm openhasp.tapp; zip -j -0 openhasp.tapp openhasp_core/* +rm openhasp_demo.tapp ; zip -j -0 openhasp_demo.tapp openhasp_demo/* openhasp_core/openhasp.be +cp openhasp.tapp ../openhasp +cp openhasp_demo.tapp ../openhasp diff --git a/tasmota/berry/openhasp_src/openhasp.tapp b/tasmota/berry/openhasp_src/openhasp.tapp index 7d4138e9a..f14e88438 100644 Binary files a/tasmota/berry/openhasp_src/openhasp.tapp and b/tasmota/berry/openhasp_src/openhasp.tapp differ diff --git a/tasmota/berry/openhasp_src/openhasp_core/openhasp.be b/tasmota/berry/openhasp_src/openhasp_core/openhasp.be index 3ac250322..d4de2b209 100644 --- a/tasmota/berry/openhasp_src/openhasp_core/openhasp.be +++ b/tasmota/berry/openhasp_src/openhasp_core/openhasp.be @@ -71,8 +71,8 @@ class lvh_obj "w": "width", "h": "height", # arc - "asjustable": nil, - "mode": nil, + # "asjustable": nil, + # "mode": nil, "start_angle": "bg_start_angle", "start_angle1": "start_angle", "end_angle": "bg_end_angle", @@ -81,13 +81,13 @@ class lvh_obj "border_side": "style_border_side", "border_width": "style_border_width", "border_color": "style_border_color", - "line_width": nil, # depends on class - "line_width1": nil, # depends on class - "action": nil, # store the action in self.action - "hidden": nil, # apply to self - "enabled": nil, # apply to self - "click": nil, # synonym to enabled - "toggle": nil, + # "line_width": nil, # depends on class + # "line_width1": nil, # depends on class + # "action": nil, # store the action in self.action + # "hidden": nil, # apply to self + # "enabled": nil, # apply to self + # "click": nil, # synonym to enabled + # "toggle": nil, "bg_color": "style_bg_color", "bg_opa": "style_bg_opa", "bg_grad_color": "style_bg_grad_color", @@ -98,48 +98,50 @@ class lvh_obj "pad_top": "style_pad_top", "pad_bottom": "style_pad_bottom", "pad_all": "style_pad_all", # write-only - "type": nil, + # "type": nil, # below automatically create a sub-label - "text": nil, # apply to self - "value_str": nil, # synonym to 'text' - "align": nil, - "text_font": nil, - "value_font": nil, # synonym to text_font - "text_color": nil, - "value_color": nil, # synonym to text_color - "value_ofs_x": nil, - "value_ofs_y": nil, + # "text": nil, # apply to self + # "value_str": nil, # synonym to 'text' + # "align": nil, + # "text_font": nil, + # "value_font": nil, # synonym to text_font + # "text_color": nil, + # "value_color": nil, # synonym to text_color + # "value_ofs_x": nil, + # "value_ofs_y": nil, # - "min": nil, - "max": nil, - "val": "value", + # "min": nil, + # "max": nil, + # "val": nil, "rotation": "rotation", # img "src": "src", "image_recolor": "style_img_recolor", "image_recolor_opa": "style_img_recolor_opa", # spinner - "angle": nil, - "speed": nil, + # "angle": nil, + # "speed": nil, # padding of knob - "pad_top2": nil, - "pad_bottom2": nil, - "pad_left2": nil, - "pad_right2": nil, - "pad_all2": nil, - "radius2": nil, + # "pad_top2": nil, + # "pad_bottom2": nil, + # "pad_left2": nil, + # "pad_right2": nil, + # "pad_all2": nil, + # "radius2": nil, # rule based update of attributes # supporting both `val` and `text` - "val_rule": nil, - "val_rule_formula": nil, - "text_rule": nil, - "text_rule_formula": nil, - "text_rule_format": nil, + # "val_rule": nil, + # "val_rule_formula": nil, + # "text_rule": nil, + # "text_rule_formula": nil, + # "text_rule_format": nil, + # roller + # "options": nil, # qrcode - "qr_size": nil, - "qr_dark_color": nil, - "qr_light_color": nil, - "qr_text": nil, + # "qr_size": nil, + # "qr_dark_color": nil, + # "qr_light_color": nil, + # "qr_text": nil, } #==================================================================== @@ -173,6 +175,21 @@ class lvh_obj return bool(re.search("color$", str(t))) end + #- remove trailing NULL chars from a bytes buffer before converting to string -# + #- Berry strings can contain NULL, but this messes up C-Berry interface -# + static def remove_trailing_zeroes(b) + var sz = size(b) + var i = 0 + while i < sz + if b[-1-i] != 0 break end + i += 1 + end + if i > 0 + b.resize(size(b)-i) + end + return b + end + ################################################################################# # Parses a color attribute # @@ -317,9 +334,24 @@ class lvh_obj if event_hasp != nil import string - var val = string.format('{"hasp":{"p%ib%i":"%s"}}', self._page._page_id, self.id, event_hasp) + var tas_event_more = "" # complementary data + if event.code == lv.EVENT_VALUE_CHANGED + try + # try to get the new val + var val = self.val + if val != nil tas_event_more = string.format(',"val":%i', val) end + var text = self.text + if text != nil + import json + tas_event_more += ',"text":' + tas_event_more += json.dump(text) + end + except .. + end + end + var tas_event = string.format('{"hasp":{"p%ib%i":{"event":"%s"%s}}}', self._page._page_id, self.id, event_hasp, tas_event_more) # print("val=",val) - tasmota.set_timer(0, /-> tasmota.publish_rule(val)) + tasmota.set_timer(0, /-> tasmota.publish_rule(tas_event)) end end @@ -611,6 +643,12 @@ class lvh_obj def get_pad_all() end + def set_val(t) + self._lv_obj.set_value(t) + end + def get_val() + return self._lv_obj.get_value() + end #==================================================================== # `radius2` #==================================================================== @@ -635,37 +673,35 @@ class lvh_obj #- ------------------------------------------------------------# def member(k) import string - # ignore attributes - # print("member","self=",self,"k=",k) + import introspect + + # print("> getmember", k) + var prefix = k[0..3] + if prefix == "set_" || prefix == "get_" return end + # if attribute name is in ignore list, abort if self._attr_ignore.find(k) != nil return end - # check if the key is known + # first check if there is a method named `get_X()` + var f = introspect.get(self, "get_" + k) # call self method + if type(f) == 'function' + return f(self) + end + + # next check if there is a mapping to an LVGL attribute if self._attr_map.contains(k) - # attribute is known - # kv: (if string) the LVGL attribute name of the object - direct mapping - # kv: (if `nil`) call `get_` method of the object - import introspect var kv = self._attr_map[k] - if kv == nil - # call the object's `get_X()` - var f = introspect.get(self, "get_" + k) # call self method - if type(f) == 'function' - return f(self) - end - else - # call the native LVGL object method - var f = introspect.get(self._lv_obj, "get_" + kv) - if type(f) == 'function' # found and function, call it - if string.find(kv, "style_") == 0 - # style function need a selector as second parameter - return f(self._lv_obj, 0 #- lv.PART_MAIN | lv.STATE_DEFAULT -#) - else - return f(self._lv_obj) - end + f = introspect.get(self._lv_obj, "get_" + kv) + if type(f) == 'function' # found and function, call it + if string.find(kv, "style_") == 0 + # style function need a selector as second parameter + return f(self._lv_obj, 0 #- lv.PART_MAIN | lv.STATE_DEFAULT -#) + else + return f(self._lv_obj) end end end + # fallback to exception if attribute unknown or not a function raise "value_error", "unknown attribute " + str(k) end @@ -674,45 +710,44 @@ class lvh_obj # `setmember` virtual setter #- ------------------------------------------------------------# def setmember(k, v) - # print(">> setmember", k, v) - # print(">>", classname(self), self._attr_map) - # ignore attributes + import string + import introspect + + # print("> setmember", k, v) + var prefix = k[0..3] + if prefix == "set_" || prefix == "get_" return end + # if attribute name is in ignore list, abort if self._attr_ignore.find(k) != nil return end - # is attribute known + + # first check if there is a method named `set_X()` + var f = introspect.get(self, "set_" + k) + if type(f) == 'function' + f(self, v) + return + end + + # next check if there is a mapping to an LVGL attribute if self._attr_map.contains(k) - import string - import introspect - var kv = self._attr_map[k] - # if a string is attached to the name, then set the corresponding LVGL attribute - if kv - var f = introspect.get(self._lv_obj, "set_" + kv) - # if the attribute contains 'color', convert to lv_color - if type(kv) == 'string' && self.is_color_attribute(kv) - v = self.parse_color(v) - end - # print("f=", f, v, kv, self._lv_obj, self) - if type(f) == 'function' - if string.find(kv, "style_") == 0 - # style function need a selector as second parameter - f(self._lv_obj, v, 0 #- lv.PART_MAIN | lv.STATE_DEFAULT -#) - else - f(self._lv_obj, v) - end - return - else - print("HSP: Could not find function set_"+kv) - end - else - # else call the specific method from self - var f = introspect.get(self, "set_" + k) - # print("f==",f) - if type(f) == 'function' - f(self, v) - return - end - end + var kv = self._attr_map[k] + f = introspect.get(self._lv_obj, "set_" + kv) + # if the attribute contains 'color', convert to lv_color + if self.is_color_attribute(kv) + v = self.parse_color(v) + end + # print("f=", f, v, kv, self._lv_obj, self) + if type(f) == 'function' + if string.find(kv, "style_") == 0 + # style function need a selector as second parameter + f(self._lv_obj, v, 0 #- lv.PART_MAIN | lv.STATE_DEFAULT -#) + else + f(self._lv_obj, v) + end + return + else + print("HSP: Could not find function set_"+kv) + end else print("HSP: unknown attribute:", k) end @@ -987,6 +1022,116 @@ class lvh_qrcode : lvh_obj def get_qr_text() end end +#==================================================================== +# slider +#==================================================================== +class lvh_slider : lvh_obj + static _lv_class = lv.slider + + def set_val(t) + self._lv_obj.set_value(t, 0) # add second parameter - no animation + end +end + +#==================================================================== +# roller +#==================================================================== +class lvh_roller : lvh_obj + static _lv_class = lv.roller + + def set_val(t) + self._lv_obj.set_selected(t, 0) # add second parameter - no animation + end + def get_val() + return self._lv_obj.get_selected() + end + + def set_options(t) + self._lv_obj.set_options(t, lv.ROLLER_MODE_NORMAL) + end + def get_options() + return self._lv_obj.get_options() + end + + def set_text(t) + raise "attribute_error", "set_text unsupported on roller" + end + def get_text() + # allocate a bytes buffer + var b = bytes().resize(256) # force 256 bytes + self._lv_obj.get_selected_str(b._buffer(), 256) + b = self.remove_trailing_zeroes(b) + return b.asstring() + end +end + +#==================================================================== +# dropdown +#==================================================================== +class lvh_dropdown : lvh_obj + static _lv_class = lv.dropdown + static _dir = [ lv.DIR_BOTTOM, lv.DIR_TOP, lv.DIR_LEFT, lv.DIR_RIGHT ] # 0 = down, 1 = up, 2 = left, 3 = right + + def set_val(t) + self._lv_obj.set_selected(t, 0) # add second parameter - no animation + end + def get_val() + return self._lv_obj.get_selected() + end + + def set_options(t) + self._lv_obj.set_options(t, lv.ROLLER_MODE_NORMAL) + end + def get_options() + return self._lv_obj.get_options() + end + + def set_text(t) + # set_text sets a static text displayed whatever the value + # use `nil` to set back the text of the selected value + self._lv_obj.set_text(t) + end + def get_text() + var static_text = self._lv_obj.get_text() + if static_text == nil + # allocate a bytes buffer + var b = bytes().resize(256) # force 256 bytes + self._lv_obj.get_selected_str(b._buffer(), 256) + b = self.remove_trailing_zeroes(b) + return b.asstring() + else + return static_text + end + end + + # direction needs a conversion from OpenHASP numbers and LVGL's + def set_direction(t) + # 0 = down, 1 = up, 2 = left, 3 = right + self._lv_obj.set_dir(self._dir[int(t)]) + end + def get_direction() + var dir = self._lv_obj.get_dir() + var i = 0 + while i < size(self._dir) + if dir == self._dir[i] return i end + i += 1 + end + return -1 + end + + # show_selected (bool) is a OpenHASP addition + # only meaningful if set to `true`, setting to false requires a call to `set_text` + def set_show_selected(t) + if t + self._lv_obj.set_text(nil) # undo static text + end + end + def get_show_selected() + var static_text = self._lv_obj.get_text() + return (static_text == nil) + end +end + ################################################################################# # # All other subclasses than just map the LVGL object @@ -997,10 +1142,7 @@ class lvh_bar : lvh_obj static _lv_class = lv.bar end class lvh_btn : lvh_obj static _lv_class = lv.btn end class lvh_btnmatrix : lvh_obj static _lv_class = lv.btnmatrix end class lvh_checkbox : lvh_obj static _lv_class = lv.checkbox end -class lvh_dropdown : lvh_obj static _lv_class = lv.dropdown end class lvh_line : lvh_obj static _lv_class = lv.line end -class lvh_roller : lvh_obj static _lv_class = lv.roller end -class lvh_slider : lvh_obj static _lv_class = lv.slider end class lvh_textarea : lvh_obj static _lv_class = lv.textarea end # special case for scr (which is actually lv_obj) class lvh_scr : lvh_obj static _lv_class = nil end # no class for screen diff --git a/tasmota/berry/openhasp_src/openhasp_demo.tapp b/tasmota/berry/openhasp_src/openhasp_demo.tapp index 995db1faa..aac2e5967 100644 Binary files a/tasmota/berry/openhasp_src/openhasp_demo.tapp and b/tasmota/berry/openhasp_src/openhasp_demo.tapp differ diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 825d23be4..968c0e1cd 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Wagwoord" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Poort" #define D_POWER_FACTOR "Krag faktor" #define D_POWERUSAGE "Krag" @@ -183,6 +184,7 @@ #define D_UPGRADE "opgradeer" #define D_UPLOAD "Laai op" #define D_UPTIME "Uptyd" +#define D_USED "used" #define D_USER "Gebruiker" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Indeks" diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h index c3af37b86..c59f70c66 100644 --- a/tasmota/language/bg_BG.h +++ b/tasmota/language/bg_BG.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Парола" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Порт" #define D_POWER_FACTOR "Фактор на мощността" #define D_POWERUSAGE "Мощност" @@ -183,6 +184,7 @@ #define D_UPGRADE "Обновяване" #define D_UPLOAD "Качването е" #define D_UPTIME "Време на работа" +#define D_USED "used" #define D_USER "Потребител" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Индекс на UV" diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h index 74a161c07..b1b1ec1ab 100644 --- a/tasmota/language/cs_CZ.h +++ b/tasmota/language/cs_CZ.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Heslo" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Účiník" #define D_POWERUSAGE "Příkon" @@ -183,6 +184,7 @@ #define D_UPGRADE "aktualizace" #define D_UPLOAD "Nahrání..." #define D_UPTIME "Uptime" +#define D_USED "used" #define D_USER "Uživatel" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h index 545e376c8..1d7916525 100644 --- a/tasmota/language/de_DE.h +++ b/tasmota/language/de_DE.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Passwort" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Leistungsfaktor" #define D_POWERUSAGE "Leistung" @@ -183,6 +184,7 @@ #define D_UPGRADE "update" #define D_UPLOAD "Upload" #define D_UPTIME "Laufzeit" +#define D_USED "used" #define D_USER "Benutzer" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV-Index" diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h index 2c7678402..45c6f9038 100644 --- a/tasmota/language/el_GR.h +++ b/tasmota/language/el_GR.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Κωδικός" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Θύρα" #define D_POWER_FACTOR "Συντελεστής Ισχύος" #define D_POWERUSAGE "Ισχύς" @@ -183,6 +184,7 @@ #define D_UPGRADE "αναβάθμιση" #define D_UPLOAD "Ανέβασμα" #define D_UPTIME "Χρόνος λειτουργίας" +#define D_USED "used" #define D_USER "Χρήστης" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Δείκτης UV" diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h index 1a0a40251..ba25d36ae 100644 --- a/tasmota/language/en_GB.h +++ b/tasmota/language/en_GB.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Password" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Power Factor" #define D_POWERUSAGE "Power" @@ -183,6 +184,7 @@ #define D_UPGRADE "upgrade" #define D_UPLOAD "Upload" #define D_UPTIME "Uptime" +#define D_USED "used" #define D_USER "User" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h index a8f9af1d3..acc71ce36 100644 --- a/tasmota/language/es_ES.h +++ b/tasmota/language/es_ES.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Clave" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Puerto" #define D_POWER_FACTOR "Factor de Potencia" #define D_POWERUSAGE "Potencia" @@ -183,6 +184,7 @@ #define D_UPGRADE "Actualización" #define D_UPLOAD "Carga" #define D_UPTIME "Tiempo Encendido" +#define D_USED "used" #define D_USER "Usuario" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Índice UV" diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h index a91d40aa2..c27665fe7 100644 --- a/tasmota/language/fr_FR.h +++ b/tasmota/language/fr_FR.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Mot de passe" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Fact de puiss" #define D_POWERUSAGE "Puissance" @@ -183,6 +184,7 @@ #define D_UPGRADE "la mise à jour" // "Lancer la mise à jour" #define D_UPLOAD "Upload" // Not better in french #define D_UPTIME "Durée d'activité" +#define D_USED "used" #define D_USER "Utilisateur" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Indice UV" diff --git a/tasmota/language/fy_NL.h b/tasmota/language/fy_NL.h index 66fbd2807..db6150f80 100644 --- a/tasmota/language/fy_NL.h +++ b/tasmota/language/fy_NL.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Wachtwurd" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Poort" #define D_POWER_FACTOR "Krêftfaktor" #define D_POWERUSAGE "Krêft" @@ -183,6 +184,7 @@ #define D_UPGRADE "upgrade" #define D_UPLOAD "Stjoere" #define D_UPTIME "Betjenstiid" +#define D_USED "used" #define D_USER "Brûker" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV-index" diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h index ede44be67..9ca125c10 100644 --- a/tasmota/language/he_HE.h +++ b/tasmota/language/he_HE.h @@ -140,6 +140,7 @@ #define D_PASSWORD "סיסמא" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "פורט" #define D_POWER_FACTOR "גורם כוח" #define D_POWERUSAGE "כוח" @@ -183,6 +184,7 @@ #define D_UPGRADE "שדרוג" #define D_UPLOAD "העלאה" #define D_UPTIME "זמן עליה" +#define D_USED "used" #define D_USER "משתמש" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV אינדקס" diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h index 85e025581..ee64407b3 100644 --- a/tasmota/language/hu_HU.h +++ b/tasmota/language/hu_HU.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Jelszó" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Teljesítménytényező" #define D_POWERUSAGE "Energiafelhasználás" @@ -183,6 +184,7 @@ #define D_UPGRADE "Frissítés" #define D_UPLOAD "Feltöltés" #define D_UPTIME "Üzemidő" +#define D_USED "used" #define D_USER "Felhasználó" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV index" diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h index 90a977c7a..dd6d4e146 100644 --- a/tasmota/language/it_IT.h +++ b/tasmota/language/it_IT.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v9.4.0.1 - Last update 05.05.2022 + * Updated until v9.4.0.1 - Last update 15.05.2022 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -140,6 +140,7 @@ #define D_PASSWORD "Password" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partizione" // As in flash and firmware partition #define D_PORT "Porta" #define D_POWER_FACTOR "Fattore di potenza" #define D_POWERUSAGE "Potenza" @@ -177,12 +178,13 @@ #define D_TOGGLE "ON/OFF" #define D_TOPIC "Topic" #define D_TOTAL_USAGE "Uso totale" -#define D_TRANSMIT "Trasmesso" +#define D_TRANSMIT "Trasmessi" #define D_TRUE "Vero" #define D_TVOC "TVOC" #define D_UPGRADE "aggiornamento" #define D_UPLOAD "Caricamento" #define D_UPTIME "Tempo accensione" +#define D_USED "usati" #define D_USER "Utente" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Indice UV" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index c70b64479..40f4cd824 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -140,6 +140,7 @@ #define D_PASSWORD "비밀번호" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "포트" #define D_POWER_FACTOR "Power Factor" #define D_POWERUSAGE "전원" @@ -183,6 +184,7 @@ #define D_UPGRADE "업그레이드" #define D_UPLOAD "업로드" #define D_UPTIME "가동시간" +#define D_USED "used" #define D_USER "User" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV 색인" diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h index 8ff61cd1c..0e5cf5a06 100644 --- a/tasmota/language/nl_NL.h +++ b/tasmota/language/nl_NL.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Wachtwoord" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Poort" #define D_POWER_FACTOR "Arbeidsfactor" #define D_POWERUSAGE "Vermogen" @@ -183,6 +184,7 @@ #define D_UPGRADE "opwaarderen" #define D_UPLOAD "Verzenden" #define D_UPTIME "Bedrijfstijd" +#define D_USED "used" #define D_USER "Gebruiker" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV-index" diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h index e4f65d35a..81b2bf557 100644 --- a/tasmota/language/pl_PL.h +++ b/tasmota/language/pl_PL.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Hasło" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Cosinus fi" #define D_POWERUSAGE "Moc" @@ -183,6 +184,7 @@ #define D_UPGRADE "aktualizacji" #define D_UPLOAD "Wgraj" #define D_UPTIME "Czas pracy" +#define D_USED "used" #define D_USER "Użytkownik" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Indeks UV" diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h index d689d83ce..866960151 100644 --- a/tasmota/language/pt_BR.h +++ b/tasmota/language/pt_BR.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Senha" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Porta" #define D_POWER_FACTOR "Fator de potência" #define D_POWERUSAGE "Potência" @@ -183,6 +184,7 @@ #define D_UPGRADE "atualização" #define D_UPLOAD "Enviar" #define D_UPTIME "Tempo de atividade" +#define D_USED "used" #define D_USER "Usuário" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Índice UV" diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h index 715904df4..6da2d62cb 100644 --- a/tasmota/language/pt_PT.h +++ b/tasmota/language/pt_PT.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Palavra Chave" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Porta" #define D_POWER_FACTOR "Factor de Potência" #define D_POWERUSAGE "Potência" @@ -183,6 +184,7 @@ #define D_UPGRADE "Atualizar" #define D_UPLOAD "Enviar" #define D_UPTIME "Tempo de Atividade" +#define D_USED "used" #define D_USER "Utilizador" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Indíce UV" diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h index a57b8bade..4cfa25cb6 100644 --- a/tasmota/language/ro_RO.h +++ b/tasmota/language/ro_RO.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Parolă" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Factor de Putere" #define D_POWERUSAGE "Putere" @@ -183,6 +184,7 @@ #define D_UPGRADE "actualizare" #define D_UPLOAD "Încărcăre" #define D_UPTIME "Folosință" +#define D_USED "used" #define D_USER "Utilizator" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Index UV" diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h index ea148c878..fc83143b0 100644 --- a/tasmota/language/ru_RU.h +++ b/tasmota/language/ru_RU.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Пароль" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Порт" #define D_POWER_FACTOR "Коэффициент мощности" #define D_POWERUSAGE "Мощность" @@ -183,6 +184,7 @@ #define D_UPGRADE "обновление" #define D_UPLOAD "Загрузить" #define D_UPTIME "Uptime" +#define D_USED "used" #define D_USER "Пользователь" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h index e0626e909..840edb230 100644 --- a/tasmota/language/sk_SK.h +++ b/tasmota/language/sk_SK.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Heslo" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Účinník" #define D_POWERUSAGE "Príkon" @@ -183,6 +184,7 @@ #define D_UPGRADE "aktualizáciu" #define D_UPLOAD "Nahrávanie..." #define D_UPTIME "Uptime" +#define D_USED "used" #define D_USER "Používateľ" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h index 38ef28862..1a3b7c6fd 100644 --- a/tasmota/language/sv_SE.h +++ b/tasmota/language/sv_SE.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Lösenord" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Spänningsfaktor" #define D_POWERUSAGE "Spänning" @@ -183,6 +184,7 @@ #define D_UPGRADE "uppgradera" #define D_UPLOAD "Ladda upp" #define D_UPTIME "Upptid" +#define D_USED "used" #define D_USER "Användare" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h index b6005ade9..a2c341ee6 100644 --- a/tasmota/language/tr_TR.h +++ b/tasmota/language/tr_TR.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Şifre" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Port" #define D_POWER_FACTOR "Güç Faktörü" #define D_POWERUSAGE "Güç" @@ -183,6 +184,7 @@ #define D_UPGRADE "yükseltme" #define D_UPLOAD "Yükleme" #define D_UPTIME "Açık Kalma Süresi" +#define D_USED "used" #define D_USER "Kullanıcı" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Indeksi" diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h index 756e61b44..c93062ef7 100644 --- a/tasmota/language/uk_UA.h +++ b/tasmota/language/uk_UA.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Гасло" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Порт" #define D_POWER_FACTOR "Коефіцієнт потужності" #define D_POWERUSAGE "Потужність" @@ -183,6 +184,7 @@ #define D_UPGRADE "оновлення" #define D_UPLOAD "Завантажити" #define D_UPTIME "Час роботи" +#define D_USED "used" #define D_USER "Користувач" #define D_UTC_TIME "UTC" #define D_UV_INDEX "Індекс УФ" diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h index 3fdb716bd..44d92507b 100644 --- a/tasmota/language/vi_VN.h +++ b/tasmota/language/vi_VN.h @@ -140,6 +140,7 @@ #define D_PASSWORD "Mật khẩu" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "Cổng" #define D_POWER_FACTOR "Hệ số công suất" #define D_POWERUSAGE "Công suất" @@ -183,6 +184,7 @@ #define D_UPGRADE "nâng cấp" #define D_UPLOAD "Tải lên" #define D_UPTIME "Thời gian chạy" +#define D_USED "used" #define D_USER "Người dùng" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h index a2437a739..cde32877e 100644 --- a/tasmota/language/zh_CN.h +++ b/tasmota/language/zh_CN.h @@ -140,6 +140,7 @@ #define D_PASSWORD "密码" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "端口" #define D_POWER_FACTOR "功率因数" #define D_POWERUSAGE "功率" @@ -183,6 +184,7 @@ #define D_UPGRADE "升级" #define D_UPLOAD "上传" #define D_UPTIME "运行时间" +#define D_USED "used" #define D_USER "用户名" #define D_UTC_TIME "UTC" #define D_UV_INDEX "紫外线指数" diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h index 205162560..95639cc38 100644 --- a/tasmota/language/zh_TW.h +++ b/tasmota/language/zh_TW.h @@ -140,6 +140,7 @@ #define D_PASSWORD "密碼" #define D_PH "pH" #define D_MQ "MQ" +#define D_PARTITION "Partition" // As in flash and firmware partition #define D_PORT "通訊埠" #define D_POWER_FACTOR "功率因數" #define D_POWERUSAGE "用電量" @@ -183,6 +184,7 @@ #define D_UPGRADE "升級" #define D_UPLOAD "上傳" #define D_UPTIME "啟動時間" +#define D_USED "used" #define D_USER "使用者名稱" #define D_UTC_TIME "世界協調時間(UTC)" #define D_UV_INDEX "紫外線指數" diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 1549f5aca..0f1bbc082 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -837,7 +837,15 @@ void CmndUpgrade(void) TasmotaGlobal.ota_state_flag = 3; char stemp1[TOPSZ]; Response_P(PSTR("{\"%s\":\"" D_JSON_VERSION " %s " D_JSON_FROM " %s\"}"), XdrvMailbox.command, TasmotaGlobal.version, GetOtaUrl(stemp1, sizeof(stemp1))); - } else { + } +#if defined(ESP32) && defined(USE_WEBCLIENT_HTTPS) + else if (EspSingleOtaPartition() && !EspRunningFactoryPartition() && (1 == XdrvMailbox.data_len) && (2 == XdrvMailbox.payload)) { + TasmotaGlobal.ota_factory = true; + TasmotaGlobal.ota_state_flag = 3; + ResponseCmndChar(PSTR("Safeboot")); + } +#endif // ESP32 and WEBCLIENT_HTTPS + else { Response_P(PSTR("{\"%s\":\"" D_JSON_ONE_OR_GT "\"}"), XdrvMailbox.command, TasmotaGlobal.version); } } @@ -883,7 +891,7 @@ void CmndRestart(void) break; #ifdef ESP32 case 3: - if (EspPrepSwitchToOtherPartition()) { + if (EspPrepSwitchPartition(2)) { // Toggle partition between safeboot and production TasmotaGlobal.restart_flag = 2; ResponseCmndChar(PSTR("Switching")); } diff --git a/tasmota/support_esp.ino b/tasmota/support_esp.ino index 00538b0db..902b6a17d 100644 --- a/tasmota/support_esp.ino +++ b/tasmota/support_esp.ino @@ -269,6 +269,17 @@ void QPCWrite(const void *pSettings, unsigned nSettingsLen) { NvmSave("qpc", "pcreg", pSettings, nSettingsLen); } +bool OtaFactoryRead(void) { + uint32_t pOtaLoader; + NvmLoad("otal", "otal", &pOtaLoader, sizeof(pOtaLoader)); + return pOtaLoader; +} + +void OtaFactoryWrite(bool value) { + uint32_t pOtaLoader = value; + NvmSave("otal", "otal", &pOtaLoader, sizeof(pOtaLoader)); +} + void NvsInfo(void) { nvs_stats_t nvs_stats; nvs_get_stats(NULL, &nvs_stats); @@ -308,6 +319,21 @@ extern "C" { #include "rom/spi_flash.h" #endif +uint32_t EspProgramSize(const char *label) { + const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, label); + if (!part) { + return 0; + } + const esp_partition_pos_t part_pos = { + .offset = part->address, + .size = part->size, + }; + esp_image_metadata_t data; + data.start_addr = part_pos.offset; + esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data); + return data.image_len; +} + bool EspSingleOtaPartition(void) { return (1 == esp_ota_get_app_partition_count()); } @@ -328,15 +354,33 @@ void EspPrepRestartToSafeBoot(void) { } } -bool EspPrepSwitchToOtherPartition(void) { +bool EspPrepSwitchPartition(uint32_t state) { bool valid = EspSingleOtaPartition(); if (valid) { bool running_factory = EspRunningFactoryPartition(); - if (!running_factory) { - EspPrepRestartToSafeBoot(); - } else { - const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr); - esp_ota_set_boot_partition(partition); + switch (state) { + case 0: // Off = safeboot + if (!running_factory) { + EspPrepRestartToSafeBoot(); + } else { + valid = false; + } + break; + case 1: // On = ota0 + if (running_factory) { + const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr); + esp_ota_set_boot_partition(partition); + } else { + valid = false; + } + break; + case 2: // Toggle + if (!running_factory) { + EspPrepRestartToSafeBoot(); + } else { + const esp_partition_t* partition = esp_ota_get_next_update_partition(nullptr); + esp_ota_set_boot_partition(partition); + } } } return valid; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 343481e1d..42f573d54 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1175,6 +1175,9 @@ void Every250mSeconds(void) if (TasmotaGlobal.ota_state_flag && CommandsReady()) { TasmotaGlobal.ota_state_flag--; if (2 == TasmotaGlobal.ota_state_flag) { +#ifdef CONFIG_IDF_TARGET_ESP32C3 + OtaFactoryWrite(false); +#endif RtcSettings.ota_loader = 0; // Try requested image first ota_retry_counter = OTA_ATTEMPTS; SettingsSave(1); // Free flash for OTA update @@ -1245,7 +1248,25 @@ void Every250mSeconds(void) #ifdef ESP32 #ifndef FIRMWARE_MINIMAL +#ifdef USE_WEBCLIENT_HTTPS + if (TasmotaGlobal.ota_factory) { + char *bch = strrchr(full_ota_url, '/'); // Only consider filename after last backslash prevent change of urls having "-" in it + if (bch == nullptr) { bch = full_ota_url; } // No path found so use filename only + char *ech = strchr(bch, '.'); // Find file type in filename (none, .ino.bin, .ino.bin.gz, .bin, .bin.gz or .gz) + if (ech == nullptr) { ech = full_ota_url + strlen(full_ota_url); } // Point to '/0' at end of full_ota_url becoming an empty string + char ota_url_type[strlen(ech) +1]; + strncpy(ota_url_type, ech, sizeof(ota_url_type)); // Either empty, .ino.bin, .ino.bin.gz, .bin, .bin.gz or .gz + + char *pch = strrchr(bch, '-'); // Find last dash (-) and ignore remainder - handles tasmota-DE + if (pch == nullptr) { pch = ech; } // No dash so ignore filetype + *pch = '\0'; // full_ota_url = http://domus1:80/api/arduino/tasmota + snprintf_P(full_ota_url, sizeof(full_ota_url), PSTR("%s-safeboot%s"), full_ota_url, ota_url_type); // Safeboot filename must be filename-safeboot + } else +#endif // USE_WEBCLIENT_HTTPS if (EspSingleOtaPartition()) { +#ifdef CONFIG_IDF_TARGET_ESP32C3 + OtaFactoryWrite(true); +#endif RtcSettings.ota_loader = 1; // Try safeboot image next SettingsSaveAll(); AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING)); @@ -1265,6 +1286,7 @@ void Every250mSeconds(void) ota_result = -999; } else { httpUpdateLight.rebootOnUpdate(false); + httpUpdateLight.setFactory(TasmotaGlobal.ota_factory); ota_result = (HTTP_UPDATE_FAILED != httpUpdateLight.update(OTAclient, version)); } #else // standard OTA over HTTP @@ -1413,6 +1435,12 @@ void Every250mSeconds(void) case 3: // Every x.75 second if (!TasmotaGlobal.global_state.network_down) { #ifdef FIRMWARE_MINIMAL +#ifdef CONFIG_IDF_TARGET_ESP32C3 + if (OtaFactoryRead()) { + OtaFactoryWrite(false); + TasmotaGlobal.ota_state_flag = 3; + } +#endif if (1 == RtcSettings.ota_loader) { RtcSettings.ota_loader = 0; TasmotaGlobal.ota_state_flag = 3; diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index 44d39780f..dc815a21b 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -186,6 +186,7 @@ struct TasmotaGlobal_t { bool i2c_enabled; // I2C configured #ifdef ESP32 bool i2c_enabled_2; // I2C configured, second controller on ESP32, Wire1 + bool ota_factory; // Select safeboot binary #endif bool ntp_force_sync; // Force NTP sync bool skip_light_fade; // Temporarily skip light fading diff --git a/tasmota/tasmota_globals.h b/tasmota/tasmota_globals.h index ddeab70a3..284e7f314 100644 --- a/tasmota/tasmota_globals.h +++ b/tasmota/tasmota_globals.h @@ -104,6 +104,12 @@ String EthernetMacAddress(void); #if CONFIG_IDF_TARGET_ESP32 +#ifdef CORE32SOLO1 +#ifdef USE_ETHERNET +#undef USE_ETHERNET // ESP32-Solo1 does not support ethernet +#endif +#endif // CORE32SOLO1 + #else // Disable features not present in other ESP32 like ESP32C3, ESP32S2, ESP32S3 etc. #ifdef USE_ETHERNET #undef USE_ETHERNET // All non-ESP32 do not support ethernet diff --git a/tasmota/tasmota_version.h b/tasmota/tasmota_version.h index 72db321c3..f4b32b051 100644 --- a/tasmota/tasmota_version.h +++ b/tasmota/tasmota_version.h @@ -20,6 +20,6 @@ #ifndef _TASMOTA_VERSION_H_ #define _TASMOTA_VERSION_H_ -const uint32_t VERSION = 0x0B010002; // 11.1.0.2 +const uint32_t VERSION = 0x0B010003; // 11.1.0.3 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index 518b48ef3..55e98e862 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -353,18 +353,22 @@ const char HTTP_FORM_UPG[] PROGMEM = "


" "
 " D_UPGRADE_BY_FILE_UPLOAD " "; const char HTTP_FORM_RST_UPG[] PROGMEM = - "
" + "" "

" - "
" + "
" "
" "" ""; // upload via factory partition const char HTTP_FORM_RST_UPG_FCT[] PROGMEM = - "
" + "" "

" - "
" + "
" "
" "" "" @@ -436,6 +440,7 @@ ESP8266WebServer *Webserver; struct WEB { String chunk_buffer = ""; // Could be max 2 * CHUNKED_BUFFER_SIZE + uint32_t upload_size = 0; uint16_t upload_error = 0; uint8_t state = HTTP_OFF; uint8_t upload_file_type; @@ -556,8 +561,10 @@ const WebServerDispatch_t WebServerDispatch[] PROGMEM = { { "dl", HTTP_ANY, HandleBackupConfiguration }, { "rs", HTTP_ANY, HandleRestoreConfiguration }, { "rt", HTTP_ANY, HandleResetConfiguration }, - { "in", HTTP_ANY, HandleInformation }, #endif // Not FIRMWARE_MINIMAL +#ifndef FIRMWARE_MINIMAL_ONLY + { "in", HTTP_ANY, HandleInformation }, +#endif // Not FIRMWARE_MINIMAL_ONLY }; void WebServer_on(const char * prefix, void (*func)(void), uint8_t method = HTTP_ANY) { @@ -995,12 +1002,16 @@ void WSContentStop(void) { /*********************************************************************************************/ -void WebRestart(uint32_t type) -{ +void WebRestart(uint32_t type) { // type 0 = restart // type 1 = restart after config change // type 2 = Checking WiFi Connection - no restart, only refresh page. // type 3 = restart after WiFi Connection Test Successful + // type 4 = type 0 without auto switch to production + bool prep_switch_partition = false; + if (0 == type) { prep_switch_partition = true; } + if (4 == type) { type = 0; } + bool reset_only = (HTTP_MANAGER_RESET_ONLY == Web.state); WSContentStart_P((type) ? PSTR(D_SAVE_CONFIGURATION) : PSTR(D_RESTART), !reset_only); @@ -1033,7 +1044,7 @@ void WebRestart(uint32_t type) #endif } } - if (type<2) { + if (type < 2) { WSContentSend_P(HTTP_MSG_RSTRT); if (HTTP_MANAGER == Web.state || reset_only) { Web.state = HTTP_ADMIN; @@ -1046,6 +1057,9 @@ void WebRestart(uint32_t type) if (!(2 == type)) { AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART)); ShowWebSource(SRC_WEBGUI); +#ifdef ESP32 + if (prep_switch_partition) { EspPrepSwitchPartition(1); } // Switch to production partition if on safeboot +#endif // ESP32 TasmotaGlobal.restart_flag = 2; } } @@ -1286,7 +1300,14 @@ void HandleRoot(void) if (HTTP_ADMIN == Web.state) { #ifdef FIRMWARE_MINIMAL +#ifdef ESP32 +#ifndef FIRMWARE_MINIMAL_ONLY + WSContentSpaceButton(BUTTON_INFORMATION); + WSContentButton(BUTTON_FIRMWARE_UPGRADE); +#endif // FIRMWARE_MINIMAL_ONLY +#else // ESP8266 WSContentSpaceButton(BUTTON_FIRMWARE_UPGRADE); +#endif // ESP32 WSContentButton(BUTTON_CONSOLE); #else WSContentSpaceButton(BUTTON_CONFIGURATION); @@ -1831,25 +1852,6 @@ void ModuleSaveSettings(void) { /*-------------------------------------------------------------------------------------------*/ -const char kUnescapeCode[] = "&><\"\'\\"; -const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; - -String HtmlEscape(const String unescaped) { - char escaped[10]; - size_t ulen = unescaped.length(); - String result = ""; - for (size_t i = 0; i < ulen; i++) { - char c = unescaped[i]; - char *p = strchr(kUnescapeCode, c); - if (p != nullptr) { - result += GetTextIndexed(escaped, sizeof(escaped), p - kUnescapeCode, kEscapeCode); - } else { - result += c; - } - } - return result; -} - void HandleWifiConfiguration(void) { char tmp[TOPSZ]; // Max length is currently 150 @@ -2325,8 +2327,31 @@ void HandleRestoreConfiguration(void) Web.upload_file_type = UPL_SETTINGS; } +#endif // Not FIRMWARE_MINIMAL + /*-------------------------------------------------------------------------------------------*/ +#ifndef FIRMWARE_MINIMAL_ONLY + +const char kUnescapeCode[] = "&><\"\'\\"; +const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; + +String HtmlEscape(const String unescaped) { + char escaped[10]; + size_t ulen = unescaped.length(); + String result = ""; + for (size_t i = 0; i < ulen; i++) { + char c = unescaped[i]; + char *p = strchr(kUnescapeCode, c); + if (p != nullptr) { + result += GetTextIndexed(escaped, sizeof(escaped), p - kUnescapeCode, kEscapeCode); + } else { + result += c; + } + } + return result; +} + void HandleInformation(void) { if (!HttpCheckPriviledgedAccess()) { return; } @@ -2453,18 +2478,52 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1}2 ")); // Empty line WSContentSend_P(PSTR("}1" D_ESP_CHIP_ID "}2%d (%s)"), ESP_getChipId(), GetDeviceHardwareRevision().c_str()); WSContentSend_P(PSTR("}1" D_FLASH_CHIP_ID "}20x%06X"), ESP_getFlashChipId()); - WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%d kB"), ESP_getFlashChipRealSize() / 1024); - WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%d kB"), ESP.getFlashChipSize() / 1024); - WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%d kB"), ESP_getSketchSize() / 1024); - WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%d kB"), ESP_getFreeSketchSpace() / 1024); + WSContentSend_P(PSTR("}1" D_FLASH_CHIP_SIZE "}2%d KB"), ESP_getFlashChipRealSize() / 1024); + WSContentSend_P(PSTR("}1" D_PROGRAM_FLASH_SIZE "}2%d KB"), ESP.getFlashChipSize() / 1024); + WSContentSend_P(PSTR("}1" D_PROGRAM_SIZE "}2%d KB"), ESP_getSketchSize() / 1024); + WSContentSend_P(PSTR("}1" D_FREE_PROGRAM_SPACE "}2%d KB"), ESP_getFreeSketchSpace() / 1024); #ifdef ESP32 - WSContentSend_PD(PSTR("}1" D_FREE_MEMORY "}2%1_f kB (" D_FRAGMENTATION " %d%%)"), &freemem, ESP_getHeapFragmentation()); + WSContentSend_PD(PSTR("}1" D_FREE_MEMORY "}2%1_f KB (" D_FRAGMENTATION " %d%%)"), &freemem, ESP_getHeapFragmentation()); if (UsePSRAM()) { - WSContentSend_P(PSTR("}1" D_PSR_MAX_MEMORY "}2%d kB"), ESP.getPsramSize() / 1024); - WSContentSend_P(PSTR("}1" D_PSR_FREE_MEMORY "}2%d kB"), ESP.getFreePsram() / 1024); + WSContentSend_P(PSTR("}1" D_PSR_MAX_MEMORY "}2%d KB"), ESP.getPsramSize() / 1024); + WSContentSend_P(PSTR("}1" D_PSR_FREE_MEMORY "}2%d KB"), ESP.getFreePsram() / 1024); } + WSContentSend_P(PSTR("}1}2 ")); // Empty line + uint32_t cur_part = ESP_PARTITION_SUBTYPE_APP_FACTORY; // 0 + const esp_partition_t *running_ota = esp_ota_get_running_partition(); + if (running_ota) { cur_part = running_ota->subtype; } // 16 - 32 + esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL); + for (; it != NULL; it = esp_partition_next(it)) { + const esp_partition_t *part = esp_partition_get(it); + +// AddLog(LOG_LEVEL_DEBUG, PSTR("PRT: Type %d, Subtype %d, Name %s, Size %d"), part->type, part->subtype, part->label, part->size); + + uint32_t part_size = part->size / 1024; + if (ESP_PARTITION_TYPE_APP == part->type) { + uint32_t prog_size = 0; // No active ota partition + if (part->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY) { + prog_size = EspProgramSize(part->label); // safeboot partition (slow response) + } + else if ((part->subtype >= ESP_PARTITION_SUBTYPE_APP_OTA_MIN) && (part->subtype <= ESP_PARTITION_SUBTYPE_APP_OTA_MAX)) { + if (cur_part == part->subtype) { + prog_size = ESP_getSketchSize(); // Active running ota partition (fast response) + } + else if (cur_part == ESP_PARTITION_SUBTYPE_APP_FACTORY) { + prog_size = EspProgramSize(part->label); // One app partition when safeboot partitions (slow response) + } + } + char running[2] = { 0 }; + if (part->subtype == cur_part) { running[0] = '*'; } + uint32_t part_used = ((prog_size / 1024) * 100) / part_size; + WSContentSend_PD(PSTR("}1" D_PARTITION " %s%s}2%d KB (" D_USED " %d%%)"), part->label, running, part_size, part_used); + } + if ((ESP_PARTITION_TYPE_DATA == part->type) && (ESP_PARTITION_SUBTYPE_DATA_SPIFFS == part->subtype)) { + WSContentSend_PD(PSTR("}1" D_PARTITION " fs}2%d KB"), part_size); + } + } + esp_partition_iterator_release(it); #else // ESP32 - WSContentSend_PD(PSTR("}1" D_FREE_MEMORY "}2%1_f kB"), &freemem); + WSContentSend_PD(PSTR("}1" D_FREE_MEMORY "}2%1_f KB"), &freemem); #endif // ESP32 WSContentSend_P(PSTR("")); @@ -2477,7 +2536,7 @@ void HandleInformation(void) WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); } -#endif // Not FIRMWARE_MINIMAL +#endif // Not FIRMWARE_MINIMAL_ONLY /*-------------------------------------------------------------------------------------------*/ @@ -2775,11 +2834,15 @@ void HandleUploadLoop(void) { return; } if (0xE9 == upload.buf[0]) { - uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4); #ifdef ESP8266 + uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4); if (bin_flash_size > ESP.getFlashChipRealSize()) { #else - if (bin_flash_size > ESP.getFlashChipSize()) { // TODO revisit this test + char tmp[16]; + WebGetArg("fsz", tmp, sizeof(tmp)); // filesize + uint32_t upload_size = (!strlen(tmp)) ? 0 : atoi(tmp); + AddLog(LOG_LEVEL_DEBUG, D_LOG_UPLOAD "freespace=%i filesize=%i", ESP.getFreeSketchSpace(), upload_size); + if (upload_size > ESP.getFreeSketchSpace()) { // TODO revisit this test #endif Web.upload_error = 4; // Program flash size is larger than real flash size return; @@ -2826,7 +2889,7 @@ void HandleUploadLoop(void) { return; } if (upload.totalSize && !(upload.totalSize % 102400)) { - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Progress %d kB"), upload.totalSize / 1024); + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPLOAD "Progress %d KB"), upload.totalSize / 1024); } } @@ -2981,7 +3044,7 @@ void HandleSwitchBootPartition(void) AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTART)); EspRestart(); } else { - WebRestart(0); + WebRestart(4); } } else { if (api_mode) { diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino index 5d5f71431..44c3325c7 100644 --- a/tasmota/xdrv_12_discovery.ino +++ b/tasmota/xdrv_12_discovery.ino @@ -209,6 +209,18 @@ void TasDiscoverMessage(void) { } ResponseAppend_P(PSTR("]," // Shutter Options (end) + "\"sht\":[")); // Shutter Tilt (start) + for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { +#ifdef USE_SHUTTER + ResponseAppend_P(PSTR("%s[%d,%d,%d]"), (i > 0 ? "," : ""), + Settings->shutter_tilt_config[0][i], + Settings->shutter_tilt_config[1][i], + Settings->shutter_tilt_config[2][i]); +#else + ResponseAppend_P(PSTR("%s[0,0,0]"), (i > 0 ? "," : "")); +#endif // USE_SHUTTER + } + ResponseAppend_P(PSTR("]," // Shutter Tilt (end) "\"ver\":1}")); // Discovery version } diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino index 00bbf6734..ffc099e5d 100644 --- a/tasmota/xdrv_12_home_assistant.ino +++ b/tasmota/xdrv_12_home_assistant.ino @@ -376,6 +376,18 @@ void HassDiscoverMessage(void) { } ResponseAppend_P(PSTR("]," // Shutter Options (end) + "\"sht\":[")); // Shutter Tilt (start) + for (uint32_t i = 0; i < MAX_SHUTTERS; i++) { +#ifdef USE_SHUTTER + ResponseAppend_P(PSTR("%s[%d,%d,%d]"), (i > 0 ? "," : ""), + Settings->shutter_tilt_config[0][i], + Settings->shutter_tilt_config[1][i], + Settings->shutter_tilt_config[2][i]); +#else + ResponseAppend_P(PSTR("%s[0,0,0]"), (i > 0 ? "," : "")); +#endif // USE_SHUTTER + } + ResponseAppend_P(PSTR("]," // Shutter Tilt (end) "\"ver\":1}")); // Discovery version } diff --git a/tasmota/xdrv_23_zigbee_5_converters.ino b/tasmota/xdrv_23_zigbee_5_converters.ino index 805297380..4d57c1906 100644 --- a/tasmota/xdrv_23_zigbee_5_converters.ino +++ b/tasmota/xdrv_23_zigbee_5_converters.ino @@ -1489,8 +1489,10 @@ void ZCLFrame::parseReadAttributes(Z_attribute_list& attr_list) { attr_list.addAttributePMEM(PSTR("Read")).setStrRaw(attr_numbers.toString().c_str()); attr_list.addAttributePMEM(PSTR("ReadNames")).setStrRaw(attr_names.toString(true).c_str()); - // call auto-responder - autoResponder(read_attr_ids, len/2); + // call auto-responder only if src address if different from ourselves and it was a broadcast + if (_srcaddr != localShortAddr || !_wasbroadcast) { + autoResponder(read_attr_ids, len/2); + } } // ZCL_CONFIGURE_REPORTING_RESPONSE diff --git a/tasmota/xdrv_23_zigbee_A_impl.ino b/tasmota/xdrv_23_zigbee_A_impl.ino index 8abe92121..30930f76d 100644 --- a/tasmota/xdrv_23_zigbee_A_impl.ino +++ b/tasmota/xdrv_23_zigbee_A_impl.ino @@ -201,8 +201,8 @@ void zigbeeZCLSendCmd(class ZCLMessage &zcl) { zcl.transacSet = true; } - AddLog(LOG_LEVEL_DEBUG, PSTR("ZigbeeZCLSend device: 0x%04X, group: 0x%04X, endpoint:%d, cluster:0x%04X, cmd:0x%02X, send:\"%_B\""), - zcl.shortaddr, zcl.groupaddr, zcl.endpoint, zcl.cluster, zcl.cmd, &zcl.buf); + AddLog(LOG_LEVEL_DEBUG, PSTR("ZigbeeZCLSend %s: 0x%04X, endpoint:%d, cluster:0x%04X, cmd:0x%02X, send:\"%_B\""), + zcl.validShortaddr() ? "device":"group", zcl.validShortaddr() ? zcl.shortaddr : zcl.groupaddr, zcl.endpoint, zcl.cluster, zcl.cmd, &zcl.buf); ZigbeeZCLSend_Raw(zcl); diff --git a/tasmota/xdrv_27_shutter.ino b/tasmota/xdrv_27_shutter.ino index d4cbd0191..cb8a8a9be 100644 --- a/tasmota/xdrv_27_shutter.ino +++ b/tasmota/xdrv_27_shutter.ino @@ -1,7 +1,7 @@ /* xdrv_27_Shutter[i].ino - Shutter/Blind support for Tasmota - Copyright (C) 2022 Stefan Bode + Copyright (C) 2022 Stefan Bode This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -126,6 +126,7 @@ struct SHUTTERGLOBAL { #define SHT_DIV_ROUND(__A, __B) (((__A) + (__B)/2) / (__B)) + void ShutterLogPos(uint32_t i) { char stemp2[10]; @@ -175,7 +176,7 @@ void ShutterRtc50mS(void) if (Shutter[i].accelerator) { //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Accelerator i=%d -> %d"),i, Shutter[i].accelerator); ShutterUpdateVelocity(i); - digitalWrite(Pin(GPIO_PWM1, i), LOW); + digitalWrite(Pin(GPIO_PWM1, i), LOW); #ifdef ESP8266 // Convert frequency into clock cycles uint32_t cc = microsecondsToClockCycles(1000000UL) / Shutter[i].pwm_velocity; @@ -1242,8 +1243,8 @@ void CmndShutterPosition(void) ShutterReportPosition(true, index); } XdrvMailbox.index = index +1; // Fix random index for ShutterClose - if (XdrvMailbox.command) - ResponseCmndIdxNumber((Settings->shutter_options[index] & 1) ? 100 - target_pos_percent : target_pos_percent); + strcpy( XdrvMailbox.command , D_CMND_SHUTTER_POSITION); + ResponseCmndIdxNumber((Settings->shutter_options[index] & 1) ? 100 - target_pos_percent : target_pos_percent); } else { ShutterReportPosition(true, MAX_SHUTTERS); if (XdrvMailbox.command) @@ -1632,7 +1633,6 @@ void CmndShutterSetTilt(void) } XdrvMailbox.data[0] = '\0'; AddLog(LOG_LEVEL_INFO, PSTR("SHT: TiltTarget %d, payload %d"), Shutter[XdrvMailbox.index -1].tilt_target_pos,XdrvMailbox.payload); - ResponseCmndNumber(Shutter[XdrvMailbox.index -1].tilt_target_pos); Shutter[XdrvMailbox.index -1].tiltmoving = 1; CmndShutterPosition(); } @@ -1649,27 +1649,26 @@ void CmndShutterTiltConfig(void) for (char *str = strtok_r(data_copy, " ", &str_ptr); str && i < 6; str = strtok_r(nullptr, " ", &str_ptr), i++) { Shutter[XdrvMailbox.index -1].tilt_config[i] = Settings->shutter_tilt_config[i][XdrvMailbox.index -1] = atoi(str); } + // avoid negative runtime + Settings->shutter_tilt_config[2][XdrvMailbox.index -1] = Shutter[XdrvMailbox.index -1].tilt_config[2] = Shutter[XdrvMailbox.index -1].tilt_config[2] >= 0 ? Shutter[XdrvMailbox.index -1].tilt_config[2] : 127; ShutterInit(); - ResponseCmndIdxChar(XdrvMailbox.data); - } else { - char setting_chr[30] = "0"; - snprintf_P(setting_chr, sizeof(setting_chr), PSTR("SHT:%d %d %d %d %d %d"), XdrvMailbox.index -1,Shutter[XdrvMailbox.index -1].tilt_config[0], Shutter[XdrvMailbox.index -1].tilt_config[1],Shutter[XdrvMailbox.index -1].tilt_config[2],Shutter[XdrvMailbox.index -1].tilt_config[3],Shutter[XdrvMailbox.index -1].tilt_config[4]); - ResponseCmndIdxChar(setting_chr); } - AddLog(LOG_LEVEL_INFO, PSTR("SHT: TiltConfig %d, min: %d, max %d, runtime %d, close_pos: %d, open_pos: %d"), XdrvMailbox.index ,Shutter[XdrvMailbox.index -1].tilt_config[0], Shutter[XdrvMailbox.index -1].tilt_config[1],Shutter[XdrvMailbox.index -1].tilt_config[2],Shutter[XdrvMailbox.index -1].tilt_config[3],Shutter[XdrvMailbox.index -1].tilt_config[4]); + char setting_chr[30] = "0"; + snprintf_P(setting_chr, sizeof(setting_chr), PSTR("%d %d %d %d %d"), XdrvMailbox.index -1,Shutter[XdrvMailbox.index -1].tilt_config[0], Shutter[XdrvMailbox.index -1].tilt_config[1],Shutter[XdrvMailbox.index -1].tilt_config[2],Shutter[XdrvMailbox.index -1].tilt_config[3],Shutter[XdrvMailbox.index -1].tilt_config[4]); + ResponseCmndIdxChar(setting_chr); + AddLog(LOG_LEVEL_INFO, PSTR("SHT: TiltConfig %d, min: %d, max %d, runtime %d, close_pos: %d, open_pos: %d"), XdrvMailbox.index ,Shutter[XdrvMailbox.index -1].tilt_config[0], Shutter[XdrvMailbox.index -1].tilt_config[1],Shutter[XdrvMailbox.index -1].tilt_config[2],Shutter[XdrvMailbox.index -1].tilt_config[3],Shutter[XdrvMailbox.index -1].tilt_config[4]); } } void CmndShutterTiltIncDec(void) { //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Change in: payload %s (%d), payload %d, idx %d, src %d"), XdrvMailbox.data , XdrvMailbox.data_len, XdrvMailbox.payload , XdrvMailbox.index, TasmotaGlobal.last_source ); - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present)) { - if (XdrvMailbox.data_len > 0) { - XdrvMailbox.payload = Shutter[XdrvMailbox.index -1].tilt_target_pos+XdrvMailbox.payload; - CmndShutterSetTilt(); - } + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= TasmotaGlobal.shutters_present) && XdrvMailbox.data_len > 0) { + XdrvMailbox.payload = Shutter[XdrvMailbox.index -1].tilt_target_pos+XdrvMailbox.payload; + CmndShutterSetTilt(); + } else { + ResponseCmndIdxNumber(XdrvMailbox.payload); } - ResponseCmndNumber(Shutter[XdrvMailbox.index -1].tilt_target_pos); } /*********************************************************************************************\ diff --git a/tasmota/xdrv_52_3_berry_flash.ino b/tasmota/xdrv_52_3_berry_flash.ino index 39e0e44b1..c1df40a33 100644 --- a/tasmota/xdrv_52_3_berry_flash.ino +++ b/tasmota/xdrv_52_3_berry_flash.ino @@ -45,13 +45,13 @@ size_t FlashWriteSubSector(uint32_t address_start, const uint8_t *data, size_t s memcpy(buffer, data + current_offset, SPI_FLASH_SEC_SIZE); } else { ret = spi_flash_read(page_addr, buffer, SPI_FLASH_SEC_SIZE); - if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not read flash %p (0x%X)", page_addr, SPI_FLASH_SEC_SIZE); return 0; } + if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not read flash %p (0x%X) ret=%i", page_addr, SPI_FLASH_SEC_SIZE, ret); return 0; } memcpy(buffer + addr_in_page, data + current_offset, size_in_page); } ret = spi_flash_erase_sector(page_addr / SPI_FLASH_SEC_SIZE); - if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not erase flash sector 0x%X", page_addr / SPI_FLASH_SEC_SIZE); return 0; } + if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not erase flash sector 0x%X ret=%i", page_addr / SPI_FLASH_SEC_SIZE, ret); return 0; } spi_flash_write(page_addr, buffer, SPI_FLASH_SEC_SIZE); - if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not write flash %p (0x%X)", page_addr, SPI_FLASH_SEC_SIZE); return 0; } + if (ret) { AddLog(LOG_LEVEL_INFO, "BRY: could not write flash %p (0x%X) ret=%i", page_addr, SPI_FLASH_SEC_SIZE, ret); return 0; } addr += size_in_page; current_offset += size_in_page; @@ -63,9 +63,9 @@ size_t FlashWriteSubSector(uint32_t address_start, const uint8_t *data, size_t s /*********************************************************************************************\ * Native functions mapped to Berry functions - * + * * import flash - * + * \*********************************************************************************************/ extern "C" { // Berry: `flash.read(address:int[, length:int]) -> bytes()` @@ -74,7 +74,7 @@ extern "C" { int32_t p_flash_read(struct bvm *vm); int32_t p_flash_read(struct bvm *vm) { int32_t argc = be_top(vm); // Get the number of arguments - if (argc >= 1 && be_isint(vm, 1) && + if (argc >= 1 && be_isint(vm, 1) && (argc < 2 || be_isint(vm, 2)) ) { // optional second argument must be int uint32_t address = be_toint(vm, 1); uint32_t length = 0x1000; @@ -102,13 +102,24 @@ extern "C" { if (argc >= 2 && be_isint(vm, 1) && be_isinstance(vm, 2)) { be_getglobal(vm, "bytes"); /* get the bytes class */ /* TODO eventually replace with be_getbuiltin */ if (be_isderived(vm, 2)) { + bool no_erase = false; + if (argc >= 3 && be_isbool(vm, 3)) { + no_erase = be_tobool(vm, 3); + } uint32_t address = be_toint(vm, 1); size_t length = 0; const void * bytes = be_tobytes(vm, 2, &length); if (bytes && length > 0) { - size_t ret = FlashWriteSubSector(address, (const uint8_t*)bytes, length); - if (ret == 0) { - be_raise(vm, "internal_error", "Error calling spi_flash_write()"); + if (no_erase) { + esp_err_t ret = spi_flash_write(address, (const uint8_t*)bytes, length); + if (ret) { + be_raisef(vm, "internal_error", "Error calling spi_flash_write() ret=%i", ret); + } + } else { + size_t ret = FlashWriteSubSector(address, (const uint8_t*)bytes, length); + if (ret == 0) { + be_raise(vm, "internal_error", "Error calling spi_flash_write()"); + } } be_return_nil(vm); // success @@ -146,6 +157,9 @@ extern "C" { esp_partition_erase_range(otadata_partition, 0, SPI_FLASH_SEC_SIZE * 2); } if (force_ota) { +#ifdef CONFIG_IDF_TARGET_ESP32C3 + OtaFactoryWrite(true); +#endif RtcSettings.ota_loader = 1; // force OTA at next reboot } } diff --git a/tasmota/xdrv_86_esp32_sonoff_spm.ino b/tasmota/xdrv_86_esp32_sonoff_spm.ino index c2ef0ef83..55b91e1c1 100644 --- a/tasmota/xdrv_86_esp32_sonoff_spm.ino +++ b/tasmota/xdrv_86_esp32_sonoff_spm.ino @@ -32,7 +32,7 @@ * Each SPM-4Relay has 4 bistable relays with their own CSE7761 energy monitoring device handled by an ARM processor. * Green led is controlled by ARM processor indicating SD-Card access. * ESP32 is used as interface between eWelink and ARM processor in SPM-Main unit communicating over proprietary serial protocol. - * Power on sequence for two SPM-4Relay modules is 00-00-15-10-(0F)-(13)-(13)-(19)-0C-09-04-09-04-0B-0B + * Power on sequence for two SPM-4Relay modules is 00-00-15-10-(0F)-(13)-(13)-(19)-0C-09-04-[25]-09-04-[25]-0B-0B * Up to 180 days of daily energy are stored on the SD-Card. Previous data is lost. * Tasmota support is based on Sonoff SPM v1.0.0 ARM firmware. * Energy history cannot be guaranteed using either SD-Card or internal flash. As a solution Tasmota stores the total energy and yesterday energy just after midnight. @@ -122,7 +122,7 @@ #define XDRV_86 86 #define SSPM_MAX_MODULES 8 // Currently supports up to 8 SPM-4RELAY units for a total of 32 relays restricted by 32-bit power_t size -#define SSPM_SERIAL_BUFFER_SIZE 512 // Needs to accomodate Energy total history for 180 days (408 bytes) +#define SSPM_SERIAL_BUFFER_SIZE 548 // Needs to accomodate firmware upload data blocks (546 bytes) //#define SSPM_SIMULATE 2 // Simulate additional 4Relay modules based on first detected 4Relay module (debugging purposes only!!) @@ -137,12 +137,17 @@ #define SSPM_FUNC_SET_TIME 12 // 0x0C #define SSPM_FUNC_IAMHERE 13 // 0x0D #define SSPM_FUNC_INIT_SCAN 16 // 0x10 +#define SSPM_FUNC_UPLOAD_HEADER 20 // 0x14 - Upload header #define SSPM_FUNC_UNITS 21 // 0x15 #define SSPM_FUNC_GET_ENERGY_TOTAL 22 // 0x16 #define SSPM_FUNC_GET_ENERGY 24 // 0x18 #define SSPM_FUNC_GET_LOG 26 // 0x1A #define SSPM_FUNC_ENERGY_PERIOD 27 // 0x1B #define SSPM_FUNC_RESET 28 // 0x1C - Remove device from eWelink and factory reset +#define SSPM_FUNC_ARM_RESTART 30 // 0x1E - Restart ARM +#define SSPM_FUNC_UPLOAD_DATA 31 // 0x1F - Upload incremental data blocks of max 512 bytes to ARM +#define SSPM_FUNC_UPLOAD_DONE 33 // 0x21 - Finish upload +#define SSPM_FUNC_GET_NEW1 37 // 0x25 // From ARM to ESP #define SSPM_FUNC_ENERGY_RESULT 6 // 0x06 @@ -152,20 +157,27 @@ #define SSPM_FUNC_SCAN_DONE 25 // 0x19 // Unknown -#define SSPM_FUNC_01 -#define SSPM_FUNC_02 -#define SSPM_FUNC_05 -#define SSPM_FUNC_14 -#define SSPM_FUNC_17 -#define SSPM_FUNC_18 -#define SSPM_FUNC_20 -#define SSPM_FUNC_23 +#define SSPM_FUNC_01 1 // 0x01 +#define SSPM_FUNC_02 2 // 0x02 +#define SSPM_FUNC_05 5 // 0x05 +#define SSPM_FUNC_14 14 // 0x0E +#define SSPM_FUNC_17 17 // 0x11 +#define SSPM_FUNC_18 18 // 0x12 +#define SSPM_FUNC_23 23 // 0x17 +#define SSPM_FUNC_29 29 // 0x1D +#define SSPM_FUNC_32 32 // 0x20 +#define SSPM_FUNC_34 34 // 0x22 +#define SSPM_FUNC_35 35 // 0x23 +#define SSPM_FUNC_36 36 // 0x24 #define SSPM_GPIO_ARM_RESET 15 #define SSPM_GPIO_LED_ERROR 33 #define SSPM_MODULE_NAME_SIZE 12 +#define SSPM_MAIN_V1_0_0 0x00010000 +#define SSPM_MAIN_V1_2_0 0x00010200 + /*********************************************************************************************/ #define SSPM_TOTAL_MODULES 32 // Max number of SPM-4RELAY units for a total of 128 relays @@ -176,9 +188,10 @@ enum SspmMachineStates { SPM_NONE, // Do nothing SPM_WAIT, // Wait 100ms SPM_RESET, // Toggle ARM reset pin SPM_POLL_ARM, // Wait for first acknowledge from ARM after reset - SPM_POLL_ARM_SPI, // Wait for first acknowledge from ARM SPI after reset - SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset - SPM_POLL_ARM_3, // Wait for second acknowledge from ARM after reset +// Removed to accomodate v1.2.0 too +// SPM_POLL_ARM_SPI, // Wait for first acknowledge from ARM SPI after reset +// SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset +// SPM_POLL_ARM_3, // Wait for second acknowledge from ARM after reset SPM_SEND_FUNC_UNITS, // Get number of units SPM_START_SCAN, // Start module scan sequence SPM_WAIT_FOR_SCAN, // Wait for scan sequence to complete @@ -250,6 +263,7 @@ typedef struct { float overload_max_current; uint32_t timeout; + uint32_t main_version; power_t old_power; power_t power_on_state; uint16_t last_totals; @@ -785,6 +799,21 @@ void SSPMSendInitScan(void) { AddLog(LOG_LEVEL_DEBUG, PSTR("SPM: Start relay scan...")); } +void SSPMSendUploadHeader(void) { + /* + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 14 00 0b 09 09 00 1b e5 a4 c7 00 02 88 74 00 6d df + Marker | | |Cm|Size | |Checksum |UploadSize |Ix|Chksm| + */ + SSPMInitSend(); + SspmBuffer[16] = SSPM_FUNC_UPLOAD_HEADER; // 0x14 + SspmBuffer[18] = 0x0B; + + + SspmBuffer[30] = 0; + SSPMSend(33); +} + void SSPMSendGetEnergyTotal(uint32_t relay) { /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @@ -894,6 +923,66 @@ void SSPMSendGetEnergyPeriod(uint32_t relay) { } +void SSPMSendArmRestart(void) { + /* + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + aa 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 1e 00 01 00 01 fe 05 + Marker | | |Cm|Size | |Ix|Chksm| + */ + SSPMInitSend(); + SspmBuffer[16] = SSPM_FUNC_ARM_RESTART; // 0x1E + SspmBuffer[18] = 1; + Sspm->command_sequence++; + SspmBuffer[20] = Sspm->command_sequence; + SSPMSend(23); +} + +void SSPMSendUpload(void) { + /* + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 539 540 541 542 543 544 545 + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 1f 02 0c 00 00 00 00 00 00 02 00 a2 99 c3 22 00 00 01 20 cd 95 01 08 ... 04 48 af f3 01 xx yy + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 1f 02 0c 00 00 02 00 00 00 02 00 27 f7 24 87 00 80 01 23 23 70 10 bd ... 21 fa 04 f3 02 xx yy + ... + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 1f 02 0c 00 02 86 00 00 00 02 00 f8 f5 25 6d f1 61 00 08 02 01 ff 00 ... 44 xx yy + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 1f 00 80 00 02 88 00 00 00 00 74 95 4e 01 c1 c5 e5 02 08 c5 e5 02 08 ... 45 xx yy + Marker | | |Cm|Size |Address |UploadSize |Checksum |512 data bytes |Ix |Chksm | + */ + SSPMInitSend(); + SspmBuffer[16] = SSPM_FUNC_UPLOAD_DATA; // 0x1F + + + + Sspm->command_sequence++; + SspmBuffer[543] = Sspm->command_sequence; + SSPMSend(546); +} + +void SSPMSendUploadDone(void) { + /* + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 46 32 da + Marker | | |Cm|Size |Ix|Chksm| + */ + SSPMSendCmnd(SSPM_FUNC_UPLOAD_DONE); // 0x21 +} + +void SSPMSendGetNew1(uint32_t module) { + /* + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + aa 55 01 6b 7e 32 37 39 37 34 13 4b 35 36 37 00 25 00 00 08 c0 0a + Marker |Module id |Ac|Cm|Size |Ix|Chksm| + */ + if (module >= Sspm->module_max) { return; } + + SSPMInitSend(); + memcpy(SspmBuffer +3, Sspm->module[SSPMGetMappedModuleId(module)], SSPM_MODULE_NAME_SIZE); + SspmBuffer[16] = SSPM_FUNC_GET_NEW1; // 0x25 + Sspm->command_sequence++; + SspmBuffer[19] = Sspm->command_sequence; + + SSPMSend(22); +} + /*********************************************************************************************/ void SSPMAddModule(void) { @@ -1051,11 +1140,15 @@ void SSPMHandleReceivedData(void) { MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR("SSPMOverload")); Sspm->overload_relay = 255; } else { - Sspm->module_selected--; - if (Sspm->module_selected > 0) { - SSPMSendGetModuleState(Sspm->module_selected -1); + if (Sspm->main_version > SSPM_MAIN_V1_0_0) { + SSPMSendGetNew1(Sspm->module_selected -1); } else { - SSPMSendGetScheme(Sspm->module_selected); + Sspm->module_selected--; + if (Sspm->module_selected > 0) { + SSPMSendGetModuleState(Sspm->module_selected -1); + } else { + SSPMSendGetScheme(Sspm->module_selected); + } } } break; @@ -1101,9 +1194,14 @@ void SSPMHandleReceivedData(void) { case SSPM_FUNC_SET_TIME: /* 0x0C AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 0c 00 01 00 04 3e 62 + v1.2.0: adds response from each 4-relay module + AA 55 01 8b 34 32 37 39 37 34 13 4b 35 36 37 80 0c 00 01 00 19 4c 09 */ - TasmotaGlobal.devices_present = 0; - SSPMSendGetModuleState(Sspm->module_selected -1); + if (0 == SspmBuffer[3]) { + // Discard v1.2.0 additions + TasmotaGlobal.devices_present = 0; + SSPMSendGetModuleState(Sspm->module_selected -1); + } break; case SSPM_FUNC_INIT_SCAN: /* 0x10 @@ -1117,7 +1215,11 @@ void SSPMHandleReceivedData(void) { AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 15 00 04 00 01 00 00 01 81 b1 |St|FwVersio| | | 1.0.0| + v1.2.0: + AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 15 00 04 00 01 02 00 01 41 10 + | | 1.2.0| */ + Sspm->main_version = SspmBuffer[20] << 16 | SspmBuffer[21] << 8 | SspmBuffer[22]; // 0x00010000 or 0x00010200 AddLog(LOG_LEVEL_INFO, PSTR("SPM: Main version %d.%d.%d found"), SspmBuffer[20], SspmBuffer[21], SspmBuffer[22]); Sspm->mstate = SPM_START_SCAN; @@ -1314,6 +1416,19 @@ void SSPMHandleReceivedData(void) { */ // TasmotaGlobal.restart_flag = 2; break; + case SSPM_FUNC_GET_NEW1: + /* 0x25 v1.2.0 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 21 22 23 + AA 55 01 8b 34 32 37 39 37 34 13 4b 35 36 37 80 25 00 01 01 06 98 06 + Marker |Module id |Ac|Cm|Size |St|Ix|Chksm| + */ + Sspm->module_selected--; + if (Sspm->module_selected > 0) { + SSPMSendGetModuleState(Sspm->module_selected -1); + } else { + SSPMSendGetScheme(Sspm->module_selected); + } + break; } } else { // Initiated by ARM @@ -1515,6 +1630,7 @@ void SSPMHandleReceivedData(void) { AddLog(LOG_LEVEL_DEBUG, PSTR("SPM: Relay scan done - none found")); Sspm->mstate = SPM_NONE; + Sspm->error_led_blinks = 255; } SSPMSendSetTime(); @@ -1755,6 +1871,8 @@ void SSPMEvery100ms(void) { // Wait for first acknowledge from ARM after reset SSPMSendCmnd(SSPM_FUNC_FIND); break; +/* + // Removed to accomodate v1.2.0 too case SPM_POLL_ARM_SPI: SSPMSendSPIFind(); Sspm->mstate = SPM_POLL_ARM_2; @@ -1766,6 +1884,7 @@ void SSPMEvery100ms(void) { case SPM_POLL_ARM_3: // Wait for second acknowledge from ARM after reset break; +*/ case SPM_SEND_FUNC_UNITS: // Get number of units SSPMSendCmnd(SSPM_FUNC_UNITS);