diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a919d698..f661e54d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,22 @@ All notable changes to this project will be documented in this file. ## [Released] +## [14.4.1] 20241215 +- Release Rudolph + +## [14.4.0.1] 20241215 +### Added +- MCP23XXX_DRV control register IOCON in template (#22622) + +### Changed +- Berry make Leds animate calls reentrant (#22643) +- SSL clean up remnants of old fingerprint algorithm (#22645) + +### Fixed +- ESP32 rules operation priority regression from v13.3.0.4 (#22636) +- GUI display power button regression from v14.3.0.5 (#15788) +- MCP23xxx, PCF8574 and Shift595 power control when a display is configured regression from v14.3.0.7 + ## [14.4.0] 20241211 - Release Rudolph @@ -47,8 +63,6 @@ All notable changes to this project will be documented in this file. - Add GUI submenu headers and refresh configuration button text (#22592) - ESP8266 Device Group exception due to lack of stack space (#22271) -### Removed - ## [14.3.0.6] 20241116 ### Added - Add command ``WebColor20`` to control color of Button when Off diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ba29f9fd0..20d31f8b4 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -75,7 +75,7 @@ Latest released binaries can be downloaded from - http://ota.tasmota.com/tasmota/release Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota/release-14.4.0 +- http://ota.tasmota.com/tasmota/release-14.4.1 The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` @@ -104,7 +104,7 @@ Latest released binaries can be downloaded from - https://ota.tasmota.com/tasmota32/release Historical binaries can be downloaded from -- https://ota.tasmota.com/tasmota32/release-14.4.0 +- https://ota.tasmota.com/tasmota32/release-14.4.1 The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` @@ -114,7 +114,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm [Complete list](BUILDS.md) of available feature and sensors. -## Changelog v14.4.0 Rudolph +## Changelog v14.4.1 Rudolph ### Added - Command `WebColor20` to control color of Button when Off - Command `SetOption161 1` to disable display of state text [#22515](https://github.com/arendst/Tasmota/issues/22515) @@ -139,6 +139,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Outdoor Temperature for MiElHVAC [#22345](https://github.com/arendst/Tasmota/issues/22345) - Mitsubishi Electric HVAC Compressor Frequency for MiElHVAC [#22347](https://github.com/arendst/Tasmota/issues/22347) - Mitsubishi Electric HVAC Auto Clear Remote Temp for MiElHVAC [#22370](https://github.com/arendst/Tasmota/issues/22370) +- MCP23XXX_DRV control register IOCON in template [#22622](https://github.com/arendst/Tasmota/issues/22622) - SolaxX1 Meter mode [#22330](https://github.com/arendst/Tasmota/issues/22330) - Show Active Power Total with any multi-phase energy monitoring [#22579](https://github.com/arendst/Tasmota/issues/22579) - ESP32 support for WPA2/3 Enterprise conditional in core v3.1.0.241206 [#22600](https://github.com/arendst/Tasmota/issues/22600) @@ -172,8 +173,10 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - DALI set Tasmota light control as default - Shutter optimized behavior to publish shutter data with sensor request [#22353](https://github.com/arendst/Tasmota/issues/22353) - Prevent active BLE operations with unencrypted MI-format beacons [#22453](https://github.com/arendst/Tasmota/issues/22453) +- SSL clean up remnants of old fingerprint algorithm [#22645](https://github.com/arendst/Tasmota/issues/22645) - ESP32 max number of supported switches/buttons/relays from 28 to 32 - ESP32 max number of interlocks from 14 to 16 +- Berry make Leds animate calls reentrant [#22643](https://github.com/arendst/Tasmota/issues/22643) - HASPmota support for page delete and object updates [#22311](https://github.com/arendst/Tasmota/issues/22311) ### Fixed @@ -188,11 +191,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm - Mitsubishi Electric HVAC Standby Stage for MiElHVAC [#22430](https://github.com/arendst/Tasmota/issues/22430) - EQ3 TRV firmware version 1.46 fails if the default true is used in subscribe on the notify characteristic [#22328](https://github.com/arendst/Tasmota/issues/22328) - Ethernet on -DFRAMEWORK_ARDUINO_ITEAD framework regression from v14.3.0 [#22367](https://github.com/arendst/Tasmota/issues/22367) -- ESP8266 Device Group exception due to lack of stack space (#22271)[#22271](https://github.com/arendst/Tasmota/issues/22271) +- MCP23xxx, PCF8574 and Shift595 power control when a display is configured regression from v14.3.0.7 +- GUI display power button regression from v14.3.0.5 [#15788](https://github.com/arendst/Tasmota/issues/15788) +- ESP8266 Device Group exception due to lack of stack space [#22271](https://github.com/arendst/Tasmota/issues/22271) +- ESP32 rules operation priority regression from v13.3.0.4 [#22636](https://github.com/arendst/Tasmota/issues/22636) - ESP32 Upgrade by file upload response based on file size [#22500](https://github.com/arendst/Tasmota/issues/22500) - ESP32 Arduino Core IPv6 zones used by Matter [#22378](https://github.com/arendst/Tasmota/issues/22378) - ESP32, ESP32-S2 and ESP32-S3 re-enable touch buttons [#22446](https://github.com/arendst/Tasmota/issues/22446) - ESP32-S3 UART output mode for Tx [#22426](https://github.com/arendst/Tasmota/issues/22426) - Matter provisioning with matter.js controller [#22470](https://github.com/arendst/Tasmota/issues/22470) - -### Removed diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp index afbe3602e..a11b04f03 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp @@ -767,59 +767,47 @@ extern "C" { xc->done_cert = true; // first cert already processed } -// **** Start patch Castellucci -/* - static void pubkeyfingerprint_pubkey_fingerprint(br_sha1_context *shactx, br_rsa_public_key rsakey) { - br_sha1_init(shactx); - br_sha1_update(shactx, "ssh-rsa", 7); // tag - br_sha1_update(shactx, rsakey.e, rsakey.elen); // exponent - br_sha1_update(shactx, rsakey.n, rsakey.nlen); // modulus - } -*/ - // If `compat` id false, adds a u32be length prefixed value to the sha1 state. - // If `compat` is true, the length will be omitted for compatibility with - // data from older versions of Tasmota. - static void sha1_update_len(br_sha1_context *shactx, const void *msg, uint32_t len, bool compat) { + // Add a data element with a u32be length prefix to the sha1 state. + static void sha1_update_len(br_sha1_context *shactx, const void *msg, uint32_t len) { uint8_t buf[] = {0, 0, 0, 0}; - if (!compat) { - buf[0] = (len >> 24) & 0xff; - buf[1] = (len >> 16) & 0xff; - buf[2] = (len >> 8) & 0xff; - buf[3] = (len >> 0) & 0xff; - br_sha1_update(shactx, buf, 4); // length - } + buf[0] = (len >> 24) & 0xff; + buf[1] = (len >> 16) & 0xff; + buf[2] = (len >> 8) & 0xff; + buf[3] = (len >> 0) & 0xff; + br_sha1_update(shactx, buf, 4); // length + br_sha1_update(shactx, msg, len); // message } - // Update the received fingerprint based on the certificate's public key. - // If `compat` is true, an insecure version of the fingerprint will be - // calcualted for compatibility with older versions of Tasmota. Normally, - // `compat` should be false. - static void pubkeyfingerprint_pubkey_fingerprint(br_x509_pubkeyfingerprint_context *xc, bool compat) { + // Calculate the received fingerprint based on the certificate's public key. + // The public exponent and modulus are length prefixed to avoid security + // vulnerabilities related to ambiguous serialization. Without this, an + // attacker can generate alternative public keys which result in the same + // fingerprint, but are trivial to crack. This works because RSA keys can be + // created with more than two primes, and most numbers, even large ones, can + // be easily factored. + static void pubkeyfingerprint_pubkey_fingerprint(br_x509_pubkeyfingerprint_context *xc) { br_rsa_public_key rsakey = xc->ctx.pkey.key.rsa; br_sha1_context shactx; br_sha1_init(&shactx); - sha1_update_len(&shactx, "ssh-rsa", 7, compat); // tag - sha1_update_len(&shactx, rsakey.e, rsakey.elen, compat); // exponent - sha1_update_len(&shactx, rsakey.n, rsakey.nlen, compat); // modulus + // The tag string doesn't really matter, but it should differ depending on + // key type. Since we only support RSA for now, it's a fixed string. + sha1_update_len(&shactx, "ssh-rsa", 7); // tag + sha1_update_len(&shactx, rsakey.e, rsakey.elen); // exponent + sha1_update_len(&shactx, rsakey.n, rsakey.nlen); // modulus br_sha1_out(&shactx, xc->pubkey_recv_fingerprint); // copy to fingerprint } -// **** End patch Castellucci // Callback when complete chain has been parsed. // Return 0 on validation success, !0 on validation error static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) { br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - // set fingerprint status byte to zero - // FIXME: find a better way to pass this information - xc->pubkey_recv_fingerprint[20] = 0; - // Try matching using the the new fingerprint algorithm - pubkeyfingerprint_pubkey_fingerprint(xc, false); + pubkeyfingerprint_pubkey_fingerprint(xc); if (!xc->fingerprint_all) { if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { return 0; @@ -832,7 +820,6 @@ extern "C" { // Default (no validation at all) or no errors in prior checks = success. return 0; } -// **** End patch Castellucci } // Return the public key from the validator (set by x509_minimal) diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h index 2c675d154..792a6d48e 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h @@ -152,12 +152,7 @@ class WiFiClientSecure_light : public WiFiClient { bool _insecure; // force fingerprint const uint8_t *_fingerprint1; // fingerprint1 to be checked against const uint8_t *_fingerprint2; // fingerprint2 to be checked against -// **** Start patch Castellucci -/* uint8_t _recv_fingerprint[20]; // fingerprint received -*/ - uint8_t _recv_fingerprint[21]; // fingerprint received -// **** End patch Castellucci unsigned char *_recvapp_buf; size_t _recvapp_len; diff --git a/lib/libesp32/berry_animate/src/embedded/animate_1_core.be b/lib/libesp32/berry_animate/src/embedded/animate_1_core.be index bacaf561d..190654244 100644 --- a/lib/libesp32/berry_animate/src/embedded/animate_1_core.be +++ b/lib/libesp32/berry_animate/src/embedded/animate_1_core.be @@ -110,6 +110,14 @@ class Animate_core self.strip.clear() end def start() + # check if the strip had a different animate object, stop it + var prev_animate = self.strip.get_animate() + import introspect + if (prev_animate != nil) && (type(prev_animate) == 'instance') && (prev_animate != self) + prev_animate.stop() + end + self.strip.set_animate(self) + self.running = true var animators = self.animators var idx = 0 diff --git a/lib/libesp32/berry_animate/src/solidify/solidified_animate_1_core.h b/lib/libesp32/berry_animate/src/solidify/solidified_animate_1_core.h index 440804ff2..eee5e9752 100644 --- a/lib/libesp32/berry_animate/src/solidify/solidified_animate_1_core.h +++ b/lib/libesp32/berry_animate/src/solidify/solidified_animate_1_core.h @@ -3,8 +3,8 @@ * Generated code, don't edit * \********************************************************************/ #include "be_constobj.h" -// compact class 'Animate_core' ktab size: 48, total: 98 (saved 400 bytes) -static const bvalue be_ktab_class_Animate_core[48] = { +// compact class 'Animate_core' ktab size: 52, total: 104 (saved 416 bytes) +static const bvalue be_ktab_class_Animate_core[52] = { /* K0 */ be_nested_str_weak(stop), /* K1 */ be_nested_str_weak(strip), /* K2 */ be_nested_str_weak(clear), @@ -51,8 +51,12 @@ static const bvalue be_ktab_class_Animate_core[48] = { /* K43 */ be_nested_str_weak(set_cb), /* K44 */ be_nested_str_weak(set_back_color), /* K45 */ be_nested_str_weak(add_animator), - /* K46 */ be_nested_str_weak(start), - /* K47 */ be_nested_str_weak(add_fast_loop), + /* K46 */ be_nested_str_weak(get_animate), + /* K47 */ be_nested_str_weak(introspect), + /* K48 */ be_nested_str_weak(instance), + /* K49 */ be_nested_str_weak(set_animate), + /* K50 */ be_nested_str_weak(start), + /* K51 */ be_nested_str_weak(add_fast_loop), }; @@ -716,7 +720,7 @@ be_local_closure(class_Animate_core_remove, /* name */ ********************************************************************/ be_local_closure(class_Animate_core_start, /* name */ be_nested_proto( - 6, /* nstack */ + 8, /* nstack */ 1, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -727,27 +731,47 @@ be_local_closure(class_Animate_core_start, /* name */ &be_ktab_class_Animate_core, /* shared constants */ be_str_weak(start), &be_const_str_solidified, - ( &(const binstruction[20]) { /* code */ - 0x50040200, // 0000 LDBOOL R1 1 0 - 0x90021601, // 0001 SETMBR R0 K11 R1 - 0x8804010C, // 0002 GETMBR R1 R0 K12 - 0x58080007, // 0003 LDCONST R2 K7 - 0x600C000C, // 0004 GETGBL R3 G12 - 0x5C100200, // 0005 MOVE R4 R1 - 0x7C0C0200, // 0006 CALL R3 1 - 0x140C0403, // 0007 LT R3 R2 R3 - 0x780E0004, // 0008 JMPF R3 #000E - 0x940C0202, // 0009 GETIDX R3 R1 R2 - 0x8C0C072E, // 000A GETMET R3 R3 K46 - 0x7C0C0200, // 000B CALL R3 1 - 0x0008050D, // 000C ADD R2 R2 K13 - 0x7001FFF5, // 000D JMP #0004 - 0x90022707, // 000E SETMBR R0 K19 K7 - 0xB80E0800, // 000F GETNGBL R3 K4 - 0x8C0C072F, // 0010 GETMET R3 R3 K47 - 0x8814010F, // 0011 GETMBR R5 R0 K15 - 0x7C0C0400, // 0012 CALL R3 2 - 0x80000000, // 0013 RET 0 + ( &(const binstruction[40]) { /* code */ + 0x88040101, // 0000 GETMBR R1 R0 K1 + 0x8C04032E, // 0001 GETMET R1 R1 K46 + 0x7C040200, // 0002 CALL R1 1 + 0xA40A5E00, // 0003 IMPORT R2 K47 + 0x4C0C0000, // 0004 LDNIL R3 + 0x200C0203, // 0005 NE R3 R1 R3 + 0x780E0008, // 0006 JMPF R3 #0010 + 0x600C0004, // 0007 GETGBL R3 G4 + 0x5C100200, // 0008 MOVE R4 R1 + 0x7C0C0200, // 0009 CALL R3 1 + 0x1C0C0730, // 000A EQ R3 R3 K48 + 0x780E0003, // 000B JMPF R3 #0010 + 0x200C0200, // 000C NE R3 R1 R0 + 0x780E0001, // 000D JMPF R3 #0010 + 0x8C0C0300, // 000E GETMET R3 R1 K0 + 0x7C0C0200, // 000F CALL R3 1 + 0x880C0101, // 0010 GETMBR R3 R0 K1 + 0x8C0C0731, // 0011 GETMET R3 R3 K49 + 0x5C140000, // 0012 MOVE R5 R0 + 0x7C0C0400, // 0013 CALL R3 2 + 0x500C0200, // 0014 LDBOOL R3 1 0 + 0x90021603, // 0015 SETMBR R0 K11 R3 + 0x880C010C, // 0016 GETMBR R3 R0 K12 + 0x58100007, // 0017 LDCONST R4 K7 + 0x6014000C, // 0018 GETGBL R5 G12 + 0x5C180600, // 0019 MOVE R6 R3 + 0x7C140200, // 001A CALL R5 1 + 0x14140805, // 001B LT R5 R4 R5 + 0x78160004, // 001C JMPF R5 #0022 + 0x94140604, // 001D GETIDX R5 R3 R4 + 0x8C140B32, // 001E GETMET R5 R5 K50 + 0x7C140200, // 001F CALL R5 1 + 0x0010090D, // 0020 ADD R4 R4 K13 + 0x7001FFF5, // 0021 JMP #0018 + 0x90022707, // 0022 SETMBR R0 K19 K7 + 0xB8160800, // 0023 GETNGBL R5 K4 + 0x8C140B33, // 0024 GETMET R5 R5 K51 + 0x881C010F, // 0025 GETMBR R7 R0 K15 + 0x7C140400, // 0026 CALL R5 2 + 0x80000000, // 0027 RET 0 }) ) ); diff --git a/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c b/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c index 11b2712f6..bd6ad641b 100644 --- a/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_leds_ntv_lib.c @@ -16,7 +16,6 @@ extern int be_leds_apply_bri_gamma(bvm *vm); /* @const_object_info_begin class be_class_Leds_ntv (scope: global, name: Leds_ntv, strings: weak) { _p, var - _t, var WS2812_GRB, int(ws2812_grb) SK6812_GRBW, int(sk6812_grbw) diff --git a/lib/libesp32/berry_tasmota/src/embedded/leds.be b/lib/libesp32/berry_tasmota/src/embedded/leds.be index 7a124fc50..98fbbfd29 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/leds.be +++ b/lib/libesp32/berry_tasmota/src/embedded/leds.be @@ -28,6 +28,7 @@ class Leds : Leds_ntv var gamma # if true, apply gamma (true is default) var leds # number of leds var bri # implicit brightness for this led strip (0..255, default is 50% = 127) + var animate # attached animate object or nil - this allows to stop any existing animation for this strip if we add a new animate # leds:int = number of leds of the strip # gpio:int (optional) = GPIO for NeoPixel. If not specified, takes the WS2812 gpio # typ:int (optional) = Type of LED, defaults to WS2812 RGB @@ -35,25 +36,43 @@ class Leds : Leds_ntv def init(leds, gpio_phy, typ, hardware) import gpio self.gamma = true # gamma is enabled by default, it should be disabled explicitly if needed - if (gpio_phy == nil) || (gpio_phy == gpio.pin(gpio.WS2812, 0)) + if (leds == nil ) || (gpio_phy == nil) || (gpio_phy == gpio.pin(gpio.WS2812, 0)) # use native driver self.ctor() # no parameters + # in such case, `self._p` is equal to `0` self.leds = self.pixel_count() import light self.bri = light.get()['bri'] else # use pure Berry driver - self.leds = int(leds) + leds = int(leds) + self.leds = leds self.bri = 127 # 50% brightness by default # initialize the structure - self.ctor(self.leds, gpio_phy, typ, hardware) + # check if already in global `_lhw` + if !global.contains('_lhw') + global._lhw = {} + end + if global._lhw.find(leds) != nil + # an object already exists, attach it + var prov_led = global._lhw.find(leds) # already provisioned leds instance + if self.leds != prov_led.leds + raise "value_error", f"number of leds do not match with previous instanciation {self.leds} vs {prov_led.leds}" + end + self._p = prov_led._p + self.animate = prov_led.animate + global._lhw[leds] = self # put the most recent as current + else + self.ctor(leds, gpio_phy, typ, hardware) + global._lhw[leds] = self + # call begin + self.begin() + end end if self._p == nil raise "internal_error", "couldn't not initialize noepixelbus" end - # call begin - self.begin() end def clear() @@ -71,6 +90,13 @@ class Leds : Leds_ntv return self.bri end + def set_animate(animate) + self.animate = animate + end + def get_animate() + return self.animate + end + def ctor(leds, gpio_phy, typ, hardware) if gpio_phy == nil self.call_native(0) # native driver diff --git a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h index 5a493db0e..2e476a976 100644 --- a/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h +++ b/lib/libesp32/berry_tasmota/src/solidify/solidified_leds.h @@ -3,9 +3,471 @@ * Generated code, don't edit * \********************************************************************/ #include "be_constobj.h" +extern const bclass be_class_Leds_segment; extern const bclass be_class_Leds; extern const bclass be_class_Leds_matrix; +// compact class 'Leds_segment' ktab size: 16, total: 34 (saved 144 bytes) +static const bvalue be_ktab_class_Leds_segment[16] = { + /* K0 */ be_nested_str(offset), + /* K1 */ be_nested_str(bri), + /* K2 */ be_nested_str(strip), + /* K3 */ be_nested_str(call_native), + /* K4 */ be_nested_str(to_gamma), + /* K5 */ be_nested_str(leds), + /* K6 */ be_nested_str(dirty), + /* K7 */ be_nested_str(can_show), + /* K8 */ be_nested_str(set_pixel_color), + /* K9 */ be_nested_str(is_dirty), + /* K10 */ be_nested_str(clear_to), + /* K11 */ be_const_int(0), + /* K12 */ be_nested_str(show), + /* K13 */ be_nested_str(get_pixel_color), + /* K14 */ be_nested_str(offseta), + /* K15 */ be_nested_str(pixel_size), +}; + + extern const bclass be_class_Leds_segment; + +/******************************************************************** +** Solidified function: pixel_offset +********************************************************************/ +be_local_closure(class_Leds_segment_pixel_offset, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixel_offset, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: clear_to +********************************************************************/ +be_local_closure(class_Leds_segment_clear_to, /* name */ + be_nested_proto( + 10, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_clear_to, + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0000, // 0002 JMPF R3 #0004 + 0x88080101, // 0003 GETMBR R2 R0 K1 + 0x880C0102, // 0004 GETMBR R3 R0 K2 + 0x8C0C0703, // 0005 GETMET R3 R3 K3 + 0x54160008, // 0006 LDINT R5 9 + 0x88180102, // 0007 GETMBR R6 R0 K2 + 0x8C180D04, // 0008 GETMET R6 R6 K4 + 0x5C200200, // 0009 MOVE R8 R1 + 0x5C240400, // 000A MOVE R9 R2 + 0x7C180600, // 000B CALL R6 3 + 0x881C0100, // 000C GETMBR R7 R0 K0 + 0x88200105, // 000D GETMBR R8 R0 K5 + 0x7C0C0A00, // 000E CALL R3 5 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixel_count +********************************************************************/ +be_local_closure(class_Leds_segment_pixel_count, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixel_count, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x88040105, // 0000 GETMBR R1 R0 K5 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixels_buffer +********************************************************************/ +be_local_closure(class_Leds_segment_pixels_buffer, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixels_buffer, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: dirty +********************************************************************/ +be_local_closure(class_Leds_segment_dirty, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040306, // 0001 GETMET R1 R1 K6 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: can_show +********************************************************************/ +be_local_closure(class_Leds_segment_can_show, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_can_show, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040307, // 0001 GETMET R1 R1 K7 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_pixel_color +********************************************************************/ +be_local_closure(class_Leds_segment_set_pixel_color, /* name */ + be_nested_proto( + 9, /* nstack */ + 4, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_set_pixel_color, + &be_const_str_solidified, + ( &(const binstruction[12]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x1C100604, // 0001 EQ R4 R3 R4 + 0x78120000, // 0002 JMPF R4 #0004 + 0x880C0101, // 0003 GETMBR R3 R0 K1 + 0x88100102, // 0004 GETMBR R4 R0 K2 + 0x8C100908, // 0005 GETMET R4 R4 K8 + 0x88180100, // 0006 GETMBR R6 R0 K0 + 0x00180206, // 0007 ADD R6 R1 R6 + 0x5C1C0400, // 0008 MOVE R7 R2 + 0x5C200600, // 0009 MOVE R8 R3 + 0x7C100800, // 000A CALL R4 4 + 0x80000000, // 000B RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: is_dirty +********************************************************************/ +be_local_closure(class_Leds_segment_is_dirty, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_is_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C040309, // 0001 GETMET R1 R1 K9 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: clear +********************************************************************/ +be_local_closure(class_Leds_segment_clear, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_clear, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x8C04010A, // 0000 GETMET R1 R0 K10 + 0x580C000B, // 0001 LDCONST R3 K11 + 0x7C040400, // 0002 CALL R1 2 + 0x8C04010C, // 0003 GETMET R1 R0 K12 + 0x7C040200, // 0004 CALL R1 1 + 0x80000000, // 0005 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin +********************************************************************/ +be_local_closure(class_Leds_segment_begin, /* name */ + be_nested_proto( + 1, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_begin, + &be_const_str_solidified, + ( &(const binstruction[ 1]) { /* code */ + 0x80000000, // 0000 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_pixel_color +********************************************************************/ +be_local_closure(class_Leds_segment_get_pixel_color, /* name */ + be_nested_proto( + 5, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_get_pixel_color, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x88080102, // 0000 GETMBR R2 R0 K2 + 0x8C08050D, // 0001 GETMET R2 R2 K13 + 0x8810010E, // 0002 GETMBR R4 R0 K14 + 0x00100204, // 0003 ADD R4 R1 R4 + 0x7C080400, // 0004 CALL R2 2 + 0x80040400, // 0005 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: pixel_size +********************************************************************/ +be_local_closure(class_Leds_segment_pixel_size, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_pixel_size, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040102, // 0000 GETMBR R1 R0 K2 + 0x8C04030F, // 0001 GETMET R1 R1 K15 + 0x7C040200, // 0002 CALL R1 1 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(class_Leds_segment_init, /* name */ + be_nested_proto( + 6, /* nstack */ + 4, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_init, + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x90020401, // 0000 SETMBR R0 K2 R1 + 0x60100009, // 0001 GETGBL R4 G9 + 0x5C140400, // 0002 MOVE R5 R2 + 0x7C100200, // 0003 CALL R4 1 + 0x90020004, // 0004 SETMBR R0 K0 R4 + 0x60100009, // 0005 GETGBL R4 G9 + 0x5C140600, // 0006 MOVE R5 R3 + 0x7C100200, // 0007 CALL R4 1 + 0x90020A04, // 0008 SETMBR R0 K5 R4 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: show +********************************************************************/ +be_local_closure(class_Leds_segment_show, /* name */ + be_nested_proto( + 4, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds_segment, /* shared constants */ + &be_const_str_show, + &be_const_str_solidified, + ( &(const binstruction[16]) { /* code */ + 0x60080017, // 0000 GETGBL R2 G23 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x740A0007, // 0003 JMPT R2 #000C + 0x88080100, // 0004 GETMBR R2 R0 K0 + 0x1C08050B, // 0005 EQ R2 R2 K11 + 0x780A0007, // 0006 JMPF R2 #000F + 0x88080105, // 0007 GETMBR R2 R0 K5 + 0x880C0102, // 0008 GETMBR R3 R0 K2 + 0x880C0705, // 0009 GETMBR R3 R3 K5 + 0x1C080403, // 000A EQ R2 R2 R3 + 0x780A0002, // 000B JMPF R2 #000F + 0x88080102, // 000C GETMBR R2 R0 K2 + 0x8C08050C, // 000D GETMET R2 R2 K12 + 0x7C080200, // 000E CALL R2 1 + 0x80000000, // 000F RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: Leds_segment +********************************************************************/ +be_local_class(Leds_segment, + 3, + NULL, + be_nested_map(17, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key(pixel_offset, 9), be_const_closure(class_Leds_segment_pixel_offset_closure) }, + { be_const_key(clear_to, -1), be_const_closure(class_Leds_segment_clear_to_closure) }, + { be_const_key(show, -1), be_const_closure(class_Leds_segment_show_closure) }, + { be_const_key(pixels_buffer, 10), be_const_closure(class_Leds_segment_pixels_buffer_closure) }, + { be_const_key(offset, -1), be_const_var(1) }, + { be_const_key(dirty, -1), be_const_closure(class_Leds_segment_dirty_closure) }, + { be_const_key(can_show, -1), be_const_closure(class_Leds_segment_can_show_closure) }, + { be_const_key(set_pixel_color, 6), be_const_closure(class_Leds_segment_set_pixel_color_closure) }, + { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_segment_get_pixel_color_closure) }, + { be_const_key(pixel_count, -1), be_const_closure(class_Leds_segment_pixel_count_closure) }, + { be_const_key(strip, 7), be_const_var(0) }, + { be_const_key(leds, -1), be_const_var(2) }, + { be_const_key(begin, -1), be_const_closure(class_Leds_segment_begin_closure) }, + { be_const_key(is_dirty, 8), be_const_closure(class_Leds_segment_is_dirty_closure) }, + { be_const_key(pixel_size, -1), be_const_closure(class_Leds_segment_pixel_size_closure) }, + { be_const_key(init, -1), be_const_closure(class_Leds_segment_init_closure) }, + { be_const_key(clear, 2), be_const_closure(class_Leds_segment_clear_closure) }, + })), + (bstring*) &be_const_str_Leds_segment +); // compact class 'Leds_matrix' ktab size: 24, total: 62 (saved 304 bytes) static const bvalue be_ktab_class_Leds_matrix[24] = { /* K0 */ be_nested_str(strip), @@ -649,60 +1111,58 @@ be_local_class(Leds_matrix, })), (bstring*) &be_const_str_Leds_matrix ); -// compact class 'Leds_segment' ktab size: 16, total: 34 (saved 144 bytes) -static const bvalue be_ktab_class_Leds_segment[16] = { - /* K0 */ be_nested_str(offset), - /* K1 */ be_nested_str(bri), - /* K2 */ be_nested_str(strip), - /* K3 */ be_nested_str(call_native), - /* K4 */ be_nested_str(to_gamma), - /* K5 */ be_nested_str(leds), - /* K6 */ be_nested_str(dirty), - /* K7 */ be_nested_str(can_show), - /* K8 */ be_nested_str(set_pixel_color), - /* K9 */ be_nested_str(is_dirty), - /* K10 */ be_nested_str(clear_to), - /* K11 */ be_const_int(0), - /* K12 */ be_nested_str(show), - /* K13 */ be_nested_str(get_pixel_color), - /* K14 */ be_nested_str(offseta), - /* K15 */ be_nested_str(pixel_size), +// compact class 'Leds' ktab size: 39, total: 74 (saved 280 bytes) +static const bvalue be_ktab_class_Leds[39] = { + /* K0 */ be_nested_str(leds), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(value_error), + /* K3 */ be_nested_str(out_X20of_X20range), + /* K4 */ be_const_class(be_class_Leds_segment), + /* K5 */ be_nested_str(gamma), + /* K6 */ be_const_class(be_class_Leds), + /* K7 */ be_nested_str(Leds), + /* K8 */ be_nested_str(create_matrix), + /* K9 */ be_nested_str(call_native), + /* K10 */ be_nested_str(pixel_size), + /* K11 */ be_nested_str(pixel_count), + /* K12 */ be_nested_str(_change_buffer), + /* K13 */ be_nested_str(animate), + /* K14 */ be_const_int(2), + /* K15 */ be_nested_str(bri), + /* K16 */ be_nested_str(to_gamma), + /* K17 */ be_nested_str(clear_to), + /* K18 */ be_nested_str(show), + /* K19 */ be_nested_str(apply_bri_gamma), + /* K20 */ be_const_int(1), + /* K21 */ be_const_class(be_class_Leds_matrix), + /* K22 */ be_const_int(3), + /* K23 */ be_nested_str(gpio), + /* K24 */ be_nested_str(pin), + /* K25 */ be_nested_str(WS2812), + /* K26 */ be_nested_str(ctor), + /* K27 */ be_nested_str(light), + /* K28 */ be_nested_str(get), + /* K29 */ be_nested_str(global), + /* K30 */ be_nested_str(contains), + /* K31 */ be_nested_str(_lhw), + /* K32 */ be_nested_str(find), + /* K33 */ be_nested_str(number_X20of_X20leds_X20do_X20not_X20match_X20with_X20previous_X20instanciation_X20_X25s_X20vs_X20_X25s), + /* K34 */ be_nested_str(_p), + /* K35 */ be_nested_str(begin), + /* K36 */ be_nested_str(internal_error), + /* K37 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus), + /* K38 */ be_nested_str(WS2812_GRB), }; -extern const bclass be_class_Leds_segment; +extern const bclass be_class_Leds; /******************************************************************** -** Solidified function: pixel_offset +** Solidified function: create_segment ********************************************************************/ -be_local_closure(class_Leds_segment_pixel_offset, /* name */ +be_local_closure(class_Leds_create_segment, /* name */ be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixel_offset, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: clear_to -********************************************************************/ -be_local_closure(class_Leds_segment_clear_to, /* name */ - be_nested_proto( - 10, /* nstack */ + 8, /* nstack */ 3, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -710,26 +1170,33 @@ be_local_closure(class_Leds_segment_clear_to, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_clear_to, + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_create_segment, &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x1C0C0403, // 0001 EQ R3 R2 R3 - 0x780E0000, // 0002 JMPF R3 #0004 - 0x88080101, // 0003 GETMBR R2 R0 K1 - 0x880C0102, // 0004 GETMBR R3 R0 K2 - 0x8C0C0703, // 0005 GETMET R3 R3 K3 - 0x54160008, // 0006 LDINT R5 9 - 0x88180102, // 0007 GETMBR R6 R0 K2 - 0x8C180D04, // 0008 GETMET R6 R6 K4 - 0x5C200200, // 0009 MOVE R8 R1 - 0x5C240400, // 000A MOVE R9 R2 - 0x7C180600, // 000B CALL R6 3 - 0x881C0100, // 000C GETMBR R7 R0 K0 - 0x88200105, // 000D GETMBR R8 R0 K5 - 0x7C0C0A00, // 000E CALL R3 5 - 0x80000000, // 000F RET 0 + ( &(const binstruction[23]) { /* code */ + 0x600C0009, // 0000 GETGBL R3 G9 + 0x5C100200, // 0001 MOVE R4 R1 + 0x7C0C0200, // 0002 CALL R3 1 + 0x60100009, // 0003 GETGBL R4 G9 + 0x5C140400, // 0004 MOVE R5 R2 + 0x7C100200, // 0005 CALL R4 1 + 0x000C0604, // 0006 ADD R3 R3 R4 + 0x88100100, // 0007 GETMBR R4 R0 K0 + 0x240C0604, // 0008 GT R3 R3 R4 + 0x740E0003, // 0009 JMPT R3 #000E + 0x140C0301, // 000A LT R3 R1 K1 + 0x740E0001, // 000B JMPT R3 #000E + 0x140C0501, // 000C LT R3 R2 K1 + 0x780E0000, // 000D JMPF R3 #000F + 0xB0060503, // 000E RAISE 1 K2 K3 + 0x580C0004, // 000F LDCONST R3 K4 + 0xB4000004, // 0010 CLASS K4 + 0x5C100600, // 0011 MOVE R4 R3 + 0x5C140000, // 0012 MOVE R5 R0 + 0x5C180200, // 0013 MOVE R6 R1 + 0x5C1C0400, // 0014 MOVE R7 R2 + 0x7C100600, // 0015 CALL R4 3 + 0x80040800, // 0016 RET 1 R4 }) ) ); @@ -737,9 +1204,9 @@ be_local_closure(class_Leds_segment_clear_to, /* name */ /******************************************************************** -** Solidified function: pixel_count +** Solidified function: get_gamma ********************************************************************/ -be_local_closure(class_Leds_segment_pixel_count, /* name */ +be_local_closure(class_Leds_get_gamma, /* name */ be_nested_proto( 2, /* nstack */ 1, /* argc */ @@ -749,8 +1216,8 @@ be_local_closure(class_Leds_segment_pixel_count, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixel_count, + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_get_gamma, &be_const_str_solidified, ( &(const binstruction[ 2]) { /* code */ 0x88040105, // 0000 GETMBR R1 R0 K5 @@ -761,448 +1228,6 @@ be_local_closure(class_Leds_segment_pixel_count, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: pixels_buffer -********************************************************************/ -be_local_closure(class_Leds_segment_pixels_buffer, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixels_buffer, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x4C040000, // 0000 LDNIL R1 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: dirty -********************************************************************/ -be_local_closure(class_Leds_segment_dirty, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_dirty, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C040306, // 0001 GETMET R1 R1 K6 - 0x7C040200, // 0002 CALL R1 1 - 0x80000000, // 0003 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: can_show -********************************************************************/ -be_local_closure(class_Leds_segment_can_show, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_can_show, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C040307, // 0001 GETMET R1 R1 K7 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_pixel_color -********************************************************************/ -be_local_closure(class_Leds_segment_set_pixel_color, /* name */ - be_nested_proto( - 9, /* nstack */ - 4, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_set_pixel_color, - &be_const_str_solidified, - ( &(const binstruction[12]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x1C100604, // 0001 EQ R4 R3 R4 - 0x78120000, // 0002 JMPF R4 #0004 - 0x880C0101, // 0003 GETMBR R3 R0 K1 - 0x88100102, // 0004 GETMBR R4 R0 K2 - 0x8C100908, // 0005 GETMET R4 R4 K8 - 0x88180100, // 0006 GETMBR R6 R0 K0 - 0x00180206, // 0007 ADD R6 R1 R6 - 0x5C1C0400, // 0008 MOVE R7 R2 - 0x5C200600, // 0009 MOVE R8 R3 - 0x7C100800, // 000A CALL R4 4 - 0x80000000, // 000B RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: is_dirty -********************************************************************/ -be_local_closure(class_Leds_segment_is_dirty, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_is_dirty, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C040309, // 0001 GETMET R1 R1 K9 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: clear -********************************************************************/ -be_local_closure(class_Leds_segment_clear, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_clear, - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C04010A, // 0000 GETMET R1 R0 K10 - 0x580C000B, // 0001 LDCONST R3 K11 - 0x7C040400, // 0002 CALL R1 2 - 0x8C04010C, // 0003 GETMET R1 R0 K12 - 0x7C040200, // 0004 CALL R1 1 - 0x80000000, // 0005 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: begin -********************************************************************/ -be_local_closure(class_Leds_segment_begin, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_begin, - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80000000, // 0000 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_pixel_color -********************************************************************/ -be_local_closure(class_Leds_segment_get_pixel_color, /* name */ - be_nested_proto( - 5, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_get_pixel_color, - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x88080102, // 0000 GETMBR R2 R0 K2 - 0x8C08050D, // 0001 GETMET R2 R2 K13 - 0x8810010E, // 0002 GETMBR R4 R0 K14 - 0x00100204, // 0003 ADD R4 R1 R4 - 0x7C080400, // 0004 CALL R2 2 - 0x80040400, // 0005 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixel_size -********************************************************************/ -be_local_closure(class_Leds_segment_pixel_size, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_pixel_size, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x88040102, // 0000 GETMBR R1 R0 K2 - 0x8C04030F, // 0001 GETMET R1 R1 K15 - 0x7C040200, // 0002 CALL R1 1 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(class_Leds_segment_init, /* name */ - be_nested_proto( - 6, /* nstack */ - 4, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_init, - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x90020401, // 0000 SETMBR R0 K2 R1 - 0x60100009, // 0001 GETGBL R4 G9 - 0x5C140400, // 0002 MOVE R5 R2 - 0x7C100200, // 0003 CALL R4 1 - 0x90020004, // 0004 SETMBR R0 K0 R4 - 0x60100009, // 0005 GETGBL R4 G9 - 0x5C140600, // 0006 MOVE R5 R3 - 0x7C100200, // 0007 CALL R4 1 - 0x90020A04, // 0008 SETMBR R0 K5 R4 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: show -********************************************************************/ -be_local_closure(class_Leds_segment_show, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds_segment, /* shared constants */ - &be_const_str_show, - &be_const_str_solidified, - ( &(const binstruction[16]) { /* code */ - 0x60080017, // 0000 GETGBL R2 G23 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x740A0007, // 0003 JMPT R2 #000C - 0x88080100, // 0004 GETMBR R2 R0 K0 - 0x1C08050B, // 0005 EQ R2 R2 K11 - 0x780A0007, // 0006 JMPF R2 #000F - 0x88080105, // 0007 GETMBR R2 R0 K5 - 0x880C0102, // 0008 GETMBR R3 R0 K2 - 0x880C0705, // 0009 GETMBR R3 R3 K5 - 0x1C080403, // 000A EQ R2 R2 R3 - 0x780A0002, // 000B JMPF R2 #000F - 0x88080102, // 000C GETMBR R2 R0 K2 - 0x8C08050C, // 000D GETMET R2 R2 K12 - 0x7C080200, // 000E CALL R2 1 - 0x80000000, // 000F RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified class: Leds_segment -********************************************************************/ -be_local_class(Leds_segment, - 3, - NULL, - be_nested_map(17, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(pixel_offset, 9), be_const_closure(class_Leds_segment_pixel_offset_closure) }, - { be_const_key(clear_to, -1), be_const_closure(class_Leds_segment_clear_to_closure) }, - { be_const_key(show, -1), be_const_closure(class_Leds_segment_show_closure) }, - { be_const_key(pixels_buffer, 10), be_const_closure(class_Leds_segment_pixels_buffer_closure) }, - { be_const_key(offset, -1), be_const_var(1) }, - { be_const_key(dirty, -1), be_const_closure(class_Leds_segment_dirty_closure) }, - { be_const_key(can_show, -1), be_const_closure(class_Leds_segment_can_show_closure) }, - { be_const_key(set_pixel_color, 6), be_const_closure(class_Leds_segment_set_pixel_color_closure) }, - { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_segment_get_pixel_color_closure) }, - { be_const_key(pixel_count, -1), be_const_closure(class_Leds_segment_pixel_count_closure) }, - { be_const_key(strip, 7), be_const_var(0) }, - { be_const_key(leds, -1), be_const_var(2) }, - { be_const_key(begin, -1), be_const_closure(class_Leds_segment_begin_closure) }, - { be_const_key(is_dirty, 8), be_const_closure(class_Leds_segment_is_dirty_closure) }, - { be_const_key(pixel_size, -1), be_const_closure(class_Leds_segment_pixel_size_closure) }, - { be_const_key(init, -1), be_const_closure(class_Leds_segment_init_closure) }, - { be_const_key(clear, 2), be_const_closure(class_Leds_segment_clear_closure) }, - })), - (bstring*) &be_const_str_Leds_segment -); -// compact class 'Leds' ktab size: 33, total: 65 (saved 256 bytes) -static const bvalue be_ktab_class_Leds[33] = { - /* K0 */ be_nested_str(call_native), - /* K1 */ be_nested_str(bri), - /* K2 */ be_const_class(be_class_Leds), - /* K3 */ be_nested_str(Leds), - /* K4 */ be_nested_str(create_matrix), - /* K5 */ be_const_int(0), - /* K6 */ be_const_int(3), - /* K7 */ be_nested_str(gamma), - /* K8 */ be_const_int(2), - /* K9 */ be_nested_str(WS2812_GRB), - /* K10 */ be_nested_str(leds), - /* K11 */ be_nested_str(value_error), - /* K12 */ be_nested_str(out_X20of_X20range), - /* K13 */ be_const_class(be_class_Leds_matrix), - /* K14 */ be_nested_str(to_gamma), - /* K15 */ be_const_class(be_class_Leds_segment), - /* K16 */ be_nested_str(gpio), - /* K17 */ be_nested_str(pin), - /* K18 */ be_nested_str(WS2812), - /* K19 */ be_nested_str(ctor), - /* K20 */ be_nested_str(pixel_count), - /* K21 */ be_nested_str(light), - /* K22 */ be_nested_str(get), - /* K23 */ be_nested_str(_p), - /* K24 */ be_nested_str(internal_error), - /* K25 */ be_nested_str(couldn_X27t_X20not_X20initialize_X20noepixelbus), - /* K26 */ be_nested_str(begin), - /* K27 */ be_nested_str(clear_to), - /* K28 */ be_nested_str(show), - /* K29 */ be_const_int(1), - /* K30 */ be_nested_str(apply_bri_gamma), - /* K31 */ be_nested_str(pixel_size), - /* K32 */ be_nested_str(_change_buffer), -}; - - -extern const bclass be_class_Leds; - -/******************************************************************** -** Solidified function: is_dirty -********************************************************************/ -be_local_closure(class_Leds_is_dirty, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_is_dirty, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x540E0003, // 0001 LDINT R3 4 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_bri -********************************************************************/ -be_local_closure(class_Leds_get_bri, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_get_bri, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040101, // 0000 GETMBR R1 R0 K1 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: matrix ********************************************************************/ @@ -1220,16 +1245,16 @@ be_local_closure(class_Leds_matrix, /* name */ &be_const_str_matrix, &be_const_str_solidified, ( &(const binstruction[12]) { /* code */ - 0x58100002, // 0000 LDCONST R4 K2 - 0xB8160600, // 0001 GETNGBL R5 K3 + 0x58100006, // 0000 LDCONST R4 K6 + 0xB8160E00, // 0001 GETNGBL R5 K7 0x08180001, // 0002 MUL R6 R0 R1 0x5C1C0400, // 0003 MOVE R7 R2 0x5C200600, // 0004 MOVE R8 R3 0x7C140600, // 0005 CALL R5 3 - 0x8C180B04, // 0006 GETMET R6 R5 K4 + 0x8C180B08, // 0006 GETMET R6 R5 K8 0x5C200000, // 0007 MOVE R8 R0 0x5C240200, // 0008 MOVE R9 R1 - 0x58280005, // 0009 LDCONST R10 K5 + 0x58280001, // 0009 LDCONST R10 K1 0x7C180800, // 000A CALL R6 4 0x80040C00, // 000B RET 1 R6 }) @@ -1239,11 +1264,55 @@ be_local_closure(class_Leds_matrix, /* name */ /******************************************************************** -** Solidified function: can_show +** Solidified function: pixels_buffer ********************************************************************/ -be_local_closure(class_Leds_can_show, /* name */ +be_local_closure(class_Leds_pixels_buffer, /* name */ be_nested_proto( - 4, /* nstack */ + 8, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_pixels_buffer, + &be_const_str_solidified, + ( &(const binstruction[21]) { /* code */ + 0x8C080109, // 0000 GETMET R2 R0 K9 + 0x54120005, // 0001 LDINT R4 6 + 0x7C080400, // 0002 CALL R2 2 + 0x4C0C0000, // 0003 LDNIL R3 + 0x1C0C0203, // 0004 EQ R3 R1 R3 + 0x780E0009, // 0005 JMPF R3 #0010 + 0x600C0015, // 0006 GETGBL R3 G21 + 0x5C100400, // 0007 MOVE R4 R2 + 0x8C14010A, // 0008 GETMET R5 R0 K10 + 0x7C140200, // 0009 CALL R5 1 + 0x8C18010B, // 000A GETMET R6 R0 K11 + 0x7C180200, // 000B CALL R6 1 + 0x08140A06, // 000C MUL R5 R5 R6 + 0x7C0C0400, // 000D CALL R3 2 + 0x80040600, // 000E RET 1 R3 + 0x70020003, // 000F JMP #0014 + 0x8C0C030C, // 0010 GETMET R3 R1 K12 + 0x5C140400, // 0011 MOVE R5 R2 + 0x7C0C0400, // 0012 CALL R3 2 + 0x80040200, // 0013 RET 1 R1 + 0x80000000, // 0014 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_animate +********************************************************************/ +be_local_closure(class_Leds_get_animate, /* name */ + be_nested_proto( + 2, /* nstack */ 1, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -1252,73 +1321,11 @@ be_local_closure(class_Leds_can_show, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_can_show, + &be_const_str_get_animate, &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x580C0006, // 0001 LDCONST R3 K6 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_bri -********************************************************************/ -be_local_closure(class_Leds_set_bri, /* name */ - be_nested_proto( - 3, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_set_bri, - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0x14080305, // 0000 LT R2 R1 K5 - 0x780A0000, // 0001 JMPF R2 #0003 - 0x58040005, // 0002 LDCONST R1 K5 - 0x540A00FE, // 0003 LDINT R2 255 - 0x24080202, // 0004 GT R2 R1 R2 - 0x780A0000, // 0005 JMPF R2 #0007 - 0x540600FE, // 0006 LDINT R1 255 - 0x90020201, // 0007 SETMBR R0 K1 R1 - 0x80000000, // 0008 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: set_gamma -********************************************************************/ -be_local_closure(class_Leds_set_gamma, /* name */ - be_nested_proto( - 4, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_set_gamma, - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x60080017, // 0000 GETGBL R2 G23 - 0x5C0C0200, // 0001 MOVE R3 R1 - 0x7C080200, // 0002 CALL R2 1 - 0x90020E02, // 0003 SETMBR R0 K7 R2 - 0x80000000, // 0004 RET 0 + ( &(const binstruction[ 2]) { /* code */ + 0x8804010D, // 0000 GETMBR R1 R0 K13 + 0x80040200, // 0001 RET 1 R1 }) ) ); @@ -1342,8 +1349,8 @@ be_local_closure(class_Leds_show, /* name */ &be_const_str_show, &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x580C0008, // 0001 LDCONST R3 K8 + 0x8C040109, // 0000 GETMET R1 R0 K9 + 0x580C000E, // 0001 LDCONST R3 K14 0x7C040400, // 0002 CALL R1 2 0x80000000, // 0003 RET 0 }) @@ -1353,12 +1360,12 @@ be_local_closure(class_Leds_show, /* name */ /******************************************************************** -** Solidified function: ctor +** Solidified function: set_pixel_color ********************************************************************/ -be_local_closure(class_Leds_ctor, /* name */ +be_local_closure(class_Leds_set_pixel_color, /* name */ be_nested_proto( 12, /* nstack */ - 5, /* argc */ + 4, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1366,28 +1373,78 @@ be_local_closure(class_Leds_ctor, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_ctor, + &be_const_str_set_pixel_color, &be_const_str_solidified, - ( &(const binstruction[19]) { /* code */ - 0x4C140000, // 0000 LDNIL R5 - 0x1C140405, // 0001 EQ R5 R2 R5 - 0x78160003, // 0002 JMPF R5 #0007 - 0x8C140100, // 0003 GETMET R5 R0 K0 - 0x581C0005, // 0004 LDCONST R7 K5 - 0x7C140400, // 0005 CALL R5 2 - 0x7002000A, // 0006 JMP #0012 - 0x4C140000, // 0007 LDNIL R5 - 0x1C140605, // 0008 EQ R5 R3 R5 - 0x78160000, // 0009 JMPF R5 #000B - 0x880C0109, // 000A GETMBR R3 R0 K9 - 0x8C140100, // 000B GETMET R5 R0 K0 - 0x581C0005, // 000C LDCONST R7 K5 - 0x5C200200, // 000D MOVE R8 R1 - 0x5C240400, // 000E MOVE R9 R2 - 0x5C280600, // 000F MOVE R10 R3 - 0x5C2C0800, // 0010 MOVE R11 R4 - 0x7C140C00, // 0011 CALL R5 6 - 0x80000000, // 0012 RET 0 + ( &(const binstruction[13]) { /* code */ + 0x4C100000, // 0000 LDNIL R4 + 0x1C100604, // 0001 EQ R4 R3 R4 + 0x78120000, // 0002 JMPF R4 #0004 + 0x880C010F, // 0003 GETMBR R3 R0 K15 + 0x8C100109, // 0004 GETMET R4 R0 K9 + 0x541A0009, // 0005 LDINT R6 10 + 0x5C1C0200, // 0006 MOVE R7 R1 + 0x8C200110, // 0007 GETMET R8 R0 K16 + 0x5C280400, // 0008 MOVE R10 R2 + 0x5C2C0600, // 0009 MOVE R11 R3 + 0x7C200600, // 000A CALL R8 3 + 0x7C100800, // 000B CALL R4 4 + 0x80000000, // 000C RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: is_dirty +********************************************************************/ +be_local_closure(class_Leds_is_dirty, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_is_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040109, // 0000 GETMET R1 R0 K9 + 0x540E0003, // 0001 LDINT R3 4 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: clear +********************************************************************/ +be_local_closure(class_Leds_clear, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_clear, + &be_const_str_solidified, + ( &(const binstruction[ 6]) { /* code */ + 0x8C040111, // 0000 GETMET R1 R0 K17 + 0x580C0001, // 0001 LDCONST R3 K1 + 0x7C040400, // 0002 CALL R1 2 + 0x8C040112, // 0003 GETMET R1 R0 K18 + 0x7C040200, // 0004 CALL R1 1 + 0x80000000, // 0005 RET 0 }) ) ); @@ -1411,7 +1468,7 @@ be_local_closure(class_Leds_pixel_size, /* name */ &be_const_str_pixel_size, &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 + 0x8C040109, // 0000 GETMET R1 R0 K9 0x540E0006, // 0001 LDINT R3 7 0x7C040400, // 0002 CALL R1 2 0x80040200, // 0003 RET 1 R1 @@ -1422,9 +1479,9 @@ be_local_closure(class_Leds_pixel_size, /* name */ /******************************************************************** -** Solidified function: dirty +** Solidified function: pixel_count ********************************************************************/ -be_local_closure(class_Leds_dirty, /* name */ +be_local_closure(class_Leds_pixel_count, /* name */ be_nested_proto( 4, /* nstack */ 1, /* argc */ @@ -1435,11 +1492,71 @@ be_local_closure(class_Leds_dirty, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_dirty, + &be_const_str_pixel_count, &be_const_str_solidified, ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x540E0004, // 0001 LDINT R3 5 + 0x8C040109, // 0000 GETMET R1 R0 K9 + 0x540E0007, // 0001 LDINT R3 8 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: to_gamma +********************************************************************/ +be_local_closure(class_Leds_to_gamma, /* name */ + be_nested_proto( + 8, /* nstack */ + 3, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_to_gamma, + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x4C0C0000, // 0000 LDNIL R3 + 0x1C0C0403, // 0001 EQ R3 R2 R3 + 0x780E0000, // 0002 JMPF R3 #0004 + 0x8808010F, // 0003 GETMBR R2 R0 K15 + 0x8C0C0113, // 0004 GETMET R3 R0 K19 + 0x5C140200, // 0005 MOVE R5 R1 + 0x5C180400, // 0006 MOVE R6 R2 + 0x881C0105, // 0007 GETMBR R7 R0 K5 + 0x7C0C0800, // 0008 CALL R3 4 + 0x80040600, // 0009 RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: begin +********************************************************************/ +be_local_closure(class_Leds_begin, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_begin, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040109, // 0000 GETMET R1 R0 K9 + 0x580C0014, // 0001 LDCONST R3 K20 0x7C040400, // 0002 CALL R1 2 0x80000000, // 0003 RET 0 }) @@ -1448,83 +1565,6 @@ be_local_closure(class_Leds_dirty, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: pixel_offset -********************************************************************/ -be_local_closure(class_Leds_pixel_offset, /* name */ - be_nested_proto( - 1, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_pixel_offset, - &be_const_str_solidified, - ( &(const binstruction[ 1]) { /* code */ - 0x80060A00, // 0000 RET 1 K5 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_pixel_color -********************************************************************/ -be_local_closure(class_Leds_get_pixel_color, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_get_pixel_color, - &be_const_str_solidified, - ( &(const binstruction[ 5]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x5412000A, // 0001 LDINT R4 11 - 0x5C140200, // 0002 MOVE R5 R1 - 0x7C080600, // 0003 CALL R2 3 - 0x80040400, // 0004 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_gamma -********************************************************************/ -be_local_closure(class_Leds_get_gamma, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_get_gamma, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x88040107, // 0000 GETMBR R1 R0 K7 - 0x80040200, // 0001 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: create_matrix ********************************************************************/ @@ -1557,21 +1597,21 @@ be_local_closure(class_Leds_create_matrix, /* name */ 0x4C100000, // 000C LDNIL R4 0x1C100604, // 000D EQ R4 R3 R4 0x78120000, // 000E JMPF R4 #0010 - 0x580C0005, // 000F LDCONST R3 K5 + 0x580C0001, // 000F LDCONST R3 K1 0x08100202, // 0010 MUL R4 R1 R2 0x00100803, // 0011 ADD R4 R4 R3 - 0x8814010A, // 0012 GETMBR R5 R0 K10 + 0x88140100, // 0012 GETMBR R5 R0 K0 0x24100805, // 0013 GT R4 R4 R5 0x74120005, // 0014 JMPT R4 #001B - 0x14100505, // 0015 LT R4 R2 K5 + 0x14100501, // 0015 LT R4 R2 K1 0x74120003, // 0016 JMPT R4 #001B - 0x14100305, // 0017 LT R4 R1 K5 + 0x14100301, // 0017 LT R4 R1 K1 0x74120001, // 0018 JMPT R4 #001B - 0x14100705, // 0019 LT R4 R3 K5 + 0x14100701, // 0019 LT R4 R3 K1 0x78120000, // 001A JMPF R4 #001C - 0xB006170C, // 001B RAISE 1 K11 K12 - 0x5810000D, // 001C LDCONST R4 K13 - 0xB400000D, // 001D CLASS K13 + 0xB0060503, // 001B RAISE 1 K2 K3 + 0x58100015, // 001C LDCONST R4 K21 + 0xB4000015, // 001D CLASS K21 0x5C140800, // 001E MOVE R5 R4 0x5C180000, // 001F MOVE R6 R0 0x5C1C0200, // 0020 MOVE R7 R1 @@ -1585,6 +1625,142 @@ be_local_closure(class_Leds_create_matrix, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: dirty +********************************************************************/ +be_local_closure(class_Leds_dirty, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_dirty, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040109, // 0000 GETMET R1 R0 K9 + 0x540E0004, // 0001 LDINT R3 5 + 0x7C040400, // 0002 CALL R1 2 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_bri +********************************************************************/ +be_local_closure(class_Leds_set_bri, /* name */ + be_nested_proto( + 3, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_set_bri, + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0x14080301, // 0000 LT R2 R1 K1 + 0x780A0000, // 0001 JMPF R2 #0003 + 0x58040001, // 0002 LDCONST R1 K1 + 0x540A00FE, // 0003 LDINT R2 255 + 0x24080202, // 0004 GT R2 R1 R2 + 0x780A0000, // 0005 JMPF R2 #0007 + 0x540600FE, // 0006 LDINT R1 255 + 0x90021E01, // 0007 SETMBR R0 K15 R1 + 0x80000000, // 0008 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: can_show +********************************************************************/ +be_local_closure(class_Leds_can_show, /* name */ + be_nested_proto( + 4, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_can_show, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x8C040109, // 0000 GETMET R1 R0 K9 + 0x580C0016, // 0001 LDCONST R3 K22 + 0x7C040400, // 0002 CALL R1 2 + 0x80040200, // 0003 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_animate +********************************************************************/ +be_local_closure(class_Leds_set_animate, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_set_animate, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90021A01, // 0000 SETMBR R0 K13 R1 + 0x80000000, // 0001 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_bri +********************************************************************/ +be_local_closure(class_Leds_get_bri, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_get_bri, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x8804010F, // 0000 GETMBR R1 R0 K15 + 0x80040200, // 0001 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: clear_to ********************************************************************/ @@ -1605,16 +1781,16 @@ be_local_closure(class_Leds_clear_to, /* name */ 0x4C140000, // 0000 LDNIL R5 0x1C140405, // 0001 EQ R5 R2 R5 0x78160000, // 0002 JMPF R5 #0004 - 0x88080101, // 0003 GETMBR R2 R0 K1 + 0x8808010F, // 0003 GETMBR R2 R0 K15 0x4C140000, // 0004 LDNIL R5 0x20140605, // 0005 NE R5 R3 R5 0x7816000C, // 0006 JMPF R5 #0014 0x4C140000, // 0007 LDNIL R5 0x20140805, // 0008 NE R5 R4 R5 0x78160009, // 0009 JMPF R5 #0014 - 0x8C140100, // 000A GETMET R5 R0 K0 + 0x8C140109, // 000A GETMET R5 R0 K9 0x541E0008, // 000B LDINT R7 9 - 0x8C20010E, // 000C GETMET R8 R0 K14 + 0x8C200110, // 000C GETMET R8 R0 K16 0x5C280200, // 000D MOVE R10 R1 0x5C2C0400, // 000E MOVE R11 R2 0x7C200600, // 000F CALL R8 3 @@ -1622,9 +1798,9 @@ be_local_closure(class_Leds_clear_to, /* name */ 0x5C280800, // 0011 MOVE R10 R4 0x7C140A00, // 0012 CALL R5 5 0x70020006, // 0013 JMP #001B - 0x8C140100, // 0014 GETMET R5 R0 K0 + 0x8C140109, // 0014 GETMET R5 R0 K9 0x541E0008, // 0015 LDINT R7 9 - 0x8C20010E, // 0016 GETMET R8 R0 K14 + 0x8C200110, // 0016 GETMET R8 R0 K16 0x5C280200, // 0017 MOVE R10 R1 0x5C2C0400, // 0018 MOVE R11 R2 0x7C200600, // 0019 CALL R8 3 @@ -1637,12 +1813,12 @@ be_local_closure(class_Leds_clear_to, /* name */ /******************************************************************** -** Solidified function: create_segment +** Solidified function: pixel_offset ********************************************************************/ -be_local_closure(class_Leds_create_segment, /* name */ +be_local_closure(class_Leds_pixel_offset, /* name */ be_nested_proto( - 8, /* nstack */ - 3, /* argc */ + 1, /* nstack */ + 1, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1650,32 +1826,10 @@ be_local_closure(class_Leds_create_segment, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_create_segment, + &be_const_str_pixel_offset, &be_const_str_solidified, - ( &(const binstruction[23]) { /* code */ - 0x600C0009, // 0000 GETGBL R3 G9 - 0x5C100200, // 0001 MOVE R4 R1 - 0x7C0C0200, // 0002 CALL R3 1 - 0x60100009, // 0003 GETGBL R4 G9 - 0x5C140400, // 0004 MOVE R5 R2 - 0x7C100200, // 0005 CALL R4 1 - 0x000C0604, // 0006 ADD R3 R3 R4 - 0x8810010A, // 0007 GETMBR R4 R0 K10 - 0x240C0604, // 0008 GT R3 R3 R4 - 0x740E0003, // 0009 JMPT R3 #000E - 0x140C0305, // 000A LT R3 R1 K5 - 0x740E0001, // 000B JMPT R3 #000E - 0x140C0505, // 000C LT R3 R2 K5 - 0x780E0000, // 000D JMPF R3 #000F - 0xB006170C, // 000E RAISE 1 K11 K12 - 0x580C000F, // 000F LDCONST R3 K15 - 0xB400000F, // 0010 CLASS K15 - 0x5C100600, // 0011 MOVE R4 R3 - 0x5C140000, // 0012 MOVE R5 R0 - 0x5C180200, // 0013 MOVE R6 R1 - 0x5C1C0400, // 0014 MOVE R7 R2 - 0x7C100600, // 0015 CALL R4 3 - 0x80040800, // 0016 RET 1 R4 + ( &(const binstruction[ 1]) { /* code */ + 0x80060200, // 0000 RET 1 K1 }) ) ); @@ -1683,12 +1837,12 @@ be_local_closure(class_Leds_create_segment, /* name */ /******************************************************************** -** Solidified function: set_pixel_color +** Solidified function: get_pixel_color ********************************************************************/ -be_local_closure(class_Leds_set_pixel_color, /* name */ +be_local_closure(class_Leds_get_pixel_color, /* name */ be_nested_proto( - 12, /* nstack */ - 4, /* argc */ + 6, /* nstack */ + 2, /* argc */ 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ @@ -1696,22 +1850,14 @@ be_local_closure(class_Leds_set_pixel_color, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_set_pixel_color, + &be_const_str_get_pixel_color, &be_const_str_solidified, - ( &(const binstruction[13]) { /* code */ - 0x4C100000, // 0000 LDNIL R4 - 0x1C100604, // 0001 EQ R4 R3 R4 - 0x78120000, // 0002 JMPF R4 #0004 - 0x880C0101, // 0003 GETMBR R3 R0 K1 - 0x8C100100, // 0004 GETMET R4 R0 K0 - 0x541A0009, // 0005 LDINT R6 10 - 0x5C1C0200, // 0006 MOVE R7 R1 - 0x8C20010E, // 0007 GETMET R8 R0 K14 - 0x5C280400, // 0008 MOVE R10 R2 - 0x5C2C0600, // 0009 MOVE R11 R3 - 0x7C200600, // 000A CALL R8 3 - 0x7C100800, // 000B CALL R4 4 - 0x80000000, // 000C RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x8C080109, // 0000 GETMET R2 R0 K9 + 0x5412000A, // 0001 LDINT R4 11 + 0x5C140200, // 0002 MOVE R5 R1 + 0x7C080600, // 0003 CALL R2 3 + 0x80040400, // 0004 RET 1 R2 }) ) ); @@ -1734,50 +1880,97 @@ be_local_closure(class_Leds_init, /* name */ &be_ktab_class_Leds, /* shared constants */ &be_const_str_init, &be_const_str_solidified, - ( &(const binstruction[43]) { /* code */ - 0xA4162000, // 0000 IMPORT R5 K16 + ( &(const binstruction[90]) { /* code */ + 0xA4162E00, // 0000 IMPORT R5 K23 0x50180200, // 0001 LDBOOL R6 1 0 - 0x90020E06, // 0002 SETMBR R0 K7 R6 + 0x90020A06, // 0002 SETMBR R0 K5 R6 0x4C180000, // 0003 LDNIL R6 - 0x1C180406, // 0004 EQ R6 R2 R6 - 0x741A0005, // 0005 JMPT R6 #000C - 0x8C180B11, // 0006 GETMET R6 R5 K17 - 0x88200B12, // 0007 GETMBR R8 R5 K18 - 0x58240005, // 0008 LDCONST R9 K5 - 0x7C180600, // 0009 CALL R6 3 - 0x1C180406, // 000A EQ R6 R2 R6 - 0x781A000A, // 000B JMPF R6 #0017 - 0x8C180113, // 000C GETMET R6 R0 K19 - 0x7C180200, // 000D CALL R6 1 - 0x8C180114, // 000E GETMET R6 R0 K20 - 0x7C180200, // 000F CALL R6 1 - 0x90021406, // 0010 SETMBR R0 K10 R6 - 0xA41A2A00, // 0011 IMPORT R6 K21 - 0x8C1C0D16, // 0012 GETMET R7 R6 K22 - 0x7C1C0200, // 0013 CALL R7 1 - 0x941C0F01, // 0014 GETIDX R7 R7 K1 - 0x90020207, // 0015 SETMBR R0 K1 R7 - 0x7002000B, // 0016 JMP #0023 - 0x60180009, // 0017 GETGBL R6 G9 - 0x5C1C0200, // 0018 MOVE R7 R1 - 0x7C180200, // 0019 CALL R6 1 - 0x90021406, // 001A SETMBR R0 K10 R6 - 0x541A007E, // 001B LDINT R6 127 - 0x90020206, // 001C SETMBR R0 K1 R6 - 0x8C180113, // 001D GETMET R6 R0 K19 - 0x8820010A, // 001E GETMBR R8 R0 K10 - 0x5C240400, // 001F MOVE R9 R2 - 0x5C280600, // 0020 MOVE R10 R3 - 0x5C2C0800, // 0021 MOVE R11 R4 - 0x7C180A00, // 0022 CALL R6 5 - 0x88180117, // 0023 GETMBR R6 R0 K23 - 0x4C1C0000, // 0024 LDNIL R7 - 0x1C180C07, // 0025 EQ R6 R6 R7 - 0x781A0000, // 0026 JMPF R6 #0028 - 0xB0063119, // 0027 RAISE 1 K24 K25 - 0x8C18011A, // 0028 GETMET R6 R0 K26 - 0x7C180200, // 0029 CALL R6 1 - 0x80000000, // 002A RET 0 + 0x1C180206, // 0004 EQ R6 R1 R6 + 0x741A0008, // 0005 JMPT R6 #000F + 0x4C180000, // 0006 LDNIL R6 + 0x1C180406, // 0007 EQ R6 R2 R6 + 0x741A0005, // 0008 JMPT R6 #000F + 0x8C180B18, // 0009 GETMET R6 R5 K24 + 0x88200B19, // 000A GETMBR R8 R5 K25 + 0x58240001, // 000B LDCONST R9 K1 + 0x7C180600, // 000C CALL R6 3 + 0x1C180406, // 000D EQ R6 R2 R6 + 0x781A000A, // 000E JMPF R6 #001A + 0x8C18011A, // 000F GETMET R6 R0 K26 + 0x7C180200, // 0010 CALL R6 1 + 0x8C18010B, // 0011 GETMET R6 R0 K11 + 0x7C180200, // 0012 CALL R6 1 + 0x90020006, // 0013 SETMBR R0 K0 R6 + 0xA41A3600, // 0014 IMPORT R6 K27 + 0x8C1C0D1C, // 0015 GETMET R7 R6 K28 + 0x7C1C0200, // 0016 CALL R7 1 + 0x941C0F0F, // 0017 GETIDX R7 R7 K15 + 0x90021E07, // 0018 SETMBR R0 K15 R7 + 0x70020039, // 0019 JMP #0054 + 0x60180009, // 001A GETGBL R6 G9 + 0x5C1C0200, // 001B MOVE R7 R1 + 0x7C180200, // 001C CALL R6 1 + 0x5C040C00, // 001D MOVE R1 R6 + 0x90020001, // 001E SETMBR R0 K0 R1 + 0x541A007E, // 001F LDINT R6 127 + 0x90021E06, // 0020 SETMBR R0 K15 R6 + 0xB81A3A00, // 0021 GETNGBL R6 K29 + 0x8C180D1E, // 0022 GETMET R6 R6 K30 + 0x5820001F, // 0023 LDCONST R8 K31 + 0x7C180400, // 0024 CALL R6 2 + 0x741A0003, // 0025 JMPT R6 #002A + 0xB81A3A00, // 0026 GETNGBL R6 K29 + 0x601C0013, // 0027 GETGBL R7 G19 + 0x7C1C0000, // 0028 CALL R7 0 + 0x901A3E07, // 0029 SETMBR R6 K31 R7 + 0xB81A3A00, // 002A GETNGBL R6 K29 + 0x88180D1F, // 002B GETMBR R6 R6 K31 + 0x8C180D20, // 002C GETMET R6 R6 K32 + 0x5C200200, // 002D MOVE R8 R1 + 0x7C180400, // 002E CALL R6 2 + 0x4C1C0000, // 002F LDNIL R7 + 0x20180C07, // 0030 NE R6 R6 R7 + 0x781A0016, // 0031 JMPF R6 #0049 + 0xB81A3A00, // 0032 GETNGBL R6 K29 + 0x88180D1F, // 0033 GETMBR R6 R6 K31 + 0x8C180D20, // 0034 GETMET R6 R6 K32 + 0x5C200200, // 0035 MOVE R8 R1 + 0x7C180400, // 0036 CALL R6 2 + 0x881C0100, // 0037 GETMBR R7 R0 K0 + 0x88200D00, // 0038 GETMBR R8 R6 K0 + 0x201C0E08, // 0039 NE R7 R7 R8 + 0x781E0005, // 003A JMPF R7 #0041 + 0x601C0018, // 003B GETGBL R7 G24 + 0x58200021, // 003C LDCONST R8 K33 + 0x88240100, // 003D GETMBR R9 R0 K0 + 0x88280D00, // 003E GETMBR R10 R6 K0 + 0x7C1C0600, // 003F CALL R7 3 + 0xB0060407, // 0040 RAISE 1 K2 R7 + 0x881C0D22, // 0041 GETMBR R7 R6 K34 + 0x90024407, // 0042 SETMBR R0 K34 R7 + 0x881C0D0D, // 0043 GETMBR R7 R6 K13 + 0x90021A07, // 0044 SETMBR R0 K13 R7 + 0xB81E3A00, // 0045 GETNGBL R7 K29 + 0x881C0F1F, // 0046 GETMBR R7 R7 K31 + 0x981C0200, // 0047 SETIDX R7 R1 R0 + 0x7002000A, // 0048 JMP #0054 + 0x8C18011A, // 0049 GETMET R6 R0 K26 + 0x5C200200, // 004A MOVE R8 R1 + 0x5C240400, // 004B MOVE R9 R2 + 0x5C280600, // 004C MOVE R10 R3 + 0x5C2C0800, // 004D MOVE R11 R4 + 0x7C180A00, // 004E CALL R6 5 + 0xB81A3A00, // 004F GETNGBL R6 K29 + 0x88180D1F, // 0050 GETMBR R6 R6 K31 + 0x98180200, // 0051 SETIDX R6 R1 R0 + 0x8C180123, // 0052 GETMET R6 R0 K35 + 0x7C180200, // 0053 CALL R6 1 + 0x88180122, // 0054 GETMBR R6 R0 K34 + 0x4C1C0000, // 0055 LDNIL R7 + 0x1C180C07, // 0056 EQ R6 R6 R7 + 0x781A0000, // 0057 JMPF R6 #0059 + 0xB0064925, // 0058 RAISE 1 K36 K37 + 0x80000000, // 0059 RET 0 }) ) ); @@ -1785,127 +1978,53 @@ be_local_closure(class_Leds_init, /* name */ /******************************************************************** -** Solidified function: clear +** Solidified function: ctor ********************************************************************/ -be_local_closure(class_Leds_clear, /* name */ +be_local_closure(class_Leds_ctor, /* name */ + be_nested_proto( + 12, /* nstack */ + 5, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_Leds, /* shared constants */ + &be_const_str_ctor, + &be_const_str_solidified, + ( &(const binstruction[19]) { /* code */ + 0x4C140000, // 0000 LDNIL R5 + 0x1C140405, // 0001 EQ R5 R2 R5 + 0x78160003, // 0002 JMPF R5 #0007 + 0x8C140109, // 0003 GETMET R5 R0 K9 + 0x581C0001, // 0004 LDCONST R7 K1 + 0x7C140400, // 0005 CALL R5 2 + 0x7002000A, // 0006 JMP #0012 + 0x4C140000, // 0007 LDNIL R5 + 0x1C140605, // 0008 EQ R5 R3 R5 + 0x78160000, // 0009 JMPF R5 #000B + 0x880C0126, // 000A GETMBR R3 R0 K38 + 0x8C140109, // 000B GETMET R5 R0 K9 + 0x581C0001, // 000C LDCONST R7 K1 + 0x5C200200, // 000D MOVE R8 R1 + 0x5C240400, // 000E MOVE R9 R2 + 0x5C280600, // 000F MOVE R10 R3 + 0x5C2C0800, // 0010 MOVE R11 R4 + 0x7C140C00, // 0011 CALL R5 6 + 0x80000000, // 0012 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_gamma +********************************************************************/ +be_local_closure(class_Leds_set_gamma, /* name */ be_nested_proto( 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_clear, - &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0x8C04011B, // 0000 GETMET R1 R0 K27 - 0x580C0005, // 0001 LDCONST R3 K5 - 0x7C040400, // 0002 CALL R1 2 - 0x8C04011C, // 0003 GETMET R1 R0 K28 - 0x7C040200, // 0004 CALL R1 1 - 0x80000000, // 0005 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: begin -********************************************************************/ -be_local_closure(class_Leds_begin, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_begin, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x580C001D, // 0001 LDCONST R3 K29 - 0x7C040400, // 0002 CALL R1 2 - 0x80000000, // 0003 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixel_count -********************************************************************/ -be_local_closure(class_Leds_pixel_count, /* name */ - be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_pixel_count, - &be_const_str_solidified, - ( &(const binstruction[ 4]) { /* code */ - 0x8C040100, // 0000 GETMET R1 R0 K0 - 0x540E0007, // 0001 LDINT R3 8 - 0x7C040400, // 0002 CALL R1 2 - 0x80040200, // 0003 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: to_gamma -********************************************************************/ -be_local_closure(class_Leds_to_gamma, /* name */ - be_nested_proto( - 8, /* nstack */ - 3, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_Leds, /* shared constants */ - &be_const_str_to_gamma, - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x4C0C0000, // 0000 LDNIL R3 - 0x1C0C0403, // 0001 EQ R3 R2 R3 - 0x780E0000, // 0002 JMPF R3 #0004 - 0x88080101, // 0003 GETMBR R2 R0 K1 - 0x8C0C011E, // 0004 GETMET R3 R0 K30 - 0x5C140200, // 0005 MOVE R5 R1 - 0x5C180400, // 0006 MOVE R6 R2 - 0x881C0107, // 0007 GETMBR R7 R0 K7 - 0x7C0C0800, // 0008 CALL R3 4 - 0x80040600, // 0009 RET 1 R3 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: pixels_buffer -********************************************************************/ -be_local_closure(class_Leds_pixels_buffer, /* name */ - be_nested_proto( - 8, /* nstack */ 2, /* argc */ 10, /* varg */ 0, /* has upvals */ @@ -1914,30 +2033,14 @@ be_local_closure(class_Leds_pixels_buffer, /* name */ NULL, /* no sub protos */ 1, /* has constants */ &be_ktab_class_Leds, /* shared constants */ - &be_const_str_pixels_buffer, + &be_const_str_set_gamma, &be_const_str_solidified, - ( &(const binstruction[21]) { /* code */ - 0x8C080100, // 0000 GETMET R2 R0 K0 - 0x54120005, // 0001 LDINT R4 6 - 0x7C080400, // 0002 CALL R2 2 - 0x4C0C0000, // 0003 LDNIL R3 - 0x1C0C0203, // 0004 EQ R3 R1 R3 - 0x780E0009, // 0005 JMPF R3 #0010 - 0x600C0015, // 0006 GETGBL R3 G21 - 0x5C100400, // 0007 MOVE R4 R2 - 0x8C14011F, // 0008 GETMET R5 R0 K31 - 0x7C140200, // 0009 CALL R5 1 - 0x8C180114, // 000A GETMET R6 R0 K20 - 0x7C180200, // 000B CALL R6 1 - 0x08140A06, // 000C MUL R5 R5 R6 - 0x7C0C0400, // 000D CALL R3 2 - 0x80040600, // 000E RET 1 R3 - 0x70020003, // 000F JMP #0014 - 0x8C0C0320, // 0010 GETMET R3 R1 K32 - 0x5C140400, // 0011 MOVE R5 R2 - 0x7C0C0400, // 0012 CALL R3 2 - 0x80040200, // 0013 RET 1 R1 - 0x80000000, // 0014 RET 0 + ( &(const binstruction[ 5]) { /* code */ + 0x60080017, // 0000 GETGBL R2 G23 + 0x5C0C0200, // 0001 MOVE R3 R1 + 0x7C080200, // 0002 CALL R2 1 + 0x90020A02, // 0003 SETMBR R0 K5 R2 + 0x80000000, // 0004 RET 0 }) ) ); @@ -1949,36 +2052,39 @@ be_local_closure(class_Leds_pixels_buffer, /* name */ ********************************************************************/ extern const bclass be_class_Leds_ntv; be_local_class(Leds, - 3, + 4, &be_class_Leds_ntv, - be_nested_map(26, + be_nested_map(29, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(is_dirty, -1), be_const_closure(class_Leds_is_dirty_closure) }, { be_const_key(pixels_buffer, -1), be_const_closure(class_Leds_pixels_buffer_closure) }, - { be_const_key(to_gamma, -1), be_const_closure(class_Leds_to_gamma_closure) }, - { be_const_key(can_show, -1), be_const_closure(class_Leds_can_show_closure) }, - { be_const_key(pixel_offset, -1), be_const_closure(class_Leds_pixel_offset_closure) }, - { be_const_key(set_bri, 24), be_const_closure(class_Leds_set_bri_closure) }, - { be_const_key(show, 2), be_const_closure(class_Leds_show_closure) }, - { be_const_key(ctor, -1), be_const_closure(class_Leds_ctor_closure) }, - { be_const_key(begin, 22), be_const_closure(class_Leds_begin_closure) }, - { be_const_key(leds, -1), be_const_var(1) }, - { be_const_key(set_pixel_color, -1), be_const_closure(class_Leds_set_pixel_color_closure) }, - { be_const_key(dirty, 4), be_const_closure(class_Leds_dirty_closure) }, - { be_const_key(get_pixel_color, -1), be_const_closure(class_Leds_get_pixel_color_closure) }, - { be_const_key(get_gamma, -1), be_const_closure(class_Leds_get_gamma_closure) }, - { be_const_key(gamma, -1), be_const_var(0) }, - { be_const_key(create_matrix, -1), be_const_closure(class_Leds_create_matrix_closure) }, - { be_const_key(matrix, 8), be_const_static_closure(class_Leds_matrix_closure) }, - { be_const_key(create_segment, -1), be_const_closure(class_Leds_create_segment_closure) }, - { be_const_key(bri, 10), be_const_var(2) }, - { be_const_key(init, -1), be_const_closure(class_Leds_init_closure) }, + { be_const_key(get_gamma, 26), be_const_closure(class_Leds_get_gamma_closure) }, { be_const_key(clear, -1), be_const_closure(class_Leds_clear_closure) }, - { be_const_key(get_bri, 9), be_const_closure(class_Leds_get_bri_closure) }, + { be_const_key(matrix, 13), be_const_static_closure(class_Leds_matrix_closure) }, + { be_const_key(init, 23), be_const_closure(class_Leds_init_closure) }, + { be_const_key(get_animate, -1), be_const_closure(class_Leds_get_animate_closure) }, + { be_const_key(get_pixel_color, 12), be_const_closure(class_Leds_get_pixel_color_closure) }, + { be_const_key(set_pixel_color, -1), be_const_closure(class_Leds_set_pixel_color_closure) }, + { be_const_key(animate, -1), be_const_var(3) }, + { be_const_key(is_dirty, -1), be_const_closure(class_Leds_is_dirty_closure) }, + { be_const_key(create_segment, 4), be_const_closure(class_Leds_create_segment_closure) }, + { be_const_key(pixel_offset, -1), be_const_closure(class_Leds_pixel_offset_closure) }, { be_const_key(clear_to, -1), be_const_closure(class_Leds_clear_to_closure) }, + { be_const_key(begin, 0), be_const_closure(class_Leds_begin_closure) }, + { be_const_key(set_animate, -1), be_const_closure(class_Leds_set_animate_closure) }, + { be_const_key(can_show, 24), be_const_closure(class_Leds_can_show_closure) }, + { be_const_key(create_matrix, -1), be_const_closure(class_Leds_create_matrix_closure) }, + { be_const_key(dirty, -1), be_const_closure(class_Leds_dirty_closure) }, + { be_const_key(set_bri, -1), be_const_closure(class_Leds_set_bri_closure) }, + { be_const_key(leds, 15), be_const_var(1) }, + { be_const_key(gamma, -1), be_const_var(0) }, + { be_const_key(bri, 14), be_const_var(2) }, + { be_const_key(get_bri, 11), be_const_closure(class_Leds_get_bri_closure) }, + { be_const_key(to_gamma, 2), be_const_closure(class_Leds_to_gamma_closure) }, { be_const_key(pixel_count, -1), be_const_closure(class_Leds_pixel_count_closure) }, + { be_const_key(show, 6), be_const_closure(class_Leds_show_closure) }, + { be_const_key(pixel_size, -1), be_const_closure(class_Leds_pixel_size_closure) }, + { be_const_key(ctor, -1), be_const_closure(class_Leds_ctor_closure) }, { be_const_key(set_gamma, -1), be_const_closure(class_Leds_set_gamma_closure) }, - { be_const_key(pixel_size, 1), be_const_closure(class_Leds_pixel_size_closure) }, })), (bstring*) &be_const_str_Leds ); diff --git a/pio-tools/solidify-from-url.py b/pio-tools/solidify-from-url.py index 5a8d68ad6..c5c2fd4bf 100644 --- a/pio-tools/solidify-from-url.py +++ b/pio-tools/solidify-from-url.py @@ -53,7 +53,7 @@ def addEntryToModtab(source): is_module = False - pattern = (r'''(?<=module\()[^"].*''') # module?? + pattern = (r'''(?<=module\([\"\']).*[\"\']''') # module?? result = re.findall(pattern,code) if len(result) > 0: class_name = result[0].replace("'","").replace('"','').replace(")","") diff --git a/tasmota/displaydesc/ST7701_480x480_WS_4inch.ini b/tasmota/displaydesc/ST7701_480x480_WS_4inch.ini new file mode 100644 index 000000000..a60d9380f --- /dev/null +++ b/tasmota/displaydesc/ST7701_480x480_WS_4inch.ini @@ -0,0 +1,68 @@ +:H,ST7701,480,480,16,RGB,40,39,38,41,-1,5,45,48,47,21,14,13,12,11,10,9,46,3,8,18,17,6 +:V,1,10,8,50,1,10,8,20,0 +:S,2,1,1,0,40,20 +:IS,2,1,42,-1 +11,80 +FF,5,77,01,00,00,10 +C0,2,3B,00 +C1,2,0D,02 +C2,2,21,08 +CD,1,08 +B0,10,00,11,18,0E,11,06,07,08,07,22,04,12,0F,AA,31,18 +B1,10,00,11,19,0E,12,07,08,08,08,22,04,11,11,A9,32,18 +FF,5,77,01,00,00,11 +B0,1,60 +B1,1,30 +B2,1,87 +B3,1,80 +B5,1,49 +B7,1,85 +B8,1,21 +C1,1,78 +C2,1,78,20 +E0,3,00,1B,02 +E1,B,08,A0,00,00,07,A0,00,00,00,44,44 +E2,C,11,11,44,44,ED,A0,00,00,EC,A0,00,00 +E3,4,00,00,11,11 +E4,2,44,44 +E5,10,0A,E9,D8,A0,0C,EB,D8,A0,0E,ED,D8,A0,10,EF,D8,A0 +E6,4,00,00,11,11 +E7,2,44,44 +E8,10,09,E8,D8,A0,0B,EA,D8,A0,0D,EC,D8,A0,0F,EE,D8,A0 +EB,7,02,00,E4,E4,88,00,40 +EC,2,3C,00 +ED,10,AB,89,76,54,02,FF,FF,FF,FF,FF,FF,20,45,67,98,BA +FF,5,77,01,00,00,00 +36,1,04 +3A,1,66 +21,80 +29,0 +:B,100,02 +:UTI,GT911,I1,5d,-1,-1 +RDWM 8140 4 +MV 0 1 +CPR 39 +RTF +MV 1 1 +CPR 31 +RTF +MV 2 1 +CPR 31 +RTF +RT +:UTT +RDW 814E +MV 0 1 +AND 80 +CPR 80 +RTF +RDWM 8150 8 +WRW 814E 00 +RT +:UTX +MV 0 3 +RT +:UTY +MV 2 3 +RT +# diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index 48d6d20ff..bfff6c971 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -968,8 +968,8 @@ const char HTTP_SNS_F_VOLTAGE[] PROGMEM = "{s}%s " D_VOLTAGE "{ const char HTTP_SNS_F_CURRENT[] PROGMEM = "{s}%s " D_CURRENT "{m}%*_f " D_UNIT_AMPERE "{e}"; const char HTTP_SNS_F_CURRENT_MA[] PROGMEM = "{s}%s " D_CURRENT "{m}%*_f " D_UNIT_MILLIAMPERE "{e}"; const char HTTP_SNS_F_DISTANCE_CM[] PROGMEM = "{s}%s " D_DISTANCE "{m}%1_f " D_UNIT_CENTIMETER "{e}"; -const char HTTP_SNS_F_NOX[] PROGMEM = "{s}%s " D_NOX "{m}%*_f " "{e}"; -const char HTTP_SNS_F_VOC[] PROGMEM = "{s}%s " D_VOC "{m}%*_f " "{e}"; +const char HTTP_SNS_F_NOX[] PROGMEM = "{s}%s " D_NOX "{m}%*_f" "{e}"; +const char HTTP_SNS_F_VOC[] PROGMEM = "{s}%s " D_VOC "{m}%*_f" "{e}"; const char HTTP_SNS_F_ABS_HUM[] PROGMEM = "{s}%s " D_ABSOLUTE_HUMIDITY "{m}%*_f " D_UNIT_GRAM_PER_CUBIC_METER "{e}"; const char HTTP_SNS_HUM[] PROGMEM = "{s}%s " D_HUMIDITY "{m}%s " D_UNIT_PERCENT "{e}"; @@ -987,17 +987,17 @@ const char HTTP_SNS_MOISTURE[] PROGMEM = "{s}%s " D_MOISTURE "{ const char HTTP_SNS_RANGE_CHR[] PROGMEM = "{s}%s " D_RANGE "{m}%s" "{e}"; const char HTTP_SNS_RANGE[] PROGMEM = "{s}%s " D_RANGE "{m}%d" "{e}"; const char HTTP_SNS_HALL_EFFECT[] PROGMEM = "{s}%s " D_HALL_EFFECT "{m}%d" "{e}"; -const char HTTP_SNS_PH[] PROGMEM = "{s}%s " D_PH "{m}%s " "{e}"; -const char HTTP_SNS_MQ[] PROGMEM = "{s}" D_MQ"-%s" "{m}%s " D_UNIT_PARTS_PER_MILLION "{e}"; +const char HTTP_SNS_PH[] PROGMEM = "{s}%s " D_PH "{m}%s" "{e}"; +const char HTTP_SNS_MQ[] PROGMEM = "{s}" D_MQ "-%s" "{m}%s " D_UNIT_PARTS_PER_MILLION "{e}"; const char HTTP_SNS_ORP[] PROGMEM = "{s}%s " D_ORP "{m}%s " D_UNIT_MILLIVOLT "{e}"; const char HTTP_SNS_EC[] PROGMEM = "{s}%s " D_EC "{m}%s " D_UNIT_MICROSIEMENS_PER_CM "{e}"; const char HTTP_SNS_O2[] PROGMEM = "{s}%s " D_O2 "{m}%s " D_UNIT_PERCENT "{e}"; const char HTTP_SNS_LITERS[] PROGMEM = "{s}%s " D_VOLUME "{m}%s " D_UNIT_LITERS "{e}"; const char HTTP_SNS_LPM[] PROGMEM = "{s}%s " D_FLOW_RATE "{m}%s " D_UNIT_LITERS_PER_MIN "{e}"; const char HTTP_SNS_DO[] PROGMEM = "{s}%s " D_DO "{m}%s " D_UNIT_MILIGRAMS_PER_LITER "{e}"; -const char HTTP_SNS_COLOR_RED[] PROGMEM = "{s}%s " D_COLOR_RED "{m}%u " "{e}"; -const char HTTP_SNS_COLOR_GREEN[] PROGMEM = "{s}%s " D_COLOR_GREEN "{m}%u " "{e}"; -const char HTTP_SNS_COLOR_BLUE[] PROGMEM = "{s}%s " D_COLOR_BLUE "{m}%u " "{e}"; +const char HTTP_SNS_COLOR_RED[] PROGMEM = "{s}%s " D_COLOR_RED "{m}%u" "{e}"; +const char HTTP_SNS_COLOR_GREEN[] PROGMEM = "{s}%s " D_COLOR_GREEN "{m}%u" "{e}"; +const char HTTP_SNS_COLOR_BLUE[] PROGMEM = "{s}%s " D_COLOR_BLUE "{m}%u" "{e}"; const char HTTP_SNS_MILLILITERS[] PROGMEM = "{s}%s " D_VOLUME "{m}%s " D_UNIT_MILLILITERS "{e}"; const char HTTP_SNS_GAS[] PROGMEM = "{s}%s " D_GAS "{m}%d " D_UNIT_PERCENT "LEL{e}"; const char HTTP_SNS_SOC[] PROGMEM = "{s}%s " D_SOC "{m}%d " D_UNIT_PERCENT "{e}"; @@ -1022,7 +1022,7 @@ const char HTTP_SNS_MAX_POWER[] PROGMEM = "{s}" D_MAX_POWER const char HTTP_SNS_POWER_TOTAL[] PROGMEM = "{s}" D_POWERUSAGE_ACTIVE_TOTAL "{m}%s " D_UNIT_WATT "{e}"; const char HTTP_SNS_POWERUSAGE_APPARENT[] PROGMEM = "{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}"; const char HTTP_SNS_POWERUSAGE_REACTIVE[] PROGMEM = "{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}"; -const char HTTP_SNS_POWER_FACTOR[] PROGMEM = "{s}" D_POWER_FACTOR "{m}%s {e}"; +const char HTTP_SNS_POWER_FACTOR[] PROGMEM = "{s}" D_POWER_FACTOR "{m}%s" "{e}"; const char HTTP_SNS_ENERGY_TODAY[] PROGMEM = "{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; const char HTTP_SNS_ENERGY_YESTERDAY[] PROGMEM = "{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; const char HTTP_SNS_ENERGY_TOTAL[] PROGMEM = "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 59eee7c69..4c0eac0dd 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -22,6 +22,6 @@ #define TASMOTA_SHA_SHORT // Filled by Github sed -const uint32_t TASMOTA_VERSION = 0x0E040000; // 14.4.0.0 +const uint32_t TASMOTA_VERSION = 0x0E040100; // 14.4.1.0 #endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index b2873e8df..12a1ec8f9 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -211,7 +211,7 @@ #define COLOR_TIMER_TAB_TEXT "#fff" // [WebColor17] Config timer tab text color - White #define COLOR_TIMER_TAB_BACKGROUND "#999" // [WebColor18] Config timer tab background color - Dark gray #define COLOR_TITLE_TEXT "#000" // [WebColor19] Title text color - Whiteish -#define COLOR_BUTTON_OFF "#08405e" // [WebColor20] Button color when off - Darkest blueish +#define COLOR_BUTTON_OFF "#a1d9f7" // [WebColor20] Button color when off - Light blue */ // Dark theme // WebColor {"WebColor":["#eaeaea","#252525","#4f4f4f","#000","#ddd","#65c115","#1f1f1f","#ff5661","#008000","#faffff","#1fa3ec","#0e70a4","#d43535","#931f1f","#47c266","#5aaf6f","#faffff","#999","#eaeaea","#08405e"]} @@ -234,7 +234,7 @@ #define COLOR_TIMER_TAB_TEXT "#faffff" // [WebColor17] Config timer tab text color - Very pale (mostly white) cyan. #define COLOR_TIMER_TAB_BACKGROUND "#999" // [WebColor18] Config timer tab background color - Dark gray #define COLOR_TITLE_TEXT "#eaeaea" // [WebColor19] Title text color - Very light gray -#define COLOR_BUTTON_OFF "#08405e" // [WebColor20] Button color when off - Darkest blueish +#define COLOR_BUTTON_OFF "#08405e" // [WebColor20] Button color when off - Darkest blueish // -- KNX ----------------------------------------- #define KNX_ENABLED false // [Knx_Enabled] Enable KNX protocol diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index e0b92a731..db4e9540c 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -484,6 +484,8 @@ ESP8266WebServer *Webserver; struct WEB { String chunk_buffer = ""; // Could be max 2 * CHUNKED_BUFFER_SIZE uint32_t upload_size = 0; + uint32_t light_shutter_button_mask; + uint32_t buttons_non_light_non_shutter; uint32_t slider_update_time = 0; int slider[LST_MAX]; int8_t shutter_slider[16]; // MAX_SHUTTERS_ESP32 @@ -1257,33 +1259,37 @@ int32_t IsShutterWebButton(uint32_t idx) { /*-------------------------------------------------------------------------------------------*/ -void WebGetDeviceCounts(uint32_t &buttons_non_light, uint32_t &buttons_non_light_non_shutter, uint32_t &shutter_button_mask) { - buttons_non_light = TasmotaGlobal.devices_present; +void WebGetDeviceCounts(void) { + Web.buttons_non_light_non_shutter = TasmotaGlobal.devices_present; + Web.light_shutter_button_mask = 0; // Bitmask for each light and/or shutter button #ifdef USE_LIGHT // Chk for reduced toggle buttons used by lights if (TasmotaGlobal.light_type) { - // Find and skip light buttons (Lights are controlled by the last TasmotaGlobal.devices_present (or 2)) - buttons_non_light = LightDevice() -1; + // Find and skip light buttons + uint32_t light_device = LightDevice(); + uint32_t light_devices = LightDevices(); + for (uint32_t button_idx = light_device; button_idx < (light_device + light_devices); button_idx++) { + Web.buttons_non_light_non_shutter--; + Web.light_shutter_button_mask |= (1 << (button_idx -1)); // Set button bit in bitmask + } } #endif // USE_LIGHT - buttons_non_light_non_shutter = buttons_non_light; - shutter_button_mask = 0; // Bitmask for each button #ifdef USE_SHUTTER // Chk for reduced toggle buttons used by shutters - // Find and skip dedicated shutter buttons - if (buttons_non_light && Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support - for (uint32_t button_idx = 1; button_idx <= buttons_non_light; button_idx++) { + if (Settings->flag3.shutter_mode) { // SetOption80 - Enable shutter support + // Find and skip dedicated shutter buttons + for (uint32_t button_idx = 1; button_idx <= TasmotaGlobal.devices_present; button_idx++) { if (IsShutterWebButton(button_idx) != 0) { - buttons_non_light_non_shutter--; - shutter_button_mask |= (1 << (button_idx -1)); // Set button bit in bitmask + Web.buttons_non_light_non_shutter--; + Web.light_shutter_button_mask |= (1 << (button_idx -1)); // Set button bit in bitmask } } } #endif // USE_SHUTTER -// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HTP: DP %d, BNL %d, BNLNS %d, SB %08X"), TasmotaGlobal.devices_present, buttons_non_light, buttons_non_light_non_shutter, shutter_button); +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("HTP: DP %d, BNLNS %d, SB %08X"), TasmotaGlobal.devices_present, Web.buttons_non_light_non_shutter, Web.light_shutter_button_mask); } #ifdef USE_LIGHT @@ -1366,13 +1372,10 @@ void HandleRoot(void) { #ifndef FIRMWARE_MINIMAL if (TasmotaGlobal.devices_present) { - uint32_t buttons_non_light; - uint32_t buttons_non_light_non_shutter; - uint32_t shutter_button_mask; - WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button_mask); - uint32_t button_idx = 1; + WebGetDeviceCounts(); - if (buttons_non_light_non_shutter) { // Any non light AND non shutter button - Show toggle buttons + uint32_t button_idx = 1; + if (Web.buttons_non_light_non_shutter) { // Any non light AND non shutter button - Show toggle buttons WSContentSend_P(HTTP_TABLE100); // "" WSContentSend_P(PSTR("")); @@ -1391,18 +1394,14 @@ void HandleRoot(void) { #endif // USE_SONOFF_IFAN const uint32_t max_columns = 8; - uint32_t rows = buttons_non_light_non_shutter / max_columns; - if (buttons_non_light_non_shutter % max_columns) { rows++; } - uint32_t cols = buttons_non_light_non_shutter / rows; - if (buttons_non_light_non_shutter % rows) { cols++; } + uint32_t rows = Web.buttons_non_light_non_shutter / max_columns; + if (Web.buttons_non_light_non_shutter % max_columns) { rows++; } + uint32_t cols = Web.buttons_non_light_non_shutter / rows; + if (Web.buttons_non_light_non_shutter % rows) { cols++; } uint32_t button_ptr = 0; - for (button_idx = 1; button_idx <= buttons_non_light; button_idx++) { - -#ifdef USE_SHUTTER - if (bitRead(shutter_button_mask, button_idx -1)) { continue; } // Skip non-sequential shutter button -#endif // USE_SHUTTER - + for (button_idx = 1; button_idx <= TasmotaGlobal.devices_present; button_idx++) { + if (bitRead(Web.light_shutter_button_mask, button_idx -1)) { continue; } // Skip non-sequential light and/or shutter button bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), button_idx); WSContentSend_P(HTTP_DEVICE_CONTROL, 100 / cols, button_idx, button_idx, @@ -1451,20 +1450,20 @@ void HandleRoot(void) { WSContentSend_P(PSTR("")); } WSContentSend_P(PSTR("
")); - - if (1 == button_idx) { // No power/display button - button_idx = shutter_button_idx +2; - } } #endif // USE_SHUTTER #ifdef USE_LIGHT if (TasmotaGlobal.light_type) { // Any light - Show light button and slider(s) + uint32_t light_device = LightDevice(); + uint32_t light_devices = LightDevices(); + button_idx = light_device; + WSContentSend_P(HTTP_TABLE100); // "" uint8_t light_subtype = TasmotaGlobal.light_type &7; if (!Settings->flag3.pwm_multi_channels) { // SetOption68 0 - Enable multi-channels PWM instead of Color PWM - bool split_white = ((LST_RGBW <= light_subtype) && (TasmotaGlobal.devices_present > 1) && (Settings->param[P_RGB_REMAP] & 128)); // Only on RGBW or RGBCW and SetOption37 128 + bool split_white = ((LST_RGBW <= light_subtype) && (light_devices > 1) && (Settings->param[P_RGB_REMAP] & 128)); // Only on RGBW or RGBCW and SetOption37 128 if ((LST_COLDWARM == light_subtype) || ((LST_RGBCW == light_subtype) && !split_white)) { WebSliderColdWarm(); @@ -1538,7 +1537,7 @@ void HandleRoot(void) { uint32_t width = 100; WSContentSend_P(PSTR("")); - if (button_idx <= TasmotaGlobal.devices_present) { + if (button_idx < (light_device + light_devices)) { bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); char first[2]; snprintf_P(first, sizeof(first), PSTR("%s"), PSTR(D_BUTTON_TOGGLE)); @@ -1564,9 +1563,8 @@ void HandleRoot(void) { WSContentSend_P(PSTR("")); } } else { // Settings->flag3.pwm_multi_channels - SetOption68 1 - Enable multi-channels PWM instead of Color PWM - uint32_t pwm_channels = TasmotaGlobal.devices_present - buttons_non_light; - stemp[0] = 'e'; stemp[1] = '0'; stemp[2] = '\0'; // d0 - for (uint32_t i = 0; i < pwm_channels; i++) { + stemp[0] = 'e'; stemp[1] = '0'; stemp[2] = '\0'; // e0 + for (uint32_t i = 0; i < light_devices; i++) { bool set_button = ((button_idx <= MAX_BUTTON_TEXT) && strlen(GetWebButton(button_idx -1))); char first[2]; snprintf_P(first, sizeof(first), PSTR("%s"), PSTR(D_BUTTON_TOGGLE)); @@ -1686,7 +1684,7 @@ bool HandleRootStatusRefresh(void) { char svalue[32]; // Command and number parameter char webindex[5]; // WebGetArg name - WebGetArg(PSTR("o"), tmp, sizeof(tmp)); // 1 - 16 Device number for button Toggle or Fanspeed + WebGetArg(PSTR("o"), tmp, sizeof(tmp)); // 1 - 32 Device number for button Toggle or Fanspeed if (strlen(tmp)) { ShowWebSource(SRC_WEBGUI); uint32_t device = atoi(tmp); @@ -1726,9 +1724,9 @@ bool HandleRootStatusRefresh(void) { snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_WHITE " %s"), tmp); ExecuteWebCommand(svalue); } - uint32_t light_device = LightDevice(); // Channel number offset - uint32_t pwm_channels = (TasmotaGlobal.light_type & 7) > LST_MAX ? LST_MAX : (TasmotaGlobal.light_type & 7); - for (uint32_t j = 0; j < pwm_channels; j++) { + uint32_t light_device = LightDevice(); // Channel number offset + uint32_t light_devices = LightDevices(); // Number of channels + for (uint32_t j = 0; j < light_devices; j++) { snprintf_P(webindex, sizeof(webindex), PSTR("e%d"), j +1); WebGetArg(webindex, tmp, sizeof(tmp)); // 0 - 100 percent if (strlen(tmp)) { @@ -1902,21 +1900,12 @@ bool HandleRootStatusRefresh(void) { } else { #endif // USE_SONOFF_IFAN - uint32_t buttons_non_light; - uint32_t buttons_non_light_non_shutter; - uint32_t shutter_button_mask; - WebGetDeviceCounts(buttons_non_light, buttons_non_light_non_shutter, shutter_button_mask); - - if (buttons_non_light_non_shutter <= 8) { // Any non light AND non shutter button + if (Web.buttons_non_light_non_shutter <= 8) { // Any non light AND non shutter button WSContentSend_P(PSTR("{t}")); - uint32_t cols = buttons_non_light_non_shutter; + uint32_t cols = Web.buttons_non_light_non_shutter; uint32_t fontsize = (cols < 5) ? 70 - (cols * 8) : 32; - for (uint32_t idx = 1; idx <= buttons_non_light; idx++) { - -#ifdef USE_SHUTTER - if (bitRead(shutter_button_mask, idx -1)) { continue; } // Skip non-sequential shutter button -#endif // USE_SHUTTER - + for (uint32_t idx = 1; idx <= Web.buttons_non_light_non_shutter; idx++) { + if (bitRead(Web.light_shutter_button_mask, idx -1)) { continue; } // Skip non-sequential shutter button snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(TasmotaGlobal.power, idx -1)); WSContentSend_P(HTTP_DEVICE_STATE, 100 / cols, (bitRead(TasmotaGlobal.power, idx -1)) ? PSTR("bold") : PSTR("normal"), fontsize, (cols < 5) ? GetStateText(bitRead(TasmotaGlobal.power, idx -1)) : svalue); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino index cb8e081b4..638b5bb6d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_04_light.ino @@ -236,6 +236,7 @@ struct LIGHT { uint8_t random = 0; uint8_t subtype = 0; // LST_ subtype uint8_t device = 0; + uint8_t devices = 0; uint8_t old_power = 1; uint8_t wakeup_active = 0; // 0=inctive, 1=on-going, 2=about to start, 3=will be triggered next cycle uint8_t fixed_color_index = 1; @@ -294,10 +295,7 @@ uint8_t LightDevice(void) } uint32_t LightDevices(void) { - if (0 == Light.device) { - return 0; - } - return TasmotaGlobal.devices_present - Light.device +1; // Make external + return Light.devices; // Make external } static uint32_t min3(uint32_t a, uint32_t b, uint32_t c) { @@ -1256,6 +1254,8 @@ void LightInit(void) Light.fade_initialized = true; // consider fade intialized starting from black } + Light.devices = TasmotaGlobal.devices_present - Light.device +1; // Last time that devices_present is not increments by display + LightUpdateColorMapping(); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino index d43b93aaf..dae5cfd95 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_10_rules.ino @@ -1687,14 +1687,19 @@ float evaluateExpression(const char * expression, unsigned int len) { while (index < operators_size) { if (priority == pgm_read_byte(kExpressionOperatorsPriorities + operators[index])) { // Need to calculate the operator first // Get current object value and remove the next object with current operator + +// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: index %d, v1 '%4_f', v2 '%4_f', op %d"), index, &object_values[index], &object_values[index + 1], operators[index]); + va = calculateTwoValues(object_values[index], object_values[index + 1], operators[index]); uint32_t i = index; while (i <= operators_size) { - operators[i++] = operators[i]; // operators.remove(index) +// operators[i++] = operators[i]; // operators.remove(index) - Fails on ESP32 (#22636) + operators[i] = operators[i +1]; // operators.remove(index) + i++; object_values[i] = object_values[i +1]; // object_values.remove(index + 1) } operators_size--; - object_values[index] = va; // Replace the current value with the result + object_values[index] = va; // Replace the current value with the result // AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Intermediate '%4_f'"), &object_values[index]); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino index 8096c4eaf..9d2381a61 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_13_display.ino @@ -270,7 +270,7 @@ bool disp_subscribed = false; /*********************************************************************************************/ uint32_t DisplayDevices(void) { - return (disp_device); + return (disp_device) ? 1 : 0; } /*********************************************************************************************/ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino index ab5c9246a..555f4c44d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_leds.ino @@ -76,20 +76,8 @@ extern "C" { be_getmember(vm, 1, "_p"); void * strip = (void*) be_tocomptr(vm, -1); be_pop(vm, 1); - if (strip == nullptr) { - be_raise(vm, "internal_error", "tasmotaled object not initialized"); - } return strip; } - int32_t be_get_leds_type(bvm *vm) { - be_getmember(vm, 1, "_t"); - int32_t type = be_toint(vm, -1); - be_pop(vm, 1); - if (type < 0) { - be_raise(vm, "internal_error", "invalid leds type"); - } - return type; - } int be_tasmotaled_call_native(bvm *vm); int be_tasmotaled_call_native(bvm *vm) { @@ -119,7 +107,6 @@ extern "C" { // if GPIO is '-1' led_type = 0; Ws2812InitStrip(); // ensure the tasmotaled object is initialized, because Berry code runs before the driver is initialized - // strip = Ws2812GetStrip(); TODO } else { if (led_type < 1) { led_type = 1; } TasmotaLEDPusher * pusher = TasmotaLEDPusher::Create(hardware, gpio); @@ -130,29 +117,20 @@ extern "C" { strip->SetPusher(pusher); } - // AddLog(LOG_LEVEL_DEBUG, "LED: leds %i gpio %i type %i", leds, gpio, led_type); - // store type in attribute `_t` - be_pushint(vm, led_type); - be_setmember(vm, 1, "_t"); - be_pop(vm, 1); - be_pushcomptr(vm, (void*) strip); // if native driver, it is NULL be_setmember(vm, 1, "_p"); be_pop(vm, 1); be_pushnil(vm); } else { // all other commands need a valid tasmotaled pointer - int32_t leds_type = be_get_leds_type(vm); TasmotaLED * strip = (TasmotaLED*) be_get_tasmotaled(vm); // raises an exception if pointer is invalid - // detect native driver - bool native = (leds_type == 0); - + // detect native driver means strip == nullptr be_pushnil(vm); // push a default `nil` return value switch (cmd) { case 1: // # 01 : begin void -> void - if (native) Ws2812Begin(); - else if (strip) strip->Begin(); + if (strip) strip->Begin(); + else Ws2812Begin(); break; case 2: // # 02 : show void -> void { @@ -176,43 +154,40 @@ extern "C" { } uint32_t pixels_size; // number of bytes to push bool update_completed = false; - if (native) { + if (strip) { + strip->Show(); + pixels_size = strip->PixelCount() * strip->PixelSize(); + update_completed = strip->CanShow(); + } else { Ws2812Show(); pixels_size = Ws2812PixelsSize(); update_completed =Ws2812CanShow(); } - else if (strip) { - strip->Show(); - pixels_size = strip->PixelCount() * strip->PixelSize(); - update_completed = strip->CanShow(); - } } break; case 3: // # 03 : CanShow void -> bool - if (native) be_pushbool(vm, Ws2812CanShow()); - else if (strip) be_pushbool(vm, strip->CanShow()); + if (strip) be_pushbool(vm, strip->CanShow()); + else be_pushbool(vm, Ws2812CanShow()); break; case 4: // # 04 : IsDirty void -> bool - if (native) be_pushbool(vm, Ws2812IsDirty()); - else if (strip) be_pushbool(vm, strip->IsDirty()); + if (strip) be_pushbool(vm, strip->IsDirty()); + else be_pushbool(vm, Ws2812IsDirty()); break; case 5: // # 05 : Dirty void -> void - if (native) Ws2812Dirty(); - else if (strip) strip->Dirty(); + if (strip) strip->Dirty(); + else Ws2812Dirty(); break; case 6: // # 06 : Pixels void -> bytes() (mapped to the buffer) - { - if (native) be_pushcomptr(vm, Ws2812Pixels()); - else if (strip) be_pushcomptr(vm, strip->Pixels()); - } + if (strip) be_pushcomptr(vm, strip->Pixels()); + else be_pushcomptr(vm, Ws2812Pixels()); break; case 7: // # 07 : PixelSize void -> int - if (native) be_pushint(vm, Ws2812PixelSize()); - else if (strip) be_pushint(vm, strip->PixelSize()); + if (strip) be_pushint(vm, strip->PixelSize()); + else be_pushint(vm, Ws2812PixelSize()); break; case 8: // # 08 : PixelCount void -> int - if (native) be_pushint(vm, Ws2812PixelCount()); - else if (strip) be_pushint(vm, strip->PixelCount()); + if (strip) be_pushint(vm, strip->PixelCount()); + else be_pushint(vm, Ws2812PixelCount()); break; case 9: // # 09 : ClearTo (color:??) -> void { @@ -227,11 +202,11 @@ extern "C" { if (from < 0) { from = 0; } if (len < 0) { len = 0; } - if (native) Ws2812ClearTo(r, g, b, w, from, from + len - 1); - else if (strip) strip->ClearTo(rgbw, from, from + len - 1); + if (strip) strip->ClearTo(rgbw, from, from + len - 1); + else Ws2812ClearTo(r, g, b, w, from, from + len - 1); } else { - if (native) Ws2812ClearTo(r, g, b, w, -1, -1); - else if (strip) strip->ClearTo(rgbw); + if (strip) strip->ClearTo(rgbw); + else Ws2812ClearTo(r, g, b, w, -1, -1); } } break; @@ -239,24 +214,24 @@ extern "C" { { int32_t idx = be_toint(vm, 3); uint32_t wrgb = be_toint(vm, 4); - if (native) { + if (strip) { + strip->SetPixelColor(idx, wrgb); + } else { uint8_t w = (wrgb >> 24) & 0xFF; uint8_t r = (wrgb >> 16) & 0xFF; uint8_t g = (wrgb >> 8) & 0xFF; uint8_t b = (wrgb ) & 0xFF; Ws2812SetPixelColor(idx, r, g, b, w); - } else if (strip) { - strip->SetPixelColor(idx, wrgb); } } break; case 11: // # 11 : GetPixelColor (idx:int) -> color:int wrgb { int32_t idx = be_toint(vm, 3); - if (native) { - be_pushint(vm, Ws2812GetPixelColor(idx)); - } else if (strip) { + if (strip) { be_pushint(vm, strip->GetPixelColor(idx)); + } else { + be_pushint(vm, Ws2812GetPixelColor(idx)); } } break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino index 18eb8f4fa..6afa820e4 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_67_mcp23xxx.ino @@ -26,6 +26,7 @@ * Supported template fields: * NAME - Template name * BASE - Optional. 0 = use relative buttons and switches (default), 1 = use absolute buttons and switches + * IOCON - Optional. IOCON I/O Expander configuration register (bitmap: 0 MIRROR 0 DISSLW HAEN ODR INTPOL 0. Default 0b01011000 = 0x58) * GPIO - Sequential list of pin 1 and up with configured GPIO function * Function Code Description * ------------------- -------- ---------------------------------------- @@ -60,6 +61,9 @@ * * Buttons and relays B1 B2 B3 B4 B5 B6 B7 B8 R1 R2 R3 R4 R5 R6 R7 R8 * {"NAME":"MCP23017 A=B1-8, B=R1-8","GPIO":[32,33,34,35,36,37,38,39,224,225,226,227,228,229,230,231]} + * + * Buttons and relays with open-drain INT B1 B2 B3 B4 B5 B6 B7 B8 R1 R2 R3 R4 R5 R6 R7 R8 + * {"NAME":"MCP23017 A=B1-8, B=R1-8","GPIO":[32,33,34,35,36,37,38,39,224,225,226,227,228,229,230,231],"IOCON":0x5C} * * Buttons, relays, buttons and relays B1 B2 B3 B4 B5 B6 B7 B8 R1 R2 R3 R4 R5 R6 R7 R8 B9 B10B11B12B13B14B15B16R9 R10 R11 R12 R13 R14 R15 R16 * {"NAME":"MCP23017 A=B1-8, B=R1-8, C=B9-16, D=R9-16","GPIO":[32,33,34,35,36,37,38,39,224,225,226,227,228,229,230,231,40,41,42,43,44,45,46,47,232,233,234,235,236,237,238,239]} @@ -90,6 +94,8 @@ * MCP23017 support \*********************************************************************************************/ +#define D_JSON_IOCON "IOCON" + enum MCP23S08GPIORegisters { MCP23X08_IODIR = 0x00, MCP23X08_IPOL = 0x01, @@ -140,11 +146,25 @@ typedef struct { uint8_t olatb; uint8_t address; uint8_t interface; - uint8_t pins; // 8 (MCP23x08) or 16 (MCP23x17) + uint8_t pins; // 8 (MCP23x08) or 16 (MCP23x17) int8_t pin_cs; int8_t pin_int; } tMcp23xDevice; +typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... + uint8_t reg; // Allow bit manipulation using template IOCON + struct { + uint8_t spare0 : 1; // 0 Unimplemented + uint8_t INTPOL : 1; // (0) INT pin active-low. (1) active-high + uint8_t ODR : 1; // (0) INT pin active driver output. (1) Open-drain output (overrides INTPOL) + uint8_t HAEN : 1; // (1) Hardware Address enabled (MCS23S17 only) + uint8_t DISSLW : 1; // (0) SDA output slew rate disabled + uint8_t SEQOP : 1; // 0 Sequential operation enabled, address pointer increments + uint8_t MIRROR : 1; // (1) INT pins are internally connected + uint8_t BANK : 1; // 0 Registers are in the same bank (addresses are sequential) (MCS23x17 only) + }; +} tIOCON; + struct MCP230 { tMcp23xDevice device[MCP23XXX_MAX_DEVICES]; uint32_t relay_inverted; @@ -156,6 +176,7 @@ struct MCP230 { uint8_t relay_offset; uint8_t button_max; uint8_t switch_max; + tIOCON iocon; int8_t button_offset; int8_t switch_offset; bool base; @@ -339,15 +360,15 @@ void MCP23xPinMode(uint8_t pin, uint8_t flags) { } switch (flags) { case INPUT: - MCP23xUpdate(pin, true, iodir); - MCP23xUpdate(pin, false, gppu); + MCP23xUpdate(pin, true, iodir); // Pin is configured as an input + MCP23xUpdate(pin, false, gppu); // Pull-up disabled break; case INPUT_PULLUP: - MCP23xUpdate(pin, true, iodir); - MCP23xUpdate(pin, true, gppu); + MCP23xUpdate(pin, true, iodir); // Pin is configured as an input + MCP23xUpdate(pin, true, gppu); // Pull-up enabled break; case OUTPUT: - MCP23xUpdate(pin, false, iodir); + MCP23xUpdate(pin, false, iodir); // Pin is configured as an output break; } @@ -371,21 +392,21 @@ void MCP23xPinInterruptMode(uint8_t pin, uint8_t interrupt_mode) { } switch (interrupt_mode) { case MCP23XXX_CHANGE: - MCP23xUpdate(pin, true, gpinten); - MCP23xUpdate(pin, false, intcon); + MCP23xUpdate(pin, true, gpinten); // Enable GPIO input pin for interrupt-on-change event + MCP23xUpdate(pin, false, intcon); // Pin value is compared against the previous pin value break; case MCP23XXX_RISING: - MCP23xUpdate(pin, true, gpinten); - MCP23xUpdate(pin, true, intcon); - MCP23xUpdate(pin, true, defval); + MCP23xUpdate(pin, true, gpinten); // Enable GPIO input pin for interrupt-on-change event + MCP23xUpdate(pin, true, intcon); // Controls how the associated pin value is compared for interrupt-on-change + MCP23xUpdate(pin, false, defval); // If the associated pin level is the opposite from the register bit, an interrupt occurs. break; case MCP23XXX_FALLING: - MCP23xUpdate(pin, true, gpinten); - MCP23xUpdate(pin, true, intcon); - MCP23xUpdate(pin, false, defval); + MCP23xUpdate(pin, true, gpinten); // Enable GPIO input pin for interrupt-on-change event + MCP23xUpdate(pin, true, intcon); // Controls how the associated pin value is compared for interrupt-on-change + MCP23xUpdate(pin, true, defval); // If the associated pin level is the opposite from the register bit, an interrupt occurs. break; case MCP23XXX_NO_INTERRUPT: - MCP23xUpdate(pin, false, gpinten); + MCP23xUpdate(pin, false, gpinten); // Disable GPIO input pin for interrupt-on-change event break; } } @@ -394,7 +415,7 @@ void MCP23xSetPinModes(uint8_t pin, uint8_t flags) { // pin 0 - 63 MCP23xPinMode(pin, flags); if (Mcp23x.device[Mcp23x.chip].pin_int > -1) { // Mcp23x.chip is updated by call to MCP23xPinMode - MCP23xPinInterruptMode(pin, MCP23XXX_CHANGE); + MCP23xPinInterruptMode(pin, (Mcp23x.iocon.ODR) ? MCP23XXX_FALLING : MCP23XXX_CHANGE); } } @@ -457,6 +478,15 @@ uint32_t MCP23xGetPin(uint32_t lpin) { /*********************************************************************************************/ +bool MCP23xAddItem(uint8_t &item) { + if (item >= MAX_RELAYS_SET) { // MAX_RELAYS_SET = MAX_SWITCHES_SET = MAX_KEYS_SET = 32 + AddLog(LOG_LEVEL_INFO, PSTR("MCP: Max reached")); + return false; + } + item++; + return true; +} + String MCP23xTemplateLoadFile(void) { String mcptmplt = ""; #ifdef USE_UFILESYS @@ -497,7 +527,7 @@ bool MCP23xLoadTemplate(void) { } val = root[PSTR(D_JSON_NAME)]; if (val) { - AddLog(LOG_LEVEL_DEBUG, PSTR("MCP: Base %d, Template '%s'"), Mcp23x.base, val.getStr()); + AddLog(LOG_LEVEL_DEBUG, PSTR("MCP: IOCON 0x%02X, Base %d, Template '%s'"), Mcp23x.iocon, Mcp23x.base, val.getStr()); } JsonParserArray arr = root[PSTR(D_JSON_GPIO)]; if (arr) { @@ -507,44 +537,36 @@ bool MCP23xLoadTemplate(void) { if (!val) { break; } uint16_t mpin = val.getUInt(); if (mpin) { // Above GPIO_NONE - if ((mpin >= AGPIO(GPIO_SWT1)) && (mpin < (AGPIO(GPIO_SWT1) + MAX_SWITCHES_SET))) { - Mcp23x.switch_max++; + if ((mpin >= AGPIO(GPIO_SWT1)) && (mpin < (AGPIO(GPIO_SWT1) + MAX_SWITCHES_SET)) && MCP23xAddItem(Mcp23x.switch_max)) { MCP23xSetPinModes(pin, INPUT_PULLUP); } - else if ((mpin >= AGPIO(GPIO_SWT1_NP)) && (mpin < (AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES_SET))) { + else if ((mpin >= AGPIO(GPIO_SWT1_NP)) && (mpin < (AGPIO(GPIO_SWT1_NP) + MAX_SWITCHES_SET)) && MCP23xAddItem(Mcp23x.switch_max)) { mpin -= (AGPIO(GPIO_SWT1_NP) - AGPIO(GPIO_SWT1)); - Mcp23x.switch_max++; MCP23xSetPinModes(pin, INPUT); } - else if ((mpin >= AGPIO(GPIO_KEY1)) && (mpin < (AGPIO(GPIO_KEY1) + MAX_KEYS_SET))) { - Mcp23x.button_max++; + else if ((mpin >= AGPIO(GPIO_KEY1)) && (mpin < (AGPIO(GPIO_KEY1) + MAX_KEYS_SET)) && MCP23xAddItem(Mcp23x.button_max)) { MCP23xSetPinModes(pin, INPUT_PULLUP); } - else if ((mpin >= AGPIO(GPIO_KEY1_NP)) && (mpin < (AGPIO(GPIO_KEY1_NP) + MAX_KEYS_SET))) { + else if ((mpin >= AGPIO(GPIO_KEY1_NP)) && (mpin < (AGPIO(GPIO_KEY1_NP) + MAX_KEYS_SET)) && MCP23xAddItem(Mcp23x.button_max)) { mpin -= (AGPIO(GPIO_KEY1_NP) - AGPIO(GPIO_KEY1)); - Mcp23x.button_max++; MCP23xSetPinModes(pin, INPUT); } - else if ((mpin >= AGPIO(GPIO_KEY1_INV)) && (mpin < (AGPIO(GPIO_KEY1_INV) + MAX_KEYS_SET))) { + else if ((mpin >= AGPIO(GPIO_KEY1_INV)) && (mpin < (AGPIO(GPIO_KEY1_INV) + MAX_KEYS_SET)) && MCP23xAddItem(Mcp23x.button_max)) { bitSet(Mcp23x.button_inverted, mpin - AGPIO(GPIO_KEY1_INV)); mpin -= (AGPIO(GPIO_KEY1_INV) - AGPIO(GPIO_KEY1)); - Mcp23x.button_max++; MCP23xSetPinModes(pin, INPUT_PULLUP); } - else if ((mpin >= AGPIO(GPIO_KEY1_INV_NP)) && (mpin < (AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS_SET))) { + else if ((mpin >= AGPIO(GPIO_KEY1_INV_NP)) && (mpin < (AGPIO(GPIO_KEY1_INV_NP) + MAX_KEYS_SET)) && MCP23xAddItem(Mcp23x.button_max)) { bitSet(Mcp23x.button_inverted, mpin - AGPIO(GPIO_KEY1_INV_NP)); mpin -= (AGPIO(GPIO_KEY1_INV_NP) - AGPIO(GPIO_KEY1)); - Mcp23x.button_max++; MCP23xSetPinModes(pin, INPUT); } - else if ((mpin >= AGPIO(GPIO_REL1)) && (mpin < (AGPIO(GPIO_REL1) + MAX_RELAYS_SET))) { - Mcp23x.relay_max++; + else if ((mpin >= AGPIO(GPIO_REL1)) && (mpin < (AGPIO(GPIO_REL1) + MAX_RELAYS_SET)) && MCP23xAddItem(Mcp23x.relay_max)) { MCP23xPinMode(pin, OUTPUT); } - else if ((mpin >= AGPIO(GPIO_REL1_INV)) && (mpin < (AGPIO(GPIO_REL1_INV) + MAX_RELAYS_SET))) { + else if ((mpin >= AGPIO(GPIO_REL1_INV)) && (mpin < (AGPIO(GPIO_REL1_INV) + MAX_RELAYS_SET)) && MCP23xAddItem(Mcp23x.relay_max)) { bitSet(Mcp23x.relay_inverted, mpin - AGPIO(GPIO_REL1_INV)); mpin -= (AGPIO(GPIO_REL1_INV) - AGPIO(GPIO_REL1)); - Mcp23x.relay_max++; MCP23xPinMode(pin, OUTPUT); } else if (mpin == AGPIO(GPIO_OUTPUT_HI)) { @@ -558,14 +580,9 @@ bool MCP23xLoadTemplate(void) { else { mpin = 0; } Mcp23x_gpio_pin[pin] = mpin; } - if ((Mcp23x.switch_max >= MAX_SWITCHES_SET) || - (Mcp23x.button_max >= MAX_KEYS_SET) || - (Mcp23x.relay_max >= MAX_RELAYS_SET)) { - AddLog(LOG_LEVEL_INFO, PSTR("MCP: Max reached (S%d/B%d/R%d)"), Mcp23x.switch_max, Mcp23x.button_max, Mcp23x.relay_max); - break; - } } Mcp23x.max_pins = pin; // Max number of configured pins + AddLog(LOG_LEVEL_INFO, PSTR("MCP: Pins %d (S%d/B%d/R%d)"), Mcp23x.max_pins, Mcp23x.switch_max, Mcp23x.button_max, Mcp23x.relay_max); } // AddLog(LOG_LEVEL_DEBUG, PSTR("MCP: Pins %d, Mcp23x_gpio_pin %*_V"), Mcp23x.max_pins, Mcp23x.max_pins, (uint8_t*)Mcp23x_gpio_pin); @@ -582,6 +599,10 @@ uint32_t MCP23xTemplateGpio(void) { JsonParserObject root = parser.getRootObject(); if (!root) { return 0; } + JsonParserToken val = root[PSTR(D_JSON_IOCON)]; + if (val) { + Mcp23x.iocon.reg = val.getUInt() & 0x5E; // Only allow 0 MIRROR 0 DISSLW HAEN ODR INTPOL 0 + } JsonParserArray arr = root[PSTR(D_JSON_GPIO)]; if (arr.isArray()) { return arr.size(); // Number of requested pins @@ -590,6 +611,7 @@ uint32_t MCP23xTemplateGpio(void) { } void MCP23xModuleInit(void) { + Mcp23x.iocon.reg = 0b01011000; // Default 0x58 = Enable INT mirror, Disable Slew rate, HAEN pins for addressing int32_t pins_needed = MCP23xTemplateGpio(); if (!pins_needed) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MCP: Invalid template")); @@ -606,7 +628,8 @@ void MCP23xModuleInit(void) { #endif while ((Mcp23x.max_devices < MCP23XXX_MAX_DEVICES) && PinUsed(GPIO_MCP23SXX_CS, Mcp23x.max_devices)) { Mcp23x.chip = Mcp23x.max_devices; - Mcp23x.device[Mcp23x.chip].pin_int = (PinUsed(GPIO_MCP23XXX_INT, Mcp23x.chip)) ? Pin(GPIO_MCP23XXX_INT, Mcp23x.chip) : -1; + uint32_t pin_int = (Mcp23x.iocon.ODR) ? 0 : Mcp23x.chip; // INT ODR pins are open-drain outputs and supposedly connected together to one GPIO + Mcp23x.device[Mcp23x.chip].pin_int = (PinUsed(GPIO_MCP23XXX_INT, pin_int)) ? Pin(GPIO_MCP23XXX_INT, pin_int) : -1; Mcp23x.device[Mcp23x.chip].pin_cs = Pin(GPIO_MCP23SXX_CS, Mcp23x.max_devices); digitalWrite(Mcp23x.device[Mcp23x.chip].pin_cs, 1); pinMode(Mcp23x.device[Mcp23x.chip].pin_cs, OUTPUT); @@ -619,12 +642,14 @@ void MCP23xModuleInit(void) { if (0x00 == buffer) { // MCP23S08 AddLog(LOG_LEVEL_INFO, PSTR("SPI: MCP23S08 found at CS%d"), Mcp23x.chip +1); Mcp23x.device[Mcp23x.chip].pins = 8; - MCP23xWrite(MCP23X08_IOCON, 0b00011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing +// MCP23xWrite(MCP23X08_IOCON, 0b00011000); // Slew rate disabled, HAEN pins for addressing + MCP23xWrite(MCP23X08_IOCON, Mcp23x.iocon.reg & 0x3E); Mcp23x.device[Mcp23x.chip].olata = MCP23xRead(MCP23X08_OLAT); } else if (0x80 == buffer) { // MCP23S17 AddLog(LOG_LEVEL_INFO, PSTR("SPI: MCP23S17 found at CS%d"), Mcp23x.chip +1); Mcp23x.device[Mcp23x.chip].pins = 16; - MCP23xWrite(MCP23X17_IOCONA, 0b01011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing +// MCP23xWrite(MCP23X17_IOCONA, 0b01011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing + MCP23xWrite(MCP23X17_IOCONA, Mcp23x.iocon.reg); Mcp23x.device[Mcp23x.chip].olata = MCP23xRead(MCP23X17_OLATA); Mcp23x.device[Mcp23x.chip].olatb = MCP23xRead(MCP23X17_OLATB); } @@ -641,8 +666,9 @@ void MCP23xModuleInit(void) { uint8_t mcp23xxx_address = MCP23XXX_ADDR_START; while ((Mcp23x.max_devices < MCP23XXX_MAX_DEVICES) && (mcp23xxx_address < MCP23XXX_ADDR_END)) { Mcp23x.chip = Mcp23x.max_devices; + uint32_t pin_int = (Mcp23x.iocon.ODR) ? 0 : Mcp23x.chip; // INT pins are open-drain outputs and supposedly connected together to one GPIO if (I2cSetDevice(mcp23xxx_address)) { - Mcp23x.device[Mcp23x.chip].pin_int = (PinUsed(GPIO_MCP23XXX_INT, Mcp23x.chip)) ? Pin(GPIO_MCP23XXX_INT, Mcp23x.chip) : -1; + Mcp23x.device[Mcp23x.chip].pin_int = (PinUsed(GPIO_MCP23XXX_INT, pin_int)) ? Pin(GPIO_MCP23XXX_INT, pin_int) : -1; Mcp23x.device[Mcp23x.chip].interface = MCP23X_I2C; Mcp23x.device[Mcp23x.chip].address = mcp23xxx_address; @@ -652,7 +678,8 @@ void MCP23xModuleInit(void) { if (0x00 == buffer) { I2cSetActiveFound(mcp23xxx_address, "MCP23008"); Mcp23x.device[Mcp23x.chip].pins = 8; - MCP23xWrite(MCP23X08_IOCON, 0b00011000); // Slew rate disabled, HAEN pins for addressing +// MCP23xWrite(MCP23X08_IOCON, 0b00011000); // Slew rate disabled, HAEN pins for addressing + MCP23xWrite(MCP23X08_IOCON, Mcp23x.iocon.reg & 0x3E); Mcp23x.device[Mcp23x.chip].olata = MCP23xRead(MCP23X08_OLAT); Mcp23x.max_devices++; } @@ -660,7 +687,8 @@ void MCP23xModuleInit(void) { I2cSetActiveFound(mcp23xxx_address, "MCP23017"); Mcp23x.device[Mcp23x.chip].pins = 16; MCP23xWrite(MCP23X08_IOCON, 0x00); // Reset bank mode to 0 (MCP23X17_GPINTENB) - MCP23xWrite(MCP23X17_IOCONA, 0b01011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing +// MCP23xWrite(MCP23X17_IOCONA, 0b01011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing + MCP23xWrite(MCP23X17_IOCONA, Mcp23x.iocon.reg); Mcp23x.device[Mcp23x.chip].olata = MCP23xRead(MCP23X17_OLATA); Mcp23x.device[Mcp23x.chip].olatb = MCP23xRead(MCP23X17_OLATB); Mcp23x.max_devices++; @@ -691,6 +719,8 @@ void MCP23xModuleInit(void) { return; } + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MCP: INT open-drain %d"), Mcp23x.iocon.ODR); + Mcp23x.relay_offset = TasmotaGlobal.devices_present; Mcp23x.relay_max -= UpdateDevicesPresent(Mcp23x.relay_max); @@ -745,8 +775,10 @@ void MCP23xInit(void) { } else { gpio = MCP23xRead16(MCP23X17_GPIOA); // Clear MCP23x17 interrupt } + if (Mcp23x.iocon.ODR && Mcp23x.chip) { continue; } +// pinMode(Mcp23x.device[Mcp23x.chip].pin_int, (Mcp23x.iocon.ODR) ? INPUT_PULLUP : INPUT); pinMode(Mcp23x.device[Mcp23x.chip].pin_int, INPUT_PULLUP); - attachInterrupt(Mcp23x.device[Mcp23x.chip].pin_int, MCP23xInputIsr, CHANGE); + attachInterrupt(Mcp23x.device[Mcp23x.chip].pin_int, MCP23xInputIsr, (Mcp23x.iocon.ODR) ? FALLING : CHANGE); } } }