Initial commit
This commit is contained in:
61
src/main.c
Normal file
61
src/main.c
Normal file
@ -0,0 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "mgos.h"
|
||||
#include "tft.h"
|
||||
#include "stmpe610.h"
|
||||
#include "widget.h"
|
||||
|
||||
static long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
static void touch_handler(struct mgos_stmpe610_event_data *ed) {
|
||||
uint16_t x, y;
|
||||
struct widget_t *widget;
|
||||
|
||||
if (!ed) return;
|
||||
|
||||
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));
|
||||
widget = widget_find(x, y);
|
||||
|
||||
if (ed->direction==TOUCH_DOWN) {
|
||||
// mgos_ili9341_drawCircle(x, y, ed->length, ILI9341_YELLOW);
|
||||
widget_network_recv();
|
||||
if (widget)
|
||||
widget->handler(EV_WIDGET_TOUCH_DOWN, widget, NULL);
|
||||
} else {
|
||||
// mgos_ili9341_drawCircle(x, y, ed->length, ILI9341_BLUE);
|
||||
widget_network_send();
|
||||
if (widget)
|
||||
widget->handler(EV_WIDGET_TOUCH_UP, widget, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void tft_demo(void)
|
||||
{
|
||||
mgos_ili9341_setRotation(mgos_sys_config_get_tft_orientation());
|
||||
mgos_stmpe610_set_rotation(mgos_sys_config_get_tft_orientation());
|
||||
mgos_ili9341_setGammaCurve(DEFAULT_GAMMA_CURVE);
|
||||
mgos_ili9341_setFont(DEFAULT_FONT, NULL);
|
||||
|
||||
mgos_ili9341_jpg_image(CENTER, CENTER, 1, "mongoose-os.jpg", NULL, 0);
|
||||
// mgos_ili9341_jpg_image(200, 150, 2, "flower.jpg", NULL, 0);
|
||||
|
||||
widget_add(0, 0, 198, 20, 0, widget_name_ev, NULL);
|
||||
widget_add(198, 0, 22, 20, 0, widget_network_ev, NULL);
|
||||
widget_add(220, 0, 20, 20, 5000, widget_wifi_ev, NULL);
|
||||
widget_add(240, 0, 80, 20, 1000, widget_time_ev, NULL);
|
||||
widget_add(0, 21, 320, 2, 0, widget_topbar_ev, NULL);
|
||||
}
|
||||
|
||||
enum mgos_app_init_result mgos_app_init(void)
|
||||
{
|
||||
mgos_stmpe610_set_handler(touch_handler);
|
||||
|
||||
tft_demo();
|
||||
|
||||
return MGOS_APP_INIT_SUCCESS;
|
||||
}
|
89
src/widget.c
Normal file
89
src/widget.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include "mgos.h"
|
||||
#include "widget.h"
|
||||
|
||||
struct widget_list_t {
|
||||
struct widget_t *widget;
|
||||
SLIST_ENTRY(widget_list_t) entries;
|
||||
};
|
||||
|
||||
SLIST_HEAD(widget_list, widget_list_t) s_widgets;
|
||||
|
||||
static void widget_event_timer(void *arg) {
|
||||
struct widget_t *widget = (struct widget_t *) arg;
|
||||
if (!widget)
|
||||
return;
|
||||
if (widget->handler)
|
||||
widget->handler(EV_WIDGET_TIMER, widget, NULL);
|
||||
}
|
||||
|
||||
static void widget_destroy(struct widget_t *widget) {
|
||||
if (!widget)
|
||||
return;
|
||||
if (widget->handler)
|
||||
widget->handler(EV_WIDGET_DESTROY, widget, NULL);
|
||||
|
||||
if (widget->timer_msec)
|
||||
mgos_clear_timer(widget->_timer_id);
|
||||
if (widget->user_data)
|
||||
free(widget->user_data);
|
||||
free(widget);
|
||||
}
|
||||
|
||||
struct widget_t *widget_add(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t timer_msec, widget_event_fn handler, void *user_data) {
|
||||
struct widget_t *widget;
|
||||
struct widget_list_t *wl;
|
||||
|
||||
widget = (struct widget_t *) calloc(1, sizeof(*widget));
|
||||
if (!widget)
|
||||
return NULL;
|
||||
widget->x=x;
|
||||
widget->y=y;
|
||||
widget->w=w;
|
||||
widget->h=h;
|
||||
widget->timer_msec=timer_msec;
|
||||
widget->handler=handler;
|
||||
widget->user_data=user_data;
|
||||
if (timer_msec > 0)
|
||||
widget->_timer_id = mgos_set_timer(timer_msec, MGOS_TIMER_REPEAT, widget_event_timer, widget);
|
||||
|
||||
wl = (struct widget_list_t *) calloc(1, sizeof(*wl));
|
||||
if (!wl) {
|
||||
widget_destroy(widget);
|
||||
return NULL;
|
||||
}
|
||||
wl->widget = widget;
|
||||
SLIST_INSERT_HEAD(&s_widgets, wl, entries);
|
||||
|
||||
if (handler)
|
||||
handler(EV_WIDGET_CREATE, widget, NULL);
|
||||
return widget;
|
||||
}
|
||||
|
||||
struct widget_t *widget_find(uint16_t x, uint16_t y) {
|
||||
struct widget_list_t *wl;
|
||||
|
||||
SLIST_FOREACH(wl, &s_widgets, entries) {
|
||||
if (wl->widget->x < x &&
|
||||
x < (wl->widget->x+wl->widget->w) &&
|
||||
wl->widget->y < y &&
|
||||
y < (wl->widget->y+wl->widget->h))
|
||||
return wl->widget;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void widget_remove(struct widget_t *widget) {
|
||||
// struct widget_list_t *wl, *wlt;
|
||||
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
/*
|
||||
SLIST_FOREACH_SAFE(wl, &s_widgets, entries, wlt) {
|
||||
if (wl->widget == widget) {
|
||||
SLIST_REMOVE(&s_widgets, wl, widget_t, entries);
|
||||
free(wl);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
80
src/widget_name.c
Normal file
80
src/widget_name.c
Normal file
@ -0,0 +1,80 @@
|
||||
#include "mgos.h"
|
||||
#include "mgos_config.h"
|
||||
#include "mgos_wifi.h"
|
||||
#include "mgos_net.h"
|
||||
#include "tft.h"
|
||||
#include "widget.h"
|
||||
|
||||
#define WIDGET_NAME_NAME 0
|
||||
#define WIDGET_NAME_IPADDR 1
|
||||
#define WIDGET_NAME_SSID 2
|
||||
#define WIDGET_NAME_EMPTY 3
|
||||
|
||||
static uint8_t what = WIDGET_NAME_NAME;
|
||||
|
||||
static void widget_name_render(struct widget_t *w, void *ev_data) {
|
||||
char namestring[21];
|
||||
char *p = NULL;
|
||||
|
||||
|
||||
if (!w)
|
||||
return;
|
||||
switch (what) {
|
||||
case WIDGET_NAME_NAME:
|
||||
sprintf(namestring, "%-20s",mgos_sys_config_get_app_hostname());
|
||||
break;
|
||||
case WIDGET_NAME_IPADDR: {
|
||||
char ip[16];
|
||||
struct mgos_net_event_data evd = {
|
||||
.if_type = MGOS_NET_IF_TYPE_WIFI, .if_instance = 0,
|
||||
};
|
||||
|
||||
mgos_net_get_ip_info(MGOS_NET_IF_TYPE_WIFI, 0, &evd.ip_info);
|
||||
memset(ip, 0, sizeof(ip));
|
||||
mgos_net_ip_to_str(&evd.ip_info.ip, ip);
|
||||
sprintf(namestring, "%-20s",ip);
|
||||
break;
|
||||
}
|
||||
case WIDGET_NAME_SSID:
|
||||
p = mgos_wifi_get_connected_ssid();
|
||||
sprintf(namestring, "%-20s", p);
|
||||
free(p);
|
||||
break;
|
||||
case WIDGET_NAME_EMPTY:
|
||||
sprintf(namestring, "%-20s", "");
|
||||
break;
|
||||
default:
|
||||
sprintf(namestring, "%-20s",mgos_sys_config_get_app_hostname());
|
||||
}
|
||||
|
||||
mgos_ili9341_setclipwin(w->x, w->y, w->x+w->w, w->y+w->h);
|
||||
mgos_ili9341_fillRect(0, 0, w->w, w->h, ILI9341_BLACK);
|
||||
mgos_ili9341_set_fg(&ILI9341_GREEN);
|
||||
mgos_ili9341_print(namestring, 2, 4);
|
||||
mgos_ili9341_resetclipwin();
|
||||
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
void widget_name_ev(int ev, struct widget_t *w, void *ev_data) {
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
switch(ev) {
|
||||
case EV_WIDGET_CREATE:
|
||||
case EV_WIDGET_DRAW:
|
||||
case EV_WIDGET_REDRAW:
|
||||
case EV_WIDGET_TIMER:
|
||||
widget_name_render(w, ev_data);
|
||||
break;
|
||||
case EV_WIDGET_TOUCH_UP:
|
||||
what++;
|
||||
if (what > WIDGET_NAME_EMPTY) what=WIDGET_NAME_NAME;
|
||||
widget_name_render(w, ev_data);
|
||||
break;
|
||||
case EV_WIDGET_TOUCH_DOWN:
|
||||
case EV_WIDGET_DESTROY:
|
||||
default: // EV_WIDGET_NONE
|
||||
break;
|
||||
}
|
||||
}
|
64
src/widget_network.c
Normal file
64
src/widget_network.c
Normal file
@ -0,0 +1,64 @@
|
||||
#include "mgos.h"
|
||||
#include "mgos_timers.h"
|
||||
#include "tft.h"
|
||||
#include "widget.h"
|
||||
|
||||
static mgos_timer_id send_timer = 0;
|
||||
static mgos_timer_id recv_timer = 0;
|
||||
static struct widget_t *widget_network = NULL;
|
||||
|
||||
static void widget_network_render(struct widget_t *w, void *ev_data) {
|
||||
mgos_ili9341_setclipwin(w->x, w->y, w->x+w->w, w->y+w->h);
|
||||
// Send
|
||||
mgos_ili9341_fillTriangle(2, 10, 10, 10, 6, 2, send_timer?ILI9341_YELLOW:ILI9341_DARKGREY);
|
||||
mgos_ili9341_fillRect(5, 10, 3, 8, send_timer?ILI9341_YELLOW:ILI9341_DARKGREY);
|
||||
|
||||
// Recv
|
||||
mgos_ili9341_fillTriangle(12, 10, 20, 10, 16, 18, recv_timer?ILI9341_YELLOW:ILI9341_DARKGREY);
|
||||
mgos_ili9341_fillRect(15, 2, 3, 8, recv_timer?ILI9341_YELLOW:ILI9341_DARKGREY);
|
||||
mgos_ili9341_resetclipwin();
|
||||
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
static void widget_network_send_clear(void *arg) {
|
||||
send_timer=0;
|
||||
widget_network_ev(EV_WIDGET_REDRAW, widget_network, NULL);
|
||||
}
|
||||
|
||||
static void widget_network_recv_clear(void *arg) {
|
||||
recv_timer=0;
|
||||
widget_network_ev(EV_WIDGET_REDRAW, widget_network, NULL);
|
||||
}
|
||||
|
||||
void widget_network_send() {
|
||||
if (!send_timer)
|
||||
send_timer=mgos_set_timer(100, 0, widget_network_send_clear, NULL);
|
||||
widget_network_ev(EV_WIDGET_REDRAW, widget_network, NULL);
|
||||
}
|
||||
|
||||
void widget_network_recv() {
|
||||
if (!recv_timer)
|
||||
recv_timer=mgos_set_timer(100, 0, widget_network_recv_clear, NULL);
|
||||
widget_network_ev(EV_WIDGET_REDRAW, widget_network, NULL);
|
||||
}
|
||||
|
||||
void widget_network_ev(int ev, struct widget_t *w, void *ev_data) {
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
switch(ev) {
|
||||
case EV_WIDGET_CREATE:
|
||||
widget_network=w;
|
||||
case EV_WIDGET_DRAW:
|
||||
case EV_WIDGET_REDRAW:
|
||||
widget_network_render(w, ev_data);
|
||||
break;
|
||||
case EV_WIDGET_TIMER:
|
||||
case EV_WIDGET_TOUCH_UP:
|
||||
case EV_WIDGET_TOUCH_DOWN:
|
||||
case EV_WIDGET_DESTROY:
|
||||
default: // EV_WIDGET_NONE
|
||||
break;
|
||||
}
|
||||
}
|
40
src/widget_time.c
Normal file
40
src/widget_time.c
Normal file
@ -0,0 +1,40 @@
|
||||
#include "mgos.h"
|
||||
#include "tft.h"
|
||||
#include "widget.h"
|
||||
|
||||
static void widget_time_render(struct widget_t *w, void *ev_data) {
|
||||
char tmp_buff[32];
|
||||
|
||||
time_t now = 3600 + time(0); // TZ=GMT+1
|
||||
struct tm* tm_info = gmtime(&now);
|
||||
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
mgos_ili9341_set_fg(&ILI9341_YELLOW);
|
||||
sprintf(tmp_buff, " %02d:%02d:%02d", tm_info->tm_hour, tm_info->tm_min, tm_info->tm_sec);
|
||||
mgos_ili9341_setclipwin(w->x, w->y, w->x+w->w, w->y+w->h);
|
||||
mgos_ili9341_print(tmp_buff, 2, 4);
|
||||
mgos_ili9341_resetclipwin();
|
||||
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
void widget_time_ev(int ev, struct widget_t *w, void *ev_data) {
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
switch(ev) {
|
||||
case EV_WIDGET_CREATE:
|
||||
case EV_WIDGET_DRAW:
|
||||
case EV_WIDGET_REDRAW:
|
||||
case EV_WIDGET_TIMER:
|
||||
widget_time_render(w, ev_data);
|
||||
break;
|
||||
case EV_WIDGET_TOUCH_UP:
|
||||
case EV_WIDGET_TOUCH_DOWN:
|
||||
case EV_WIDGET_DESTROY:
|
||||
default: // EV_WIDGET_NONE
|
||||
break;
|
||||
}
|
||||
}
|
33
src/widget_topbar.c
Normal file
33
src/widget_topbar.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include "mgos.h"
|
||||
#include "tft.h"
|
||||
#include "widget.h"
|
||||
|
||||
static void widget_topbar_render(struct widget_t *w, void *ev_data) {
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
mgos_ili9341_setclipwin(w->x, w->y, w->x+w->w, w->y+w->h);
|
||||
mgos_ili9341_fillRect(0, 0, w->w, w->h, ILI9341_WHITE);
|
||||
mgos_ili9341_resetclipwin();
|
||||
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
void widget_topbar_ev(int ev, struct widget_t *w, void *ev_data) {
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
switch(ev) {
|
||||
case EV_WIDGET_CREATE:
|
||||
case EV_WIDGET_DRAW:
|
||||
case EV_WIDGET_REDRAW:
|
||||
case EV_WIDGET_TIMER:
|
||||
widget_topbar_render(w, ev_data);
|
||||
break;
|
||||
case EV_WIDGET_TOUCH_UP:
|
||||
case EV_WIDGET_TOUCH_DOWN:
|
||||
case EV_WIDGET_DESTROY:
|
||||
default: // EV_WIDGET_NONE
|
||||
break;
|
||||
}
|
||||
}
|
65
src/widget_wifi.c
Normal file
65
src/widget_wifi.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include "mgos.h"
|
||||
#include "tft.h"
|
||||
#include "widget.h"
|
||||
#include <esp_wifi.h>
|
||||
|
||||
static long map(long x, long in_min, long in_max, long out_min, long out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
// Returns a value between 0 and 100%
|
||||
static uint8_t widget_wifi_signal() {
|
||||
wifi_ap_record_t info;
|
||||
|
||||
if(0 != esp_wifi_sta_get_ap_info(&info))
|
||||
return 0;
|
||||
|
||||
if(info.rssi <= -100)
|
||||
return 0;
|
||||
if (info.rssi >= -50)
|
||||
return 100;
|
||||
return 2 * (info.rssi + 100);
|
||||
}
|
||||
|
||||
static void widget_wifi_render(struct widget_t *w, void *ev_data) {
|
||||
uint8_t x, signal;
|
||||
|
||||
mgos_ili9341_setclipwin(w->x, w->y, w->x+w->w, w->y+w->h);
|
||||
|
||||
mgos_ili9341_fillTriangle(2, 18, 18, 18, 18, 2, ILI9341_DARKGREY);
|
||||
|
||||
// Map signal strength from [0..100] to [0..16]
|
||||
signal = widget_wifi_signal();
|
||||
x = map(signal, 0, 100, 0, 16);
|
||||
if (x>0)
|
||||
mgos_ili9341_fillTriangle(2, 18, 2+x, 18, 2+x, 18-x, ILI9341_WHITE);
|
||||
|
||||
// Draw an X in the corner if we don't have an IP address.
|
||||
if (mgos_wifi_get_status() != MGOS_WIFI_IP_ACQUIRED) {
|
||||
mgos_ili9341_drawLine(11, 11, 16, 16, ILI9341_RED);
|
||||
mgos_ili9341_drawLine(11, 16, 16, 11, ILI9341_RED);
|
||||
}
|
||||
mgos_ili9341_resetclipwin();
|
||||
|
||||
(void) ev_data;
|
||||
}
|
||||
|
||||
void widget_wifi_ev(int ev, struct widget_t *w, void *ev_data) {
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
switch(ev) {
|
||||
case EV_WIDGET_CREATE:
|
||||
case EV_WIDGET_DRAW:
|
||||
case EV_WIDGET_REDRAW:
|
||||
case EV_WIDGET_TIMER:
|
||||
widget_wifi_render(w, ev_data);
|
||||
break;
|
||||
case EV_WIDGET_TOUCH_UP:
|
||||
case EV_WIDGET_TOUCH_DOWN:
|
||||
case EV_WIDGET_DESTROY:
|
||||
default: // EV_WIDGET_NONE
|
||||
break;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user