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

This commit is contained in:
Pim van Pelt
2017-11-27 21:30:01 +01:00
parent 5f10481fb7
commit d07a0e053c
5 changed files with 118 additions and 0 deletions

17
include/backlight.h Normal file
View File

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

View File

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

View File

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

76
src/backlight.c Normal file
View File

@ -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_duty<backlight_target_duty)
return;
mgos_clear_timer(backlight_fader_timer_id);
backlight_fader_timer_id=0;
backlight_step=0.0;
backlight_target_duty=backlight_duty;
LOG(LL_INFO,("Backlight target reached, set at %.2f", backlight_duty));
(void) arg;
}
void backlight_set(float new_duty, int fader_msec) {
if (new_duty<0.0) backlight_target_duty=0.0;
else if (new_duty>1.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;
}

View File

@ -2,6 +2,7 @@
#include <time.h>
#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();