From fc513af351e43d06bc3675e0e54946896448fc55 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Wed, 20 Sep 2023 22:28:40 +0200 Subject: [PATCH] Berry counter (#19558) * Berry read and write Counters * rename counter --- CHANGELOG.md | 1 + lib/libesp32/berry_tasmota/src/be_gpio_lib.c | 6 ++ .../xdrv_52_3_berry_gpio.ino | 61 +++++++++++++++++++ .../tasmota_xsns_sensor/xsns_01_counter.ino | 34 +++++++++++ 4 files changed, 102 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad365fbc2..2ce0e92f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ### Added - Support for Shelly PlusPMMini, Plus1Mini and Plus1PMMini - Matter support for Virtual Devices controllable via Rules or Berry (#19520) +- Berry read and write Counters ### Breaking Changed diff --git a/lib/libesp32/berry_tasmota/src/be_gpio_lib.c b/lib/libesp32/berry_tasmota/src/be_gpio_lib.c index 592861b9c..e83347539 100644 --- a/lib/libesp32/berry_tasmota/src/be_gpio_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_gpio_lib.c @@ -15,6 +15,9 @@ extern int gp_pin_mode(bvm *vm); extern int gp_digital_write(bvm *vm); extern int gp_digital_read(bvm *vm); extern int gp_dac_voltage(bvm *vm); +extern int gp_counter_read(bvm *vm); +extern int gp_counter_set(bvm *vm); +extern int gp_counter_add(bvm *vm); extern int gp_pin_used(bvm *vm); extern int gp_pin(bvm *vm); @@ -31,6 +34,9 @@ module gpio (scope: global) { digital_write, func(gp_digital_write) digital_read, func(gp_digital_read) dac_voltage, func(gp_dac_voltage) + counter_read, func(gp_counter_read) + counter_set, func(gp_counter_set) + counter_add, func(gp_counter_add) pin_used, func(gp_pin_used) pin, func(gp_pin) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino index a8815f798..7e514622a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_gpio.ino @@ -241,6 +241,67 @@ extern "C" { analogWritePhase(pin, duty, hpoint); } + // gpio.counter_read(counter:int) -> int or nil + // + // Read counter value, or return nil if counter is not used + int gp_counter_read(bvm *vm); + int gp_counter_read(bvm *vm) { +#ifdef USE_COUNTER + int32_t argc = be_top(vm); // Get the number of arguments + if (argc >= 1 && be_isint(vm, 1)) { + int32_t counter = be_toint(vm, 1); + + // is `index` refering to a counter? + if (CounterPinConfigured(counter)) { + be_pushint(vm, CounterPinRead(counter)); + be_return(vm); + } else { + be_return_nil(vm); + } + } + be_raise(vm, kTypeError, nullptr); +#else + be_return_nil(vm); +#endif + } + + + int gp_counter_set_add(bvm *vm, bool add) { +#ifdef USE_COUNTER + int32_t argc = be_top(vm); // Get the number of arguments + if (argc >= 2 && be_isint(vm, 1) && be_isint(vm, 2)) { + int32_t counter = be_toint(vm, 1); + int32_t value = be_toint(vm, 2); + + // is `index` refering to a counter? + if (CounterPinConfigured(counter)) { + be_pushint(vm, CounterPinSet(counter, value, add)); + be_return(vm); + } else { + be_return_nil(vm); + } + } + be_raise(vm, kTypeError, nullptr); +#else + be_return_nil(vm); +#endif + } + + // gpio.counter_set(counter:int, value:int) -> int or nil + // + // Set the counter value, return the actual value, or return nil if counter is not used + int gp_counter_set(bvm *vm); + int gp_counter_set(bvm *vm) { + return gp_counter_set_add(vm, false); + } + + // gpio.counter_add(counter:int, value:int) -> int or nil + // + // Add to the counter value, return the actual value, or return nil if counter is not used + int gp_counter_add(bvm *vm); + int gp_counter_add(bvm *vm) { + return gp_counter_set_add(vm, true); + } } #endif // USE_BERRY diff --git a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino index 183fbb62c..245055c60 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_01_counter.ino @@ -127,6 +127,40 @@ bool CounterPinState(void) return false; } +// is this GPIO configured as a counter +// this encapsulates the logic and avoids exposing internals to Berry +bool CounterPinConfigured(int32_t counter) { + if ((counter > 0) && (counter <= MAX_COUNTERS) && (PinUsed(GPIO_CNTR1, counter - 1))) { + return true; + } else { + return false; + } +} + +// return counter value for this GPIO +// this encapsulates the logic and avoids exposing internals to Berry +uint32_t CounterPinRead(int32_t counter) { + if (CounterPinConfigured(counter)) { + return RtcSettings.pulse_counter[counter - 1]; + } + return 0; +} + +// set the value, add offset if `add` is true, return value +// this encapsulates the logic and avoids exposing internals to Berry +uint32_t CounterPinSet(int32_t counter, int32_t value, bool add) { + if (CounterPinConfigured(counter)) { + if (add) { + RtcSettings.pulse_counter[counter - 1] += value; + } else { + RtcSettings.pulse_counter[counter - 1] = value; + } + return RtcSettings.pulse_counter[counter - 1]; + } + return 0; +} + + void CounterInit(void) {