284 lines
7.7 KiB
C
284 lines
7.7 KiB
C
/*
|
|
* (c) danielinux 2019
|
|
*
|
|
* GPLv.2
|
|
*
|
|
* See LICENSE for details
|
|
*/
|
|
#include <stdint.h>
|
|
#include "system.h"
|
|
#include "display.h"
|
|
#include "systick.h"
|
|
#include "button.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "ui.h"
|
|
#include "timer.h"
|
|
#include "led.h"
|
|
|
|
|
|
/* Uncomment for device initialization */
|
|
//#define DEVICE_INITIALIZATION
|
|
|
|
static const char welcome_message0[]= " Waveblender ";
|
|
static const char welcome_message1[]= "(c) danielinux ";
|
|
static const char welcome_message2[]= " GPL v.2 ";
|
|
static const char welcome_message3[]= "src: wb.vado.li";
|
|
|
|
static uint32_t last_action = 0;
|
|
static uint32_t offset = 0;
|
|
|
|
#define ST_LOCKED 0
|
|
#define ST_PIN_ENTRY 1
|
|
#define ST_UNLOCKED 2
|
|
#define MAX_PASSWORD 32
|
|
|
|
static int fsm_state = ST_LOCKED;
|
|
static int sleeping = 0;
|
|
|
|
static char password[MAX_PASSWORD] = {};
|
|
static int pin_idx = 0;
|
|
|
|
|
|
#define SLEEP_TIME (5000)
|
|
|
|
static void ui_sleep(void)
|
|
{
|
|
display_scroll(NULL, 0);
|
|
display_clear(NULL);
|
|
sleeping = 1;
|
|
}
|
|
|
|
static int ui_wakeup(void)
|
|
{
|
|
last_action = jiffies;
|
|
if (sleeping) {
|
|
sleeping = 0;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ui_msg(const char *txt)
|
|
{
|
|
ui_wakeup();
|
|
display_scroll(NULL, 0);
|
|
display_clear(NULL);
|
|
display_text(6, txt);
|
|
}
|
|
|
|
|
|
static uint8_t display_cur_v = 0;
|
|
static uint8_t menu_selection = 0;
|
|
|
|
void ui_menu_autoscroll(void)
|
|
{
|
|
int lines = CurrentMenu->entry_n;
|
|
if ((lines < 5) || (menu_selection < 2))
|
|
display_cur_v = 0;
|
|
else if (menu_selection > lines - 2)
|
|
display_cur_v = 0x40 - ((lines - 4) * 8);
|
|
else
|
|
display_cur_v = 0x40 - ((menu_selection - 2) * 8);
|
|
display_scroll(NULL, display_cur_v);
|
|
}
|
|
|
|
extern struct display_menu MainMenu;
|
|
static void ui_display_menu_refresh(void)
|
|
{
|
|
const struct display_menu *menu = CurrentMenu;
|
|
uint8_t vline;
|
|
int i;
|
|
char txt[16];
|
|
display_scroll(NULL, display_cur_v);
|
|
display_clear(NULL);
|
|
if (menu->render)
|
|
menu->render(menu);
|
|
for (i = 0; i < menu->entry_n; i++) {
|
|
vline = i + 4;
|
|
if (vline > 7)
|
|
vline -= 8;
|
|
switch (menu->entry[i].type) {
|
|
case ENTRY_TYPE_TEXT:
|
|
strncpy(txt, menu->entry[i].label, 15);
|
|
break;
|
|
case ENTRY_TYPE_HEX:
|
|
{
|
|
int x = *menu->entry[i].var ;
|
|
int j;
|
|
strncpy(txt, menu->entry[i].label, 11);
|
|
for (j = strlen(menu->entry[i].label); j < 12; j++)
|
|
txt[j] = ' ';
|
|
if (x > 0xFF) {
|
|
if (((x >> 8) & 0x0F) > 9)
|
|
txt[12] = (((x >> 8) & 0x0F) - 10) + 'A';
|
|
else
|
|
txt[12] = ((x >> 8) & 0x0F) + '0';
|
|
} else
|
|
txt[12] = ' ';
|
|
if (x > 0x0F) {
|
|
if (((x >> 4) & 0x0F) > 9)
|
|
txt[13] = (((x >> 4) & 0x0F) - 10) + 'A';
|
|
else
|
|
txt[13] = ((x >> 4) & 0x0F) + '0';
|
|
} else
|
|
txt[13] = ' ';
|
|
if ((x & 0x0F) > 9)
|
|
txt[14] = ((x & 0x0F) - 10) + 'A';
|
|
else
|
|
txt[14] = (x & 0x0F) + '0';
|
|
}
|
|
|
|
break;
|
|
case ENTRY_TYPE_BOOL:
|
|
{
|
|
int x = *menu->entry[i].var ;
|
|
int j;
|
|
strncpy(txt, menu->entry[i].label, 10);
|
|
for (j = strlen(menu->entry[i].label); j < 12; j++)
|
|
txt[j] = ' ';
|
|
if (x)
|
|
strcpy(txt + 10, "[ ON]");
|
|
else
|
|
strcpy(txt + 10, "[OFF]");
|
|
}
|
|
break;
|
|
case ENTRY_TYPE_DEC:
|
|
{
|
|
int x = *menu->entry[i].var ;
|
|
int j;
|
|
strncpy(txt, menu->entry[i].label, 11);
|
|
for (j = strlen(menu->entry[i].label); j < 12; j++)
|
|
txt[j] = ' ';
|
|
if (x > 99) {
|
|
txt[12] = (x / 100) + '0';
|
|
} else
|
|
txt[12] = ' ';
|
|
if (x > 9) {
|
|
txt[13] = ((x % 100)/10) + '0';
|
|
} else
|
|
txt[13] = ' ';
|
|
txt[14] = (x % 10) + '0';
|
|
}
|
|
break;
|
|
}
|
|
if (i == menu_selection)
|
|
display_text_inverse(vline, txt);
|
|
else
|
|
display_text(vline, txt);
|
|
}
|
|
WFI();
|
|
}
|
|
|
|
int ui_get_menu_selection(void)
|
|
{
|
|
return menu_selection;
|
|
}
|
|
|
|
void ui_display_menu(const struct display_menu *menu)
|
|
{
|
|
uint8_t i;
|
|
display_clear(NULL);
|
|
menu_selection = 0;
|
|
display_cur_v = 0;
|
|
CurrentMenu = (struct display_menu *)menu;
|
|
ui_display_menu_refresh();
|
|
}
|
|
|
|
void ui_button_press(uint8_t b, int hold)
|
|
{
|
|
int n = menu_selection;
|
|
struct display_menu_entry e;
|
|
switch (b) {
|
|
case 'U':
|
|
if (menu_selection > 0) {
|
|
menu_selection--;
|
|
ui_menu_autoscroll();
|
|
ui_display_menu_refresh();
|
|
}
|
|
break;
|
|
case 'D':
|
|
if (menu_selection < CurrentMenu->entry_n - 1) {
|
|
menu_selection++;
|
|
ui_menu_autoscroll();
|
|
ui_display_menu_refresh();
|
|
}
|
|
break;
|
|
default:
|
|
e = CurrentMenu->entry[n];
|
|
int changed = 0;
|
|
/* Default actions for '-', '+', '*' */
|
|
if (e.var && (e.type == ENTRY_TYPE_BOOL)) {
|
|
if ((*e.var) && ((b == '-') || (b == '*'))) {
|
|
*e.var = 0;
|
|
changed = 1;
|
|
} else if ((!(*e.var)) && ((b == '+') || (b == '*'))) {
|
|
*e.var = 1;
|
|
changed = 1;
|
|
}
|
|
} else if ((e.min != e.max) && e.var && ((e.type == ENTRY_TYPE_DEC) || (e.type == ENTRY_TYPE_DEC))) {
|
|
if ((*e.var > e.min) && (b == '-')) {
|
|
*e.var -= e.step;
|
|
changed = 1;
|
|
} else if ((*e.var < e.max) && (b == '+')) {
|
|
*e.var += e.step;
|
|
changed = 1;
|
|
}
|
|
}
|
|
/* Custom actions for '-', '+', '*' (after changes are applied) */
|
|
if (b != 0 && e.action) {
|
|
e.action(&e, b);
|
|
changed = 1;
|
|
}
|
|
if (changed) {
|
|
ui_display_menu_refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ui_init(void)
|
|
{
|
|
uint32_t now;
|
|
int i;
|
|
display_scroll(NULL, 0x3f);
|
|
display_text(0, welcome_message0);
|
|
display_text(1, welcome_message1);
|
|
display_text(2, welcome_message2);
|
|
display_text(3, welcome_message3);
|
|
now = jiffies;
|
|
for (i = 0x3f; i >= 0x20; i--) {
|
|
display_scroll(NULL, i);
|
|
while ((jiffies - now) < 20)
|
|
WFI();
|
|
now = jiffies;
|
|
}
|
|
for (i = display_getcontrast(NULL); i >= 0; i--) {
|
|
display_setcontrast(NULL, i);
|
|
while ((jiffies - now) < 16)
|
|
WFI();
|
|
now = jiffies;
|
|
}
|
|
display_scroll(NULL, display_cur_v);
|
|
display_clear(NULL);
|
|
display_setcontrast(NULL, 0xcf);
|
|
ui_display_menu(CurrentMenu);
|
|
now = jiffies;
|
|
for (i = 1; i < 9; i++) {
|
|
led_beat(i);
|
|
while((jiffies - now) < 100)
|
|
WFI();
|
|
now = jiffies;
|
|
}
|
|
for (i = 8; i > 0; i--) {
|
|
led_beat(i);
|
|
while((jiffies - now) < 100)
|
|
WFI();
|
|
now = jiffies;
|
|
}
|
|
led_beat(0);
|
|
}
|
|
|
|
void ui_keepalive(uint32_t timeslice)
|
|
{
|
|
}
|