Compare commits
16
Commits
2.3.0-pre1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e125aec459 | ||
|
|
ee61b38026 | ||
|
|
7e4d25272a
|
||
|
|
d3130c43da
|
||
|
|
70020581fd
|
||
|
|
8cc9ae8df4
|
||
|
|
6971fe2036
|
||
|
|
9f97d5c9d1
|
||
|
|
5343d44ea8
|
||
|
|
76fbf5d65f
|
||
|
|
6b4013f779
|
||
|
|
0438f88c83
|
||
|
|
d0d7200e57
|
||
|
|
78aaa949a3
|
||
|
|
5dbb592946
|
||
|
|
d9aa0418fa
|
+3
-2
@@ -16,8 +16,9 @@ esphttpdconfig.mk
|
||||
|
||||
# Garbage added by CLion
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
cmake-build-debug*/
|
||||
.sass-cache
|
||||
|
||||
*.map
|
||||
.gitignore
|
||||
!.gitignore
|
||||
|
||||
|
||||
+1
-1
Submodule front-end updated: 445d78d4e1...9aae724df2
+2
-2
@@ -18,8 +18,8 @@ if [ -z ${ESPTOOL} ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -z ESPPORT ] && ESPPORT=/dev/ttyUSB0
|
||||
[ -z ESPBAUD ] && ESPBAUD=460800
|
||||
[ -z ${ESPPORT} ] && ESPPORT=/dev/ttyUSB0
|
||||
[ -z ${ESPBAUD} ] && ESPBAUD=460800
|
||||
|
||||
set -x
|
||||
${ESPTOOL} --port ${ESPPORT} --baud ${ESPBAUD} \
|
||||
|
||||
@@ -44,6 +44,10 @@ handle_espterm_osc(int n0, int n1, char *buffer)
|
||||
// Button message
|
||||
screen_set_button_message(n1, buffer);
|
||||
}
|
||||
else if (n0 == 30) {
|
||||
// Button color
|
||||
screen_set_button_color(n1, buffer);
|
||||
}
|
||||
else goto bad;
|
||||
return;
|
||||
|
||||
|
||||
+18
-6
@@ -94,21 +94,33 @@ apars_handle_space_cmd(char c)
|
||||
void ICACHE_FLASH_ATTR apars_handle_hash_cmd(char c)
|
||||
{
|
||||
switch(c) {
|
||||
case '1': // Double height, single width, top half (CUSTOM!)
|
||||
screen_set_line_attr(1, 2, 1);
|
||||
break;
|
||||
case '2': // Double height, single width, bottom half (CUSTOM!)
|
||||
screen_set_line_attr(1, 1, 2);
|
||||
break;
|
||||
case '3': // Double size, top half
|
||||
case '4': // Single size, bottom half
|
||||
screen_set_line_attr(2, 2, 1);
|
||||
break;
|
||||
case '4': // Double size, bottom half
|
||||
screen_set_line_attr(2, 1, 2);
|
||||
break;
|
||||
case '5': // Single width, single height
|
||||
screen_set_line_attr(1, 1, 1);
|
||||
break;
|
||||
case '6': // Double width
|
||||
ansi_noimpl("Double Size Line");
|
||||
screen_set_line_attr(2, 1, 1);
|
||||
break;
|
||||
|
||||
case '8':
|
||||
screen_fill_with_E();
|
||||
break;
|
||||
|
||||
// development codes - do not use!
|
||||
case '7':
|
||||
http_get("http://wtfismyip.com/text", NULL, http_callback_example);
|
||||
break;
|
||||
// // development codes - do not use!
|
||||
// case '7':
|
||||
// http_get("http://wtfismyip.com/text", NULL, http_callback_example);
|
||||
// break;
|
||||
|
||||
default:
|
||||
ansi_noimpl("ESC # %c", c);
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
#define API_REBOOT "/api/v1/reboot"
|
||||
#define API_PING "/api/v1/ping"
|
||||
#define API_CLEAR "/api/v1/clear"
|
||||
#define API_GPIO "/api/v1/gpio"
|
||||
|
||||
#endif //ESPTERM_API_H
|
||||
|
||||
+1
-1
@@ -178,7 +178,7 @@ d2d_parse_command(char *msg)
|
||||
else if (strstarts(msg, "H;")) {
|
||||
if (request_pending) return false;
|
||||
|
||||
// Send a esp-esp message
|
||||
// Send a HTTP request
|
||||
msg += 2;
|
||||
const char *method = NULL;
|
||||
const char *params = NULL;
|
||||
|
||||
+177
-24
@@ -10,7 +10,8 @@
|
||||
#include "cgi_logging.h"
|
||||
|
||||
#define SET_REDIR_SUC "/cfg/system"
|
||||
#define SET_REDIR_ERR SET_REDIR_SUC"?err="
|
||||
|
||||
void buildInputsJson(char *buff);
|
||||
|
||||
static ETSTimer tmr;
|
||||
|
||||
@@ -82,7 +83,18 @@ cgiSystemCfgSetParams(HttpdConnData *connData)
|
||||
char redir_url_buf[100];
|
||||
|
||||
char *redir_url = redir_url_buf;
|
||||
redir_url += sprintf(redir_url, SET_REDIR_ERR);
|
||||
|
||||
if (GET_ARG("redir")) {
|
||||
strncpy(redir_url, buff, 40);
|
||||
u32 len = strlen(buff);
|
||||
if (len > 40) len = 40;
|
||||
redir_url += len;
|
||||
} else {
|
||||
redir_url += sprintf(redir_url, SET_REDIR_SUC);
|
||||
}
|
||||
char *end_of_redir_url = redir_url;
|
||||
redir_url += sprintf(redir_url, "?err=");
|
||||
char *end_of_failed_redir_url = redir_url;
|
||||
// we'll test if anything was printed by looking for \0 in failed_keys_buf
|
||||
|
||||
if (connData->conn == NULL) {
|
||||
@@ -174,14 +186,16 @@ cgiSystemCfgSetParams(HttpdConnData *connData)
|
||||
(void)redir_url;
|
||||
(void)uart_changed; // unused
|
||||
|
||||
if (redir_url_buf[strlen(SET_REDIR_ERR)] == 0) {
|
||||
if (*end_of_failed_redir_url == '\0') {
|
||||
// All was OK
|
||||
cgi_info("Set system params - success, saving...");
|
||||
|
||||
sysconf_apply_settings();
|
||||
persist_store();
|
||||
|
||||
httpdRedirect(connData, SET_REDIR_SUC "?msg=Settings%20saved%20and%20applied.");
|
||||
strcpy(end_of_redir_url, "?msg=Settings%20saved%20and%20applied.");
|
||||
|
||||
httpdRedirect(connData, redir_url_buf);
|
||||
} else {
|
||||
cgi_warn("Some settings did not validate, asking for correction");
|
||||
|
||||
@@ -198,6 +212,40 @@ cgiSystemCfgSetParams(HttpdConnData *connData)
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
static void tplSystemCfgFill(char *token, char *buff)
|
||||
{
|
||||
buff[0] = '\0';
|
||||
|
||||
const bool admin = false;
|
||||
const bool tpl=true;
|
||||
|
||||
#define XSTRUCT sysconf
|
||||
#define X XGET_CGI_FUNC_RETURN
|
||||
XTABLE_SYSCONF
|
||||
#undef X
|
||||
#undef XSTRUCT
|
||||
|
||||
if (streq(token, "def_access_name")) {
|
||||
sprintf(buff, "%s", DEF_ACCESS_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
if (streq(token, "def_access_pw")) {
|
||||
sprintf(buff, "%s", DEF_ACCESS_PW);
|
||||
return;
|
||||
}
|
||||
|
||||
if (streq(token, "def_admin_pw")) {
|
||||
sprintf(buff, "%s", DEFAULT_ADMIN_PW);
|
||||
return;
|
||||
}
|
||||
|
||||
if (streq(token, "gpio_initial")) {
|
||||
buildInputsJson(buff);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||
tplSystemCfg(HttpdConnData *connData, char *token, void **arg)
|
||||
@@ -210,27 +258,132 @@ tplSystemCfg(HttpdConnData *connData, char *token, void **arg)
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
strcpy(buff, ""); // fallback
|
||||
|
||||
const bool admin = false;
|
||||
const bool tpl=true;
|
||||
|
||||
#define XSTRUCT sysconf
|
||||
#define X XGET_CGI_FUNC
|
||||
XTABLE_SYSCONF
|
||||
#undef X
|
||||
#undef XSTRUCT
|
||||
|
||||
if (streq(token, "def_access_name")) {
|
||||
sprintf(buff, "%s", DEF_ACCESS_NAME);
|
||||
}
|
||||
else if (streq(token, "def_access_pw")) {
|
||||
sprintf(buff, "%s", DEF_ACCESS_PW);
|
||||
}
|
||||
else if (streq(token, "def_admin_pw")) {
|
||||
sprintf(buff, "%s", DEFAULT_ADMIN_PW);
|
||||
}
|
||||
tplSystemCfgFill(token, buff);
|
||||
|
||||
tplSend(connData, buff, -1);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
|
||||
static ETSTimer tmrPulse;
|
||||
|
||||
static void ICACHE_FLASH_ATTR tmrPulseCb(void *arg)
|
||||
{
|
||||
u32 mask = sysconf->gpio2_conf==GPIOCONF_OFF ? 0x30 : 0x34;
|
||||
u32 argu = (u32) arg;
|
||||
u32 set_on = argu & mask;
|
||||
u32 set_off = (argu >> 16) & mask;
|
||||
gpio_output_set(set_off, set_on, 0, 0); // the args are swapped here to achieve the opposite
|
||||
}
|
||||
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
buildInputsJson(char *buff)
|
||||
{
|
||||
u32 inputs = gpio_input_get();
|
||||
|
||||
sprintf(buff, "{\"io2\":%d,\"io4\":%d,\"io5\":%d}",
|
||||
((inputs&(1<<2)) != 0),
|
||||
((inputs&(1<<4)) != 0),
|
||||
((inputs&(1<<5)) != 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* API to set GPIOs
|
||||
*
|
||||
* @param connData
|
||||
* @return
|
||||
*/
|
||||
httpd_cgi_state ICACHE_FLASH_ATTR cgiGPIO(HttpdConnData *connData)
|
||||
{
|
||||
char buff[32];
|
||||
|
||||
if (connData->conn==NULL) {
|
||||
//Connection aborted. Clean up.
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
bool set = 0;
|
||||
u32 inputs = gpio_input_get();
|
||||
|
||||
// args are do2, do4, do5, pulse. Values: 0 - off, 1 - on, t - toggle. pulse is in ms
|
||||
|
||||
s8 set_d2 = -1, set_d4 = -1, set_d5 = -1;
|
||||
|
||||
if (sysconf->gpio2_conf == GPIOCONF_OUT_START_0 || sysconf->gpio2_conf == GPIOCONF_OUT_START_1) {
|
||||
if (GET_ARG("do2")) {
|
||||
if (buff[0] == 't') {
|
||||
set = ((inputs & (1<<2)) == 0);
|
||||
} else {
|
||||
set = buff[0] == '1';
|
||||
}
|
||||
set_d2 = set;
|
||||
gpio_output_set((uint32) (set << 2), (uint32) ((!set) << 2), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (sysconf->gpio4_conf == GPIOCONF_OUT_START_0 || sysconf->gpio4_conf == GPIOCONF_OUT_START_1) {
|
||||
if (GET_ARG("do4")) {
|
||||
if (buff[0] == 't') {
|
||||
set = ((inputs & (1<<4)) == 0);
|
||||
} else {
|
||||
set = buff[0] == '1';
|
||||
}
|
||||
set_d4 = set;
|
||||
gpio_output_set((uint32) (set << 4), (uint32) ((!set) << 4), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (sysconf->gpio5_conf == GPIOCONF_OUT_START_0 || sysconf->gpio5_conf == GPIOCONF_OUT_START_1) {
|
||||
if (GET_ARG("do5")) {
|
||||
if (buff[0] == 't') {
|
||||
set = ((inputs & (1<<5)) == 0);
|
||||
} else {
|
||||
set = buff[0] == '1';
|
||||
}
|
||||
set_d5 = set;
|
||||
gpio_output_set((uint32) (set << 5), (uint32) ((!set) << 5), 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_ARG("pulse")) {
|
||||
int duration = atoi(buff);
|
||||
|
||||
if (duration > 0) {
|
||||
u32 cmd = 0;
|
||||
if (set_d2 != -1) {
|
||||
if (set_d2) { cmd |= 1<<2; } else { cmd |= 1<<(16+2); }
|
||||
}
|
||||
|
||||
if (set_d4 != -1) {
|
||||
if (set_d4) { cmd |= 1<<4; } else { cmd |= 1<<(16+4); }
|
||||
}
|
||||
|
||||
if (set_d5 != -1) {
|
||||
if (set_d5) { cmd |= 1<<5; } else { cmd |= 1<<(16+5); }
|
||||
}
|
||||
|
||||
os_timer_disarm(&tmrPulse);
|
||||
os_timer_setfn(&tmrPulse, tmrPulseCb, (void*) cmd);
|
||||
os_timer_arm(&tmrPulse, duration, false);
|
||||
}
|
||||
}
|
||||
|
||||
httpdStartResponse(connData, 200);
|
||||
httpdHeader(connData, "Content-Type", "application/json");
|
||||
httpdEndHeaders(connData);
|
||||
|
||||
// refresh inputs
|
||||
buildInputsJson(buff);
|
||||
httpdSend(connData, buff, -1);
|
||||
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
|
||||
/** "GPIO" page */
|
||||
httpd_cgi_state ICACHE_FLASH_ATTR
|
||||
tplGpio(HttpdConnData *connData, char *token, void **arg)
|
||||
{
|
||||
return tplSystemCfg(connData, token, arg);
|
||||
}
|
||||
|
||||
@@ -9,5 +9,7 @@ httpd_cgi_state cgiResetDevice(HttpdConnData *connData);
|
||||
httpd_cgi_state cgiSystemCfgSetParams(HttpdConnData *connData);
|
||||
httpd_cgi_state tplSystemCfg(HttpdConnData *connData, char *token, void **arg);
|
||||
httpd_cgi_state cgiResetScreen(HttpdConnData *connData);
|
||||
httpd_cgi_state cgiGPIO(HttpdConnData *connData);
|
||||
httpd_cgi_state tplGpio(HttpdConnData *connData, char *token, void **arg);
|
||||
|
||||
#endif // CGI_PING_H
|
||||
|
||||
@@ -88,6 +88,9 @@ enum xset_result xset_ustring(const char *name, u8 *field, const char *buff, con
|
||||
#define XGET_CGI_FUNC(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
|
||||
if ((allow) && streq(token, #name)) xget(buff, deref XSTRUCT->name);
|
||||
|
||||
#define XGET_CGI_FUNC_RETURN(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
|
||||
if ((allow) && streq(token, #name)) { xget(buff, deref XSTRUCT->name); return; }
|
||||
|
||||
#define XSTRUCT_FIELD(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
|
||||
type name suffix;
|
||||
|
||||
|
||||
@@ -98,7 +98,10 @@ static void ICACHE_FLASH_ATTR resetBtnTimerCb(void *arg) {
|
||||
} else {
|
||||
// Switch LED pins back to UART mode
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
|
||||
if (sysconf->gpio2_conf == GPIOCONF_OFF) {
|
||||
// only if uart is enabled
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
}
|
||||
|
||||
if (resetCnt>=12) { //6 secs pressed - FR (timer is at 500 ms)
|
||||
info("Restoring to default settings via BOOT button!");
|
||||
@@ -140,3 +143,61 @@ void ICACHE_FLASH_ATTR ioInit() {
|
||||
}
|
||||
}
|
||||
|
||||
struct pinmapping {
|
||||
bool set;
|
||||
bool reset;
|
||||
bool enable;
|
||||
bool disable;
|
||||
bool input;
|
||||
bool pullup;
|
||||
};
|
||||
|
||||
void ICACHE_FLASH_ATTR userGpioInit(void)
|
||||
{
|
||||
const struct pinmapping pin_mappings[5] = {
|
||||
// S R E D I P
|
||||
{0, 1, 0, 1, 0, 0}, // OFF
|
||||
{0, 1, 1, 0, 0, 0}, // OUT 0
|
||||
{1, 0, 1, 0, 0, 0}, // OUT 1
|
||||
{0, 0, 0, 1, 1, 1}, // IN PULL
|
||||
{0, 0, 0, 1, 1, 0}, // IN NOPULL
|
||||
};
|
||||
|
||||
u8 num;
|
||||
const struct pinmapping *pm;
|
||||
|
||||
// GPIO2
|
||||
num = 2;
|
||||
pm = &pin_mappings[sysconf->gpio2_conf];
|
||||
gpio_output_set((uint32) (pm->set << num), (uint32) (pm->reset << num), (uint32) (pm->enable << num), (uint32) (pm->disable << num));
|
||||
if (pm->pullup) {
|
||||
PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO2_U);
|
||||
} else {
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U);
|
||||
}
|
||||
if (sysconf->gpio2_conf == GPIOCONF_OFF) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
} else {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
|
||||
}
|
||||
|
||||
// GPIO4
|
||||
num = 4;
|
||||
pm = &pin_mappings[sysconf->gpio4_conf];
|
||||
gpio_output_set((uint32) (pm->set << num), (uint32) (pm->reset << num), (uint32) (pm->enable << num), (uint32) (pm->disable << num));
|
||||
if (pm->pullup) {
|
||||
PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U);
|
||||
} else {
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO4_U);
|
||||
}
|
||||
|
||||
// GPIO5
|
||||
num = 5;
|
||||
pm = &pin_mappings[sysconf->gpio5_conf];
|
||||
gpio_output_set((uint32) (pm->set << num), (uint32) (pm->reset << num), (uint32) (pm->enable << num), (uint32) (pm->disable << num));
|
||||
if (pm->pullup) {
|
||||
PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO5_U);
|
||||
} else {
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO5_U);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
#define IO_H
|
||||
|
||||
void ioInit(void);
|
||||
void userGpioInit(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -103,6 +103,7 @@ const HttpdBuiltInUrl routes[] ESP_CONST_DATA = {
|
||||
ROUTE_TPL_FILE("/", tplScreen, "/term.tpl"),
|
||||
ROUTE_TPL_FILE("/about/?", tplAbout, "/about.tpl"),
|
||||
ROUTE_FILE("/help/?", "/help.html"),
|
||||
ROUTE_TPL_FILE("/cfg/gpio/?", tplGpio, "/cfg_gpio.tpl"),
|
||||
|
||||
// --- Sockets ---
|
||||
ROUTE_WS(URL_WS_UPDATE, updateSockConnect),
|
||||
@@ -114,6 +115,7 @@ const HttpdBuiltInUrl routes[] ESP_CONST_DATA = {
|
||||
ROUTE_CGI(API_PING"/?", cgiPing),
|
||||
ROUTE_CGI(API_CLEAR"/?", cgiResetScreen),
|
||||
ROUTE_CGI(API_D2D_MSG"/?", cgiD2DMessage),
|
||||
ROUTE_CGI(API_GPIO"/?", cgiGPIO),
|
||||
|
||||
ROUTE_REDIRECT("/cfg/?", "/cfg/wifi"),
|
||||
|
||||
|
||||
+180
-23
@@ -39,6 +39,7 @@ static Cell screen[MAX_SCREEN_SIZE];
|
||||
|
||||
|
||||
#define TABSTOP_WORDS 5
|
||||
#define LINE_ATTRS_COUNT 64
|
||||
/**
|
||||
* Screen state structure
|
||||
*/
|
||||
@@ -57,9 +58,12 @@ static struct {
|
||||
int vm1;
|
||||
|
||||
u32 tab_stops[TABSTOP_WORDS]; // tab stops bitmap
|
||||
u8 line_attribs[LINE_ATTRS_COUNT]; // assume that's quite enough...
|
||||
char last_char[4];
|
||||
} scr;
|
||||
|
||||
#define IS_DOUBLE_WIDTH() (scr.line_attribs[cursor.y]&0b001)
|
||||
|
||||
#define TOP scr.vm0
|
||||
#define BTM scr.vm1
|
||||
#define RH (scr.vm1 - scr.vm0 + 1)
|
||||
@@ -373,6 +377,8 @@ terminal_restore_defaults(void)
|
||||
strcpy((char*)termconf->bm4, "\x04");
|
||||
strcpy((char*)termconf->bm5, "\x05");
|
||||
|
||||
termconf->bc1 = termconf->bc2 = termconf->bc3 = termconf->bc4 = termconf->bc5 = 0;
|
||||
|
||||
termconf->theme = 0;
|
||||
termconf->parser_tout_ms = SCR_DEF_PARSER_TOUT_MS;
|
||||
termconf->display_tout_ms = SCR_DEF_DISPLAY_TOUT_MS;
|
||||
@@ -389,6 +395,8 @@ terminal_restore_defaults(void)
|
||||
termconf->allow_decopt_12 = SCR_DEF_DECOPT12;
|
||||
termconf->ascii_debug = SCR_DEF_ASCIIDEBUG;
|
||||
termconf->backdrop[0] = 0;
|
||||
termconf->font_stack[0] = 0;
|
||||
termconf->font_size = 20;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,6 +448,14 @@ terminal_apply_settings_noclear(void)
|
||||
termconf->button_count = SCR_DEF_BUTTON_COUNT;
|
||||
changed = 1;
|
||||
}
|
||||
if (termconf->config_version < 6) {
|
||||
persist_dbg("termconf: Updating to version 6");
|
||||
termconf->backdrop[0] = 0;
|
||||
termconf->font_stack[0] = 0;
|
||||
termconf->font_size = 20;
|
||||
termconf->bc1 = termconf->bc2 = termconf->bc3 = termconf->bc4 = termconf->bc5 = 0;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
termconf->config_version = TERMCONF_VERSION;
|
||||
|
||||
@@ -539,7 +555,12 @@ screen_reset_sgr(void)
|
||||
static void ICACHE_FLASH_ATTR
|
||||
screen_reset_do(bool size, bool labels)
|
||||
{
|
||||
ScreenNotifyTopics topics = TOPIC_CHANGE_SCREEN_OPTS | TOPIC_CHANGE_CURSOR | TOPIC_CHANGE_CONTENT_ALL;
|
||||
ScreenNotifyTopics topics =
|
||||
TOPIC_CHANGE_SCREEN_OPTS
|
||||
| TOPIC_CHANGE_CURSOR
|
||||
| TOPIC_CHANGE_CONTENT_ALL
|
||||
| TOPIC_DOUBLE_LINES;
|
||||
|
||||
NOTIFY_LOCK();
|
||||
|
||||
// DECopts
|
||||
@@ -576,6 +597,9 @@ screen_reset_do(bool size, bool labels)
|
||||
scr.tab_stops[i] = 0x80808080;
|
||||
}
|
||||
|
||||
// clear line attribs
|
||||
memset(scr.line_attribs, 0, LINE_ATTRS_COUNT);
|
||||
|
||||
if (labels) {
|
||||
strcpy(termconf_live.title, termconf->title);
|
||||
strcpy(termconf_live.backdrop, termconf->backdrop);
|
||||
@@ -675,6 +699,32 @@ screen_swap_state(bool alternate)
|
||||
|
||||
//endregion
|
||||
|
||||
//region --- Double lines ---
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
screen_set_line_attr(uint8_t double_w, uint8_t double_h_top, uint8_t double_h_bot)
|
||||
{
|
||||
NOTIFY_LOCK();
|
||||
u8 attr = scr.line_attribs[cursor.y];
|
||||
if (double_w==2) attr |= 0b001;
|
||||
else if (double_w==1) attr &= ~0b001;
|
||||
if (double_h_top==2) attr |= 0b010;
|
||||
else if (double_h_top==1) attr &= ~0b010;
|
||||
if (double_h_bot==2) attr |= 0b100;
|
||||
else if (double_h_bot==1) attr &= ~0b100;
|
||||
scr.line_attribs[cursor.y] = attr;
|
||||
|
||||
if (attr & 0b001) {
|
||||
// if we're using double width - clamp cursor X position
|
||||
// TODO this should happen in all cursor ops - now it can sometimes go offscreen
|
||||
if (cursor.x >= W/2) cursor.x = W/2;
|
||||
}
|
||||
|
||||
NOTIFY_DONE(TOPIC_DOUBLE_LINES);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
//region --- Tab stops ---
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
@@ -710,6 +760,7 @@ next_tab_stop(void)
|
||||
{
|
||||
// cursor must never go past EOL
|
||||
if (cursor.x >= W-1) return -1;
|
||||
if (IS_DOUBLE_WIDTH() && cursor.x >= W/2-1) return -1;
|
||||
|
||||
// find first word to inspect
|
||||
int idx = (cursor.x+1)/32;
|
||||
@@ -721,6 +772,7 @@ next_tab_stop(void)
|
||||
for(;offs<32;offs++) {
|
||||
cp++;
|
||||
if (cp >= W) return -1;
|
||||
if (IS_DOUBLE_WIDTH() && cp >= W/2) return -1;
|
||||
if (w & 1) return cp;
|
||||
w >>= 1;
|
||||
}
|
||||
@@ -778,6 +830,7 @@ screen_tab_forward(int count)
|
||||
}
|
||||
else {
|
||||
cursor.x = W - 1;
|
||||
if (IS_DOUBLE_WIDTH()) cursor.x = W/2 - 1;
|
||||
}
|
||||
}
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CURSOR);
|
||||
@@ -979,19 +1032,23 @@ screen_clear(ClearMode mode)
|
||||
unicode_cache_clear();
|
||||
clear_range_noutf(0, W * H - 1);
|
||||
scr.last_char[0] = 0;
|
||||
for (int i = 0; i < LINE_ATTRS_COUNT; i++) scr.line_attribs[i] = 0;
|
||||
break;
|
||||
|
||||
case CLEAR_FROM_CURSOR:
|
||||
clear_range_utf((cursor.y * W) + cursor.x, W * H - 1);
|
||||
expand_dirty(cursor.y, H-1, 0, W-1);
|
||||
for (int i = cursor.y; i < LINE_ATTRS_COUNT; i++) scr.line_attribs[i] = 0;
|
||||
break;
|
||||
|
||||
case CLEAR_TO_CURSOR:
|
||||
clear_range_utf(0, (cursor.y * W) + cursor.x);
|
||||
expand_dirty(0, cursor.y, 0, W-1);
|
||||
for (int i = 0; i <= cursor.y; i++) scr.line_attribs[i] = 0;
|
||||
break;
|
||||
}
|
||||
NOTIFY_DONE(mode == CLEAR_ALL ? TOPIC_CHANGE_CONTENT_ALL : TOPIC_CHANGE_CONTENT_PART);
|
||||
NOTIFY_DONE((mode == CLEAR_ALL ? TOPIC_CHANGE_CONTENT_ALL : TOPIC_CHANGE_CONTENT_PART)
|
||||
| TOPIC_DOUBLE_LINES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1043,11 +1100,15 @@ screen_insert_lines(unsigned int lines)
|
||||
int targetStart = cursor.y + lines;
|
||||
if (targetStart > BTM) {
|
||||
clear_range_utf(cursor.y*W, (BTM+1)*W-1);
|
||||
for (int i = cursor.y; i <= BTM; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
} else {
|
||||
// do the moving
|
||||
for (int i = BTM; i >= targetStart; i--) {
|
||||
utf_free_row(i); // release old characters
|
||||
copy_row(i, i - lines);
|
||||
scr.line_attribs[i] = scr.line_attribs[i-lines];
|
||||
if (i != targetStart) utf_backup_row(i);
|
||||
}
|
||||
|
||||
@@ -1059,7 +1120,7 @@ screen_insert_lines(unsigned int lines)
|
||||
}
|
||||
}
|
||||
expand_dirty(cursor.y, BTM, 0, W - 1);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART|TOPIC_DOUBLE_LINES);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
@@ -1074,18 +1135,26 @@ screen_delete_lines(unsigned int lines)
|
||||
// clear the entire rest of the screen
|
||||
movedBlockEnd = cursor.y;
|
||||
clear_range_utf(movedBlockEnd*W, (BTM+1)*W-1);
|
||||
for (int i = movedBlockEnd; i <= BTM; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
} else {
|
||||
// move some lines up, clear the rest
|
||||
for (int i = cursor.y; i <= movedBlockEnd; i++) {
|
||||
utf_free_row(i);
|
||||
copy_row(i, i+lines);
|
||||
scr.line_attribs[i] = scr.line_attribs[i+lines];
|
||||
if (i != movedBlockEnd) utf_backup_row(i);
|
||||
}
|
||||
clear_range_noutf((movedBlockEnd+1)*W, (BTM+1)*W-1);
|
||||
|
||||
for (int i = movedBlockEnd+1; i <= BTM; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
expand_dirty(cursor.y, BTM, 0, W - 1);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART|TOPIC_DOUBLE_LINES);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
@@ -1206,12 +1275,13 @@ void ICACHE_FLASH_ATTR
|
||||
screen_set_button_text(int num, const char *text)
|
||||
{
|
||||
NOTIFY_LOCK();
|
||||
if (num == 1) strncpy(termconf_live.btn1, text, TERM_BTN_LEN);
|
||||
else if (num == 2) strncpy(termconf_live.btn2, text, TERM_BTN_LEN);
|
||||
else if (num == 3) strncpy(termconf_live.btn3, text, TERM_BTN_LEN);
|
||||
else if (num == 4) strncpy(termconf_live.btn4, text, TERM_BTN_LEN);
|
||||
else if (num == 5) strncpy(termconf_live.btn5, text, TERM_BTN_LEN);
|
||||
|
||||
if (num >= 1 && num <= TERM_BTN_COUNT) {
|
||||
char *buf = TERM_BTN_N(&termconf_live, num - 1);
|
||||
strncpy(buf, text, TERM_BTN_MSG_LEN);
|
||||
}
|
||||
else ansi_warn("Bad button num: %d", num);
|
||||
|
||||
NOTIFY_DONE(TOPIC_CHANGE_BUTTONS);
|
||||
}
|
||||
|
||||
@@ -1224,12 +1294,32 @@ void ICACHE_FLASH_ATTR
|
||||
screen_set_button_message(int num, const char *msg)
|
||||
{
|
||||
NOTIFY_LOCK();
|
||||
if (num == 1) strncpy(termconf_live.bm1, msg, TERM_BTN_MSG_LEN);
|
||||
else if (num == 2) strncpy(termconf_live.bm2, msg, TERM_BTN_MSG_LEN);
|
||||
else if (num == 3) strncpy(termconf_live.bm3, msg, TERM_BTN_MSG_LEN);
|
||||
else if (num == 4) strncpy(termconf_live.bm4, msg, TERM_BTN_MSG_LEN);
|
||||
else if (num == 5) strncpy(termconf_live.bm5, msg, TERM_BTN_MSG_LEN);
|
||||
|
||||
if (num >= 1 && num <= TERM_BTN_COUNT) {
|
||||
char *buf = TERM_BM_N(&termconf_live, num - 1);
|
||||
strncpy(buf, msg, TERM_BTN_MSG_LEN);
|
||||
}
|
||||
else ansi_warn("Bad button num: %d", num);
|
||||
|
||||
NOTIFY_DONE(TOPIC_CHANGE_BUTTONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to set terminal button label
|
||||
* @param num - button number 1-5
|
||||
* @param str - button text
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
screen_set_button_color(int num, const char *buf)
|
||||
{
|
||||
NOTIFY_LOCK();
|
||||
|
||||
if (num >= 1 && num <= TERM_BTN_COUNT) {
|
||||
u32 *fieldptr = &termconf_live.bc1 + (num-1);
|
||||
xset_term_color("", fieldptr, buf, NULL);
|
||||
}
|
||||
else ansi_warn("Bad button num: %d", num);
|
||||
|
||||
NOTIFY_DONE(TOPIC_CHANGE_BUTTONS);
|
||||
}
|
||||
|
||||
@@ -1271,6 +1361,9 @@ screen_scroll_up(unsigned int lines)
|
||||
if (lines >= RH) {
|
||||
// clear entire region
|
||||
clear_range_utf(TOP * W, (BTM + 1) * W - 1);
|
||||
for (int i = TOP; i <= BTM; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1283,14 +1376,18 @@ screen_scroll_up(unsigned int lines)
|
||||
for (y = TOP; y <= BTM - lines; y++) {
|
||||
utf_free_row(y);
|
||||
copy_row(y, y+lines);
|
||||
scr.line_attribs[y] = scr.line_attribs[y+lines];
|
||||
if (y < BTM - lines) utf_backup_row(y);
|
||||
}
|
||||
|
||||
clear_range_noutf(y * W, (BTM + 1) * W - 1);
|
||||
for (int i = y; i <= BTM; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
expand_dirty(TOP, BTM, 0, W - 1);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART|TOPIC_DOUBLE_LINES);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1303,6 +1400,9 @@ screen_scroll_down(unsigned int lines)
|
||||
if (lines >= RH) {
|
||||
// clear entire region
|
||||
clear_range_utf(TOP * W, (BTM + 1) * W - 1);
|
||||
for (int i = TOP; i <= BTM; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1315,13 +1415,17 @@ screen_scroll_down(unsigned int lines)
|
||||
for (y = BTM; y >= TOP+lines; y--) {
|
||||
utf_free_row(y);
|
||||
copy_row(y, y-lines);
|
||||
scr.line_attribs[y] = scr.line_attribs[y-lines];
|
||||
if (y > TOP + lines) utf_backup_row(y);
|
||||
}
|
||||
|
||||
clear_range_noutf(TOP * W, TOP * W + lines * W - 1);
|
||||
clear_range_noutf(TOP * W, (TOP + lines) * W - 1);
|
||||
for (int i = TOP; i < TOP + lines; i++) {
|
||||
scr.line_attribs[i] = 0;
|
||||
}
|
||||
done:
|
||||
expand_dirty(TOP, BTM, 0, W - 1);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART);
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CONTENT_PART|TOPIC_DOUBLE_LINES);
|
||||
}
|
||||
|
||||
/** Set scrolling region */
|
||||
@@ -1426,6 +1530,9 @@ screen_cursor_set_x(int x)
|
||||
// hanging happens when the cursor is virtually at col=81, which
|
||||
// cannot be set using the cursor-set commands.
|
||||
cursor.hanging = false;
|
||||
|
||||
if (IS_DOUBLE_WIDTH() && cursor.x >= W/2) cursor.x = W/2-1;
|
||||
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CURSOR);
|
||||
}
|
||||
|
||||
@@ -1470,6 +1577,7 @@ screen_cursor_move(int dy, int dx, bool scroll)
|
||||
cursor.x += dx;
|
||||
cursor.y += dy;
|
||||
if (cursor.x >= (int)W) cursor.x = W - 1;
|
||||
if (IS_DOUBLE_WIDTH() && cursor.x >= W/2) cursor.x = W/2-1;
|
||||
if (cursor.x < (int)0) {
|
||||
if (cursor.auto_wrap && cursor.reverse_wrap) {
|
||||
// this is mimicking a behavior from xterm that allows any number of steps backwards with reverse wraparound enabled
|
||||
@@ -1576,6 +1684,8 @@ screen_cursor_restore(bool withAttrs)
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_DOUBLE_WIDTH() && cursor.x >= W/2) cursor.x = W/2-1;
|
||||
|
||||
NOTIFY_DONE(TOPIC_CHANGE_CURSOR);
|
||||
}
|
||||
|
||||
@@ -1944,6 +2054,10 @@ putchar_graphic(const char *ch)
|
||||
cursor.hanging = true; // hanging - next typed char wraps around, but backspace and arrows still stay on the same line.
|
||||
cursor.x = W - 1;
|
||||
}
|
||||
if (IS_DOUBLE_WIDTH() && cursor.x >= W/2) {
|
||||
cursor.hanging = true; // hanging
|
||||
cursor.x = W/2 - 1;
|
||||
}
|
||||
|
||||
NOTIFY_DONE(topics);
|
||||
return ch;
|
||||
@@ -2143,6 +2257,15 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
bufput_utf8((num)); \
|
||||
} while(0)
|
||||
|
||||
#define bufput_color_utf8(c) do { \
|
||||
if ((c) < 256) { \
|
||||
bufput_utf8(c); \
|
||||
} else { \
|
||||
bufput_utf8((((c)-256)&0xFFF) | 0x10000); \
|
||||
bufput_utf8((((c)-256)>>12)&0xFFF); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
// tags for screen serialization
|
||||
#define SEQ_TAG_SKIP '\x01'
|
||||
#define SEQ_TAG_REPEAT '\x02'
|
||||
@@ -2153,6 +2276,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
#define SEQ_TAG_ATTRS_0 '\x07'
|
||||
|
||||
#define TOPICMARK_SCREEN_OPTS 'O'
|
||||
#define TOPICMARK_STATIC_OPTS 'P'
|
||||
#define TOPICMARK_TITLE 'T'
|
||||
#define TOPICMARK_BUTTONS 'B'
|
||||
#define TOPICMARK_DEBUG 'D'
|
||||
@@ -2160,6 +2284,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
#define TOPICMARK_CURSOR 'C'
|
||||
#define TOPICMARK_SCREEN 'S'
|
||||
#define TOPICMARK_BACKDROP 'W'
|
||||
#define TOPICMARK_DBL_LINE 'H'
|
||||
|
||||
if (ss == NULL) {
|
||||
// START!
|
||||
@@ -2250,12 +2375,8 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
bufput_utf8(H);
|
||||
bufput_utf8(W);
|
||||
bufput_utf8(termconf_live.theme);
|
||||
|
||||
bufput_utf8(termconf_live.default_fg & 0xFFFF);
|
||||
bufput_utf8((termconf_live.default_fg >> 16) & 0xFFFF);
|
||||
|
||||
bufput_utf8(termconf_live.default_bg & 0xFFFF);
|
||||
bufput_utf8((termconf_live.default_bg >> 16) & 0xFFFF);
|
||||
bufput_color_utf8(termconf_live.default_fg);
|
||||
bufput_color_utf8(termconf_live.default_bg);
|
||||
|
||||
bufput_utf8(
|
||||
(scr.cursor_visible << 0) |
|
||||
@@ -2274,6 +2395,36 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
);
|
||||
END_TOPIC
|
||||
|
||||
BEGIN_TOPIC(TOPIC_CHANGE_STATIC_OPTS, 110)
|
||||
bufput_c(TOPICMARK_STATIC_OPTS);
|
||||
|
||||
size_t len = strlen(termconf_live.font_stack);
|
||||
if (len > 0) {
|
||||
memcpy(bb, termconf_live.font_stack, len);
|
||||
bb += len;
|
||||
remain -= len;
|
||||
}
|
||||
bufput_c('\x01');
|
||||
|
||||
bufput_utf8(termconf_live.font_size);
|
||||
END_TOPIC
|
||||
|
||||
BEGIN_TOPIC(TOPIC_DOUBLE_LINES, 70)
|
||||
bufput_c(TOPICMARK_DBL_LINE);
|
||||
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < LINE_ATTRS_COUNT; i++) {
|
||||
if (scr.line_attribs[i] != 0) cnt++;
|
||||
}
|
||||
bufput_utf8(cnt);
|
||||
|
||||
for (int i = 0; i < LINE_ATTRS_COUNT; i++) {
|
||||
if (scr.line_attribs[i] != 0) {
|
||||
bufput_utf8((i << 3) | (scr.line_attribs[i]&0b111));
|
||||
}
|
||||
}
|
||||
END_TOPIC
|
||||
|
||||
BEGIN_TOPIC(TOPIC_CHANGE_TITLE, TERM_TITLE_LEN+4+1)
|
||||
bufput_c(TOPICMARK_TITLE);
|
||||
|
||||
@@ -2291,7 +2442,11 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
|
||||
bufput_utf8(termconf_live.button_count);
|
||||
|
||||
u32 *cp = &termconf_live.bc1;
|
||||
for (int i = 0; i < termconf_live.button_count; i++) {
|
||||
uint32_t c = *cp++;
|
||||
bufput_color_utf8(c);
|
||||
|
||||
size_t len = strlen(TERM_BTN_N(&termconf_live, i));
|
||||
if (len > 0) {
|
||||
memcpy(bb, TERM_BTN_N(&termconf_live, i), len);
|
||||
@@ -2333,6 +2488,8 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, ScreenNotifyTopics topics,
|
||||
bufput_utf8(cursor.charsetN);
|
||||
bufput_c(cursor.charset0);
|
||||
bufput_c(cursor.charset1);
|
||||
bufput_color_utf8(cursor.fg);
|
||||
bufput_color_utf8(cursor.bg);
|
||||
bufput_utf8(system_get_free_heap_size());
|
||||
bufput_utf8(term_active_clients);
|
||||
END_TOPIC
|
||||
|
||||
+24
-6
@@ -40,6 +40,7 @@
|
||||
#define TERM_TITLE_LEN 64
|
||||
#define TERM_BTN_COUNT 5
|
||||
#define TERM_BACKDROP_LEN 100
|
||||
#define TERM_FONTSTACK_LEN 100
|
||||
|
||||
#define SCR_DEF_DISPLAY_TOUT_MS 12
|
||||
#define SCR_DEF_DISPLAY_COOLDOWN_MS 35
|
||||
@@ -77,8 +78,8 @@ enum CursorShape {
|
||||
|
||||
// Size designed for the terminal config structure
|
||||
// Must be constant to avoid corrupting user config after upgrade
|
||||
#define TERMCONF_SIZE 400
|
||||
#define TERMCONF_VERSION 5
|
||||
#define TERMCONF_SIZE 500
|
||||
#define TERMCONF_VERSION 6
|
||||
|
||||
//....Type................Name..Suffix...............Deref..XGET.........Cast..XSET...........NOTIFY..Allow
|
||||
// Deref is used to pass the field to xget. Cast is used to convert the &'d field to what xset wants (needed for static arrays)
|
||||
@@ -114,10 +115,19 @@ enum CursorShape {
|
||||
X(bool, allow_decopt_12, /**/, /**/, xget_bool, xset_bool, NULL, /**/, 1) \
|
||||
X(bool, ascii_debug, /**/, /**/, xget_bool, xset_bool, NULL, /**/, 1) \
|
||||
X(char, backdrop, [TERM_BACKDROP_LEN], /**/, xget_string, xset_string, TERM_BACKDROP_LEN, /**/, 1) \
|
||||
X(u8, button_count, /**/, /**/, xget_dec, xset_u8, NULL, /**/, 1)
|
||||
X(u8, button_count, /**/, /**/, xget_dec, xset_u8, NULL, /**/, 1) \
|
||||
X(u32, bc1, /**/, /**/, xget_term_color, xset_term_color, NULL, /**/, 1) \
|
||||
X(u32, bc2, /**/, /**/, xget_term_color, xset_term_color, NULL, /**/, 1) \
|
||||
X(u32, bc3, /**/, /**/, xget_term_color, xset_term_color, NULL, /**/, 1) \
|
||||
X(u32, bc4, /**/, /**/, xget_term_color, xset_term_color, NULL, /**/, 1) \
|
||||
X(u32, bc5, /**/, /**/, xget_term_color, xset_term_color, NULL, /**/, 1) \
|
||||
X(char, font_stack, [TERM_FONTSTACK_LEN], /**/, xget_string, xset_string, TERM_FONTSTACK_LEN, /**/, 1) \
|
||||
X(u8, font_size, /**/, /**/, xget_dec, xset_u8, NULL, /**/, 1)
|
||||
|
||||
#define TERM_BM_N(tc, n) ((tc)->bm1+(TERM_BTN_MSG_LEN*n))
|
||||
#define TERM_BTN_N(tc, n) ((tc)->btn1+(TERM_BTN_LEN*n))
|
||||
/** Get button N message from the passed config structure pointer */
|
||||
#define TERM_BM_N(tc, n) ((tc)->bm1+(TERM_BTN_MSG_LEN*(n)))
|
||||
/** Get button N text from the passed config structure pointer */
|
||||
#define TERM_BTN_N(tc, n) ((tc)->btn1+(TERM_BTN_LEN*(n)))
|
||||
|
||||
/** Export color for config */
|
||||
void xget_term_color(char *buff, u32 value);
|
||||
@@ -183,6 +193,7 @@ void screen_set_title(const char *title);
|
||||
/** Set a button text */
|
||||
void screen_set_button_text(int num, const char *text);
|
||||
void screen_set_button_message(int num, const char *msg);
|
||||
void screen_set_button_color(int num, const char *buf);
|
||||
void screen_set_button_count(int count);
|
||||
/** Change backdrop */
|
||||
void screen_set_backdrop(const char *url);
|
||||
@@ -208,16 +219,20 @@ enum ScreenSerializeTopic {
|
||||
TOPIC_INTERNAL = (1<<6), // debugging internal state
|
||||
TOPIC_BELL = (1<<7), // beep
|
||||
TOPIC_CHANGE_BACKDROP = (1<<8),
|
||||
TOPIC_CHANGE_STATIC_OPTS = (1<<9),
|
||||
TOPIC_DOUBLE_LINES = (1<<10),
|
||||
TOPIC_FLAG_NOCLEAN = (1<<15), // do not clean dirty extents
|
||||
|
||||
// combos
|
||||
TOPIC_INITIAL =
|
||||
TOPIC_CHANGE_SCREEN_OPTS |
|
||||
TOPIC_CHANGE_STATIC_OPTS |
|
||||
TOPIC_CHANGE_CONTENT_ALL |
|
||||
TOPIC_CHANGE_CURSOR |
|
||||
TOPIC_CHANGE_TITLE |
|
||||
TOPIC_CHANGE_BACKDROP |
|
||||
TOPIC_CHANGE_BUTTONS,
|
||||
TOPIC_CHANGE_BUTTONS |
|
||||
TOPIC_DOUBLE_LINES,
|
||||
};
|
||||
|
||||
typedef u16 ScreenNotifyTopics;
|
||||
@@ -369,6 +384,9 @@ void screen_tab_reverse(int count);
|
||||
/** Move left, shift right if at the boundary */
|
||||
void screen_back_index(int count);
|
||||
|
||||
/** Set line attribs; 0-no change, 1,2 - single,double */
|
||||
void screen_set_line_attr(uint8_t double_w, uint8_t double_h_top, uint8_t double_h_bot);
|
||||
|
||||
// --- Printing characters ---
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,11 +11,13 @@ static ETSTimer flushLogTimer;
|
||||
|
||||
static void buf_putc(char c)
|
||||
{
|
||||
if (sysconf->gpio2_conf == GPIOCONF_OFF) {
|
||||
if (lb_ls != lb_nw) {
|
||||
logbuf[lb_nw++] = c;
|
||||
if (lb_nw >= DEBUG_LOGBUF_SIZE) lb_nw = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
buf_pop(void *unused)
|
||||
@@ -42,8 +44,10 @@ buf_pop(void *unused)
|
||||
|
||||
LOCAL void my_putc(char c)
|
||||
{
|
||||
if (sysconf->gpio2_conf == GPIOCONF_OFF) {
|
||||
UART_WriteCharCRLF(UART1, (u8) c, 200);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the serial ports
|
||||
@@ -79,6 +83,14 @@ void ICACHE_FLASH_ATTR serialInit(void)
|
||||
UART_SetStopBits(UART0, (UartStopBitsNum) sysconf->uart_stopbits);
|
||||
UART_SetBaudrate(UART0, sysconf->uart_baudrate);
|
||||
|
||||
// GPIO2 may be used as a remotely controlled GPIO
|
||||
if (sysconf->gpio2_conf == GPIOCONF_OFF) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
} else {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
|
||||
// further config of the GPIO will be done in persist.c after calling this func
|
||||
}
|
||||
|
||||
info("COM SERIAL: %d baud, %s parity, %s stopbit(s)",
|
||||
sysconf->uart_baudrate,
|
||||
(sysconf->uart_parity == PARITY_NONE ? "NONE" : (sysconf->uart_parity == PARITY_ODD ? "ODD" : "EVEN")),
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "uart_driver.h"
|
||||
#include "serial.h"
|
||||
#include "cgi_logging.h"
|
||||
#include "io.h"
|
||||
|
||||
SystemConfigBundle * const sysconf = &persist.current.sysconf;
|
||||
|
||||
@@ -119,6 +120,14 @@ sysconf_apply_settings(void)
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (sysconf->config_version < 2) {
|
||||
dbg("Upgrading syscfg to v 2");
|
||||
sysconf->gpio2_conf = GPIOCONF_OFF;
|
||||
sysconf->gpio4_conf = GPIOCONF_OUT_START_0;
|
||||
sysconf->gpio5_conf = GPIOCONF_OUT_START_0;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
sysconf->config_version = SYSCONF_VERSION;
|
||||
|
||||
if (changed) {
|
||||
@@ -128,6 +137,9 @@ sysconf_apply_settings(void)
|
||||
// uart settings live here, but the CGI handler + form has been moved to the Terminal config page
|
||||
serialInit();
|
||||
|
||||
// initialize user GPIOs
|
||||
userGpioInit();
|
||||
|
||||
system_update_cpu_freq((uint8) (sysconf->overclock ? 160 : 80));
|
||||
}
|
||||
|
||||
@@ -143,4 +155,7 @@ sysconf_restore_defaults(void)
|
||||
strcpy((char *)sysconf->access_pw, DEF_ACCESS_PW);
|
||||
strcpy((char *)sysconf->access_name, DEF_ACCESS_NAME);
|
||||
sysconf->overclock = false;
|
||||
sysconf->gpio2_conf = GPIOCONF_OFF; // means 'use debug uart'
|
||||
sysconf->gpio4_conf = GPIOCONF_OUT_START_0;
|
||||
sysconf->gpio5_conf = GPIOCONF_OUT_START_0;
|
||||
}
|
||||
|
||||
+13
-2
@@ -11,7 +11,7 @@
|
||||
// Size designed for the wifi config structure
|
||||
// Must be constant to avoid corrupting user config after upgrade
|
||||
#define SYSCONF_SIZE 300
|
||||
#define SYSCONF_VERSION 1
|
||||
#define SYSCONF_VERSION 2
|
||||
|
||||
#define DEF_ACCESS_PW "1234"
|
||||
#define DEF_ACCESS_NAME "espterm"
|
||||
@@ -25,6 +25,14 @@ enum pwlock {
|
||||
PWLOCK_MAX = 5,
|
||||
};
|
||||
|
||||
enum gpioconf {
|
||||
GPIOCONF_OFF = 0,
|
||||
GPIOCONF_OUT_START_0 = 1,
|
||||
GPIOCONF_OUT_START_1 = 2,
|
||||
GPIOCONF_IN_PULL = 3,
|
||||
GPIOCONF_IN_NOPULL = 4,
|
||||
};
|
||||
|
||||
//....Type................Name..Suffix...............Deref..XGET............XSET.........................NOTIFY....Allow
|
||||
// Deref is used to pass the field to xget. Cast is used to convert the &'d field to what xset wants (needed for static arrays)
|
||||
#define XTABLE_SYSCONF \
|
||||
@@ -39,7 +47,9 @@ enum pwlock {
|
||||
X(uchar, access_name, [32], /**/, xget_ustring, xset_ustring, NULL, /**/, admin|tpl) \
|
||||
\
|
||||
X(bool, overclock, /**/, /**/, xget_bool, xset_bool, NULL, /**/, 1) \
|
||||
|
||||
X(u8, gpio2_conf, /**/, /**/, xget_dec, xset_u8, NULL, /**/, 1) \
|
||||
X(u8, gpio4_conf, /**/, /**/, xget_dec, xset_u8, NULL, /**/, 1) \
|
||||
X(u8, gpio5_conf, /**/, /**/, xget_dec, xset_u8, NULL, /**/, 1)
|
||||
|
||||
typedef struct {
|
||||
#define X XSTRUCT_FIELD
|
||||
@@ -54,6 +64,7 @@ typedef struct {
|
||||
// char access_pw[64]; // access password
|
||||
// char access_name[32]; // access name
|
||||
// bool overclock;
|
||||
// bool debug_uart;
|
||||
} SystemConfigBundle;
|
||||
|
||||
extern SystemConfigBundle * const sysconf;
|
||||
|
||||
@@ -56,6 +56,7 @@ void ICACHE_FLASH_ATTR UART_Init(void)
|
||||
|
||||
// U1TXD (GPIO2)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U);
|
||||
|
||||
// Configure the UART peripherals
|
||||
UART_SetWordLength(UART0, EIGHT_BITS); // main
|
||||
|
||||
+3
-1
@@ -96,6 +96,8 @@ static ETSTimer prHeapTimer;
|
||||
//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done.
|
||||
void ICACHE_FLASH_ATTR user_init(void)
|
||||
{
|
||||
sysconf->gpio2_conf = GPIOCONF_OFF; // enable debug UART for the start-up (sysconf is not loaded yet)
|
||||
|
||||
ansi_parser_inhibit = true;
|
||||
serialInitBase();
|
||||
|
||||
@@ -110,7 +112,7 @@ void ICACHE_FLASH_ATTR user_init(void)
|
||||
banner_gap();
|
||||
banner("================ ESPTerm ================");
|
||||
banner_info();
|
||||
banner_info("Project by Ondrej Hruska, 2017");
|
||||
banner_info("Project by Ondrej Hruska, 2017-2018");
|
||||
banner_info();
|
||||
banner_info(TERMINAL_GITHUB_REPO_NOPROTO);
|
||||
banner_info();
|
||||
|
||||
+3
-3
@@ -9,10 +9,10 @@
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
#define FW_V_MAJOR 2
|
||||
#define FW_V_MINOR 3
|
||||
#define FW_V_MINOR 4
|
||||
#define FW_V_PATCH 0
|
||||
#define FW_V_SUFFIX "-pre1"
|
||||
#define FW_CODENAME "Cricket" // 2.3
|
||||
#define FW_V_SUFFIX "-pre2"
|
||||
#define FW_CODENAME "Damselfly"
|
||||
#define FW_CODENAME_QUOTED "\""FW_CODENAME"\""
|
||||
|
||||
#define FW_VERSION STR(FW_V_MAJOR) "." STR(FW_V_MINOR) "." STR(FW_V_PATCH) FW_V_SUFFIX
|
||||
|
||||
Reference in New Issue
Block a user