From 8eb6bcb11287031200a162e7407c965545cc6dc7 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Thu, 1 Nov 2018 20:29:51 +0100 Subject: [PATCH] add channel_set_duration() for timer based polls --- include/main.h | 1 + src/channel.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/main.h b/include/main.h index 5091a2b..b6c99b1 100644 --- a/include/main.h +++ b/include/main.h @@ -24,6 +24,7 @@ bool channel_init(const char *fn); uint8_t channel_gpio_by_idx(int idx); uint8_t channel_idx_by_gpio(int gpio); void channel_set(int idx, bool state); +void channel_set_duration(int idx, bool state, uint16_t seconds); bool channel_get(int idx); int channel_get_total(); void channel_handler(int gpio, void *arg); diff --git a/src/channel.c b/src/channel.c index cfb2496..0714fad 100644 --- a/src/channel.c +++ b/src/channel.c @@ -144,6 +144,28 @@ uint8_t channel_idx_by_gpio(int gpio) { return GPIO_INVALID; } +// Slightly tricky callback (installed on a timer by channel_set and +// channel_toggle carries information in the arg pointer -- top 16 bits are +// the channel idx, LSB is boolean value to set the channel to. +static void channel_set_cb(void *arg) { + uint32_t input=(uint32_t) arg; + int idx = input>>16; + int value = input & 0x1; + LOG(LL_INFO, ("Channel callback for channel %d value %d", idx, value)); + channel_set(idx, (bool)value); +} + +void channel_set_duration(int idx, bool state, uint16_t seconds) { + uint32_t val; + channel_set(idx, state); + + // Pass an argument to the channel_set_cb callback, top 16 bits is channel, + // bottom bit is what to set it to + val = idx<<16+(!state); + LOG(LL_INFO, ("Setting timer for %d seconds on channel %d with future value %d", seconds, idx, !state)); + mgos_set_timer (1000 * seconds, false /* oneshot */, channel_set_cb, (void *)val); +} + void channel_set(int idx, bool state) { double now = mg_time();