From d07a0e053ce214c6aa9a472e3f2f0478b2a72b10 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Mon, 27 Nov 2017 21:30:01 +0100 Subject: [PATCH] Backlight support. TOUCH events feed backlight_keepalive(); After a timeout, we fade the backlight to 0 using timers. When the backlight is not active, TOUCH events are not passed to widgets, but the backlight is re-enabled; Add some flags to mos.yml to drive timeout and PWM pin for the backlight on Featherwing --- include/backlight.h | 17 +++++++++ include/mongoose-touch.h | 1 + mos.yml | 5 +++ src/backlight.c | 76 ++++++++++++++++++++++++++++++++++++++++ src/main.c | 19 ++++++++++ 5 files changed, 118 insertions(+) create mode 100644 include/backlight.h create mode 100644 src/backlight.c diff --git a/include/backlight.h b/include/backlight.h new file mode 100644 index 0000000..a3d616d --- /dev/null +++ b/include/backlight.h @@ -0,0 +1,17 @@ +#ifndef __BACKLIGHT_H +#define __BACKLIGHT_H + +#include "mgos.h" +#include "mgos_pwm.h" +#include "mgos_config.h" +#include "mgos_timers.h" + +#define BACKLIGHT_PWM_HZ 10000 +#define BACKLIGHT_STEP_USEC 10000 // 10ms per step. + +void backlight_init(void); +void backlight_set(float new_duty, int fader_msec); +void backlight_keepalive(); +bool backlight_active(); + +#endif // __BACKLIGHT_H diff --git a/include/mongoose-touch.h b/include/mongoose-touch.h index 2b6a626..6434f38 100644 --- a/include/mongoose-touch.h +++ b/include/mongoose-touch.h @@ -3,6 +3,7 @@ #include "widget.h" #include "screen.h" +#include "backlight.h" void widget_time_ev(int ev, struct widget_t *w, void *ev_data); diff --git a/mos.yml b/mos.yml index 6ee9425..7ed30f5 100644 --- a/mos.yml +++ b/mos.yml @@ -33,6 +33,10 @@ config_schema: - ["app", "o", {title: "APP settings"}] - ["app.hostname", "s", {title: "Device hostname"}] - ["app.hostname", "Mongoose Touch"] + - ["app.backlight_pin", "i", {title: "Backlight pin"}] + - ["app.backlight_pin", 22] + - ["app.inactivity_timeout", "i", {title: "Inactivity timeout in seconds"}] + - ["app.inactivity_timeout", 10] # List of libraries used by this app, in order of initialisation @@ -43,6 +47,7 @@ libs: - origin: https://github.com/mongoose-os-libs/rpc-service-fs - origin: https://github.com/mongoose-os-libs/rpc-uart - origin: https://github.com/mongoose-os-libs/prometheus-metrics + - origin: https://github.com/mongoose-os-libs/pwm - origin: libs/lobo-spi - origin: libs/ili9341 - origin: libs/stmpe610 diff --git a/src/backlight.c b/src/backlight.c new file mode 100644 index 0000000..1604929 --- /dev/null +++ b/src/backlight.c @@ -0,0 +1,76 @@ +#include "backlight.h" + +static float backlight_duty; +static float backlight_target_duty; +static float backlight_step; + +static mgos_timer_id backlight_fader_timer_id = 0; +static mgos_timer_id backlight_keepalive_timer_id = 0; + +static void backlight_fader_cb(void *arg) { + float new_duty = backlight_duty+backlight_step; + + LOG(LL_DEBUG,("Set backlight from %.2f to %.2f, step %.4f, target %.2f", backlight_duty, new_duty, backlight_step, backlight_target_duty)); + backlight_duty = new_duty; + if (backlight_duty>1.0) backlight_duty=1.0; + if (backlight_duty<0.0) backlight_duty=0.0; + mgos_pwm_set(mgos_sys_config_get_app_backlight_pin(), BACKLIGHT_PWM_HZ, backlight_duty); + if (backlight_step<0 && backlight_duty>backlight_target_duty) + return; + if (backlight_step>0 && backlight_duty1.0) backlight_target_duty=1.0; + else backlight_target_duty=new_duty; + + if (backlight_target_duty == backlight_duty) + return; + + if (fader_msec == 0) { + backlight_duty=backlight_target_duty; + backlight_step=0.0; + LOG(LL_INFO, ("Setting backlight to %.2f", backlight_duty)); + mgos_pwm_set(mgos_sys_config_get_app_backlight_pin(), BACKLIGHT_PWM_HZ, backlight_duty); + return; + } + + backlight_step = (backlight_target_duty - backlight_duty) / ((1000.0*fader_msec)/BACKLIGHT_STEP_USEC); + LOG(LL_INFO, ("Changing backlight from %.2f to %.2f in %d msecs, steps of %.4f", backlight_duty, backlight_target_duty, fader_msec, backlight_step)); + if (backlight_fader_timer_id) + mgos_clear_timer(backlight_fader_timer_id); + backlight_fader_timer_id = mgos_set_timer(BACKLIGHT_STEP_USEC/1000, true, backlight_fader_cb, NULL); +} + +static void backlight_keepalive_cb(void *arg) { + LOG(LL_INFO, ("Inactivity timeout of %d seconds reached, setting backlight off", mgos_sys_config_get_app_inactivity_timeout())); + backlight_set(0.0, 1000); + (void) arg; +} + +void backlight_keepalive() { + if (backlight_keepalive_timer_id) + mgos_clear_timer(backlight_keepalive_timer_id); + backlight_keepalive_timer_id = mgos_set_timer(mgos_sys_config_get_app_inactivity_timeout()*1000, false, backlight_keepalive_cb, NULL); + backlight_set(1.0, 0); +} + +bool backlight_active() { + return (backlight_duty>0.0); +} + + +void backlight_init(void) { + backlight_keepalive(); + return; +} diff --git a/src/main.c b/src/main.c index 2f4ce50..4456873 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include #include "mgos.h" +#include "mgos_pwm.h" #include "tft.h" #include "stmpe610.h" #include "mongoose-touch.h" @@ -21,6 +22,23 @@ static void touch_handler(struct mgos_stmpe610_event_data *ed) { x = map(ed->x, 0, 4095, 0, _width-1); y = map(ed->y, 0, 4095, 0, _height-1); LOG(LL_INFO, ("Touch %s at (%d,%d) pressure=%d, length=%d", ed->direction==TOUCH_UP?"UP":"DOWN", x, y, ed->z, ed->length)); + + // If the backlight is inactive, grab the TOUCH_DOWN and TOUCH_UP events. + // Do nothing on TOUCH_DOWN, but reactivate the backlight by calling + // backlight_keepalive() upon TOUCH_UP. This way, the first touch will + // wake up the UI, but not send events to widgets and things. + if (!backlight_active()) { + if (ed->direction==TOUCH_DOWN) { + LOG(LL_INFO, ("Ignoring touch event, backlight is inactive")); + return; + } + LOG(LL_INFO, ("Ignoring touch event, but waking up")); + backlight_keepalive(); + return; + } + + backlight_keepalive(); + widget = screen_widget_find_by_xy(screen, x, y); if (ed->direction==TOUCH_DOWN) { @@ -80,6 +98,7 @@ void tft_demo(void) enum mgos_app_init_result mgos_app_init(void) { mgos_stmpe610_set_handler(touch_handler); + backlight_init(); tft_demo();