Files
ninlight-w600/src/sys/nl_console.c
T

168 lines
4.7 KiB
C

#include <stdio.h>
#include <string.h>
#include "wm_include.h"
#include "wm_watchdog.h"
#include "light/nl_control.h"
#include "light/nl_engine.h"
#include "net/nl_wifi.h"
#include "sys/nl_app.h"
#include "sys/nl_console.h"
#include "sys/nl_console_cmd.h"
#define NL_CONSOLE_PRIO 45
static u32 s_stack[768];
static void print_state(void)
{
nl_light_state_t s;
nl_settings_t *cfg = nl_app_settings();
nl_app_lock();
nl_ctrl_get(&s);
nl_app_unlock();
printf("state: %s bri=%u mode=%s rgb=%u,%u,%u ct=%u | pob=%u fade=%u/%u\r\n",
s.on ? "on" : "off", s.brightness, s.mode == NL_MODE_COLOR ? "color" : "white",
s.r, s.g, s.b, s.ct, cfg->power_on_behaviour, cfg->fade_in_ms, cfg->fade_out_ms);
}
static void set_transition(nl_light_change_t *ch, const nl_cmd_t *c, uint8_t index)
{
if (c->argc > index) {
ch->has_transition = true;
ch->transition_ms = (uint32_t)c->arg[index];
}
}
static void exec(const nl_cmd_t *c)
{
nl_light_change_t ch;
nl_ctrl_err_t err;
nl_settings_t *cfg = nl_app_settings();
memset(&ch, 0, sizeof ch);
switch (c->type) {
case NL_CMD_NONE:
return;
case NL_CMD_ON:
case NL_CMD_OFF:
ch.has_on = true;
ch.on = c->type == NL_CMD_ON;
set_transition(&ch, c, 0);
break;
case NL_CMD_BRI:
ch.has_brightness = true;
ch.brightness = (uint8_t)c->arg[0];
set_transition(&ch, c, 1);
break;
case NL_CMD_RGB:
ch.has_color = true;
ch.r = (uint8_t)c->arg[0];
ch.g = (uint8_t)c->arg[1];
ch.b = (uint8_t)c->arg[2];
set_transition(&ch, c, 3);
break;
case NL_CMD_CT:
ch.has_ct = true;
ch.ct = (uint16_t)c->arg[0];
set_transition(&ch, c, 1);
break;
case NL_CMD_POB:
nl_app_lock();
cfg->power_on_behaviour = (uint8_t)c->arg[0];
nl_app_unlock();
printf(nl_app_save_settings() == 0 ? "ok\r\n" : "error: save failed\r\n");
print_state();
return;
case NL_CMD_FADE:
nl_app_lock();
cfg->fade_in_ms = (uint16_t)c->arg[0];
cfg->fade_out_ms = (uint16_t)c->arg[1];
nl_ctrl_set_fades(cfg->fade_in_ms, cfg->fade_out_ms);
nl_app_unlock();
printf(nl_app_save_settings() == 0 ? "ok\r\n" : "error: save failed\r\n");
print_state();
return;
case NL_CMD_STATE:
print_state();
return;
case NL_CMD_BLINK:
nl_app_lock();
nl_engine_blink((uint8_t)c->arg[0]);
nl_app_unlock();
return;
case NL_CMD_PULSE:
nl_app_lock();
nl_engine_pulse(c->arg[0] != 0);
nl_app_unlock();
return;
case NL_CMD_FACTORY:
nl_app_request_factory_reset();
return;
case NL_CMD_REBOOT:
nl_app_reboot();
return;
case NL_CMD_NET: {
nl_wifi_status_t w;
nl_wifi_status(&w);
printf("net: mode=%s ssid=%s ip=%s sta_ip=%s rssi=%d error=%s host=%s\r\n", w.mode, w.ssid, w.ip,
w.sta_ip[0] ? w.sta_ip : "-", w.rssi, w.error ? w.error : "-", nl_wifi_hostname());
return;
}
case NL_CMD_WDTEST:
printf("wdtest: holding app lock forever\r\n");
nl_app_lock(); /* deliberately never released: light_task and app_task stall on it,
* so only the watchdog reset can recover the chip */
return;
case NL_CMD_HELP:
printf("%s", nl_console_help);
return;
default:
printf("error: unknown command or bad argument (try help)\r\n");
return;
}
nl_app_lock();
err = nl_ctrl_apply(&ch, nl_app_now_ms());
nl_app_unlock();
if (err == NL_CTRL_OK)
printf("ok\r\n");
else
printf("error %d\r\n", (int)err);
print_state();
}
static void console_task(void *arg)
{
char line[64];
int len = 0;
u8 buf[16];
(void)arg;
printf("console ready, type help\r\n");
for (;;) {
int n = tls_uart_read(TLS_UART_0, buf, sizeof buf);
for (int i = 0; i < n; i++) {
char c = (char)buf[i];
if (c == '\r' || c == '\n') {
if (len) {
nl_cmd_t cmd;
line[len] = '\0';
cmd = nl_console_parse(line);
exec(&cmd);
len = 0;
}
} else if (len < (int)sizeof(line) - 1) {
line[len++] = c;
}
}
tls_os_time_delay(HZ / 50); /* 20 ms */
}
}
void nl_console_start(void)
{
tls_uart_port_init(TLS_UART_0, NULL, 0);
tls_os_task_create(NULL, "nl_con", console_task, NULL, (u8 *)s_stack, sizeof(s_stack), NL_CONSOLE_PRIO, 0);
}