Berry counter (#19558)

* Berry read and write Counters

* rename counter
This commit is contained in:
s-hadinger 2023-09-20 22:28:40 +02:00 committed by GitHub
parent f8b5a38dc9
commit fc513af351
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 0 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)
{