ui.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * (c) danielinux 2019
  3. *
  4. * GPLv.2
  5. *
  6. * See LICENSE for details
  7. */
  8. #include <stdint.h>
  9. #include "system.h"
  10. #include "display.h"
  11. #include "systick.h"
  12. #include "button.h"
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include "ui.h"
  17. #include "timer.h"
  18. #include "led.h"
  19. /* Uncomment for device initialization */
  20. //#define DEVICE_INITIALIZATION
  21. static const char welcome_message0[]= " Waveblender ";
  22. static const char welcome_message1[]= "(c) danielinux ";
  23. static const char welcome_message2[]= " GPL v.2 ";
  24. static const char welcome_message3[]= "src: wb.vado.li";
  25. static uint32_t last_action = 0;
  26. static uint32_t offset = 0;
  27. #define ST_LOCKED 0
  28. #define ST_PIN_ENTRY 1
  29. #define ST_UNLOCKED 2
  30. #define MAX_PASSWORD 32
  31. static int fsm_state = ST_LOCKED;
  32. static int sleeping = 0;
  33. static char password[MAX_PASSWORD] = {};
  34. static int pin_idx = 0;
  35. #define SLEEP_TIME (5000)
  36. static void ui_sleep(void)
  37. {
  38. display_scroll(NULL, 0);
  39. display_clear(NULL);
  40. sleeping = 1;
  41. }
  42. static int ui_wakeup(void)
  43. {
  44. last_action = jiffies;
  45. if (sleeping) {
  46. sleeping = 0;
  47. return 1;
  48. }
  49. return 0;
  50. }
  51. void ui_msg(const char *txt)
  52. {
  53. ui_wakeup();
  54. display_scroll(NULL, 0);
  55. display_clear(NULL);
  56. display_text(6, txt);
  57. }
  58. static uint8_t display_cur_v = 0;
  59. static uint8_t menu_selection = 0;
  60. void ui_menu_autoscroll(void)
  61. {
  62. int lines = CurrentMenu->entry_n;
  63. if ((lines < 5) || (menu_selection < 2))
  64. display_cur_v = 0;
  65. else if (menu_selection > lines - 2)
  66. display_cur_v = 0x40 - ((lines - 4) * 8);
  67. else
  68. display_cur_v = 0x40 - ((menu_selection - 2) * 8);
  69. display_scroll(NULL, display_cur_v);
  70. }
  71. static void ui_display_menu_refresh(void)
  72. {
  73. const struct display_menu *menu = CurrentMenu;
  74. uint8_t vline;
  75. int i;
  76. char txt[16];
  77. display_scroll(NULL, display_cur_v);
  78. display_clear(NULL);
  79. for (i = 0; i < menu->entry_n; i++) {
  80. vline = i + 4;
  81. if (vline > 7)
  82. vline -= 8;
  83. switch (menu->entry[i].type) {
  84. case ENTRY_TYPE_TEXT:
  85. strncpy(txt, menu->entry[i].label, 15);
  86. break;
  87. case ENTRY_TYPE_HEX:
  88. {
  89. int x = *menu->entry[i].var ;
  90. int j;
  91. strncpy(txt, menu->entry[i].label, 11);
  92. for (j = strlen(menu->entry[i].label); j < 12; j++)
  93. txt[j] = ' ';
  94. if (x > 0xFF) {
  95. if (((x >> 8) & 0x0F) > 9)
  96. txt[12] = (((x >> 8) & 0x0F) - 10) + 'A';
  97. else
  98. txt[12] = ((x >> 8) & 0x0F) + '0';
  99. } else
  100. txt[12] = ' ';
  101. if (x > 0x0F) {
  102. if (((x >> 4) & 0x0F) > 9)
  103. txt[13] = (((x >> 4) & 0x0F) - 10) + 'A';
  104. else
  105. txt[13] = ((x >> 4) & 0x0F) + '0';
  106. } else
  107. txt[13] = ' ';
  108. if ((x & 0x0F) > 9)
  109. txt[14] = ((x & 0x0F) - 10) + 'A';
  110. else
  111. txt[14] = (x & 0x0F) + '0';
  112. }
  113. break;
  114. case ENTRY_TYPE_BOOL:
  115. {
  116. int x = *menu->entry[i].var ;
  117. int j;
  118. strncpy(txt, menu->entry[i].label, 10);
  119. for (j = strlen(menu->entry[i].label); j < 12; j++)
  120. txt[j] = ' ';
  121. if (x)
  122. strcpy(txt + 10, "[ ON]");
  123. else
  124. strcpy(txt + 10, "[OFF]");
  125. }
  126. break;
  127. case ENTRY_TYPE_DEC:
  128. {
  129. int x = *menu->entry[i].var ;
  130. int j;
  131. strncpy(txt, menu->entry[i].label, 11);
  132. for (j = strlen(menu->entry[i].label); j < 12; j++)
  133. txt[j] = ' ';
  134. if (x > 99) {
  135. txt[12] = (x / 100) + '0';
  136. } else
  137. txt[12] = ' ';
  138. if (x > 9) {
  139. txt[13] = ((x % 100)/10) + '0';
  140. } else
  141. txt[13] = ' ';
  142. txt[14] = (x % 10) + '0';
  143. }
  144. break;
  145. }
  146. if (i == menu_selection)
  147. display_text_inverse(vline, txt);
  148. else
  149. display_text(vline, txt);
  150. }
  151. WFI();
  152. }
  153. void ui_display_menu(const struct display_menu *menu)
  154. {
  155. uint8_t i;
  156. display_clear(NULL);
  157. menu_selection = 0;
  158. display_cur_v = 0;
  159. CurrentMenu = (struct display_menu *)menu;
  160. ui_display_menu_refresh();
  161. }
  162. void ui_button_press(uint8_t b, int hold)
  163. {
  164. int n = menu_selection;
  165. struct display_menu_entry e;
  166. switch (b) {
  167. case 'U':
  168. if (menu_selection > 0) {
  169. menu_selection--;
  170. ui_menu_autoscroll();
  171. ui_display_menu_refresh();
  172. }
  173. break;
  174. case 'D':
  175. if (menu_selection < CurrentMenu->entry_n - 1) {
  176. menu_selection++;
  177. ui_menu_autoscroll();
  178. ui_display_menu_refresh();
  179. }
  180. break;
  181. default:
  182. e = CurrentMenu->entry[n];
  183. int changed = 0;
  184. /* Default actions for '-', '+', '*' */
  185. if (e.var && (e.type == ENTRY_TYPE_BOOL)) {
  186. if ((*e.var) && ((b == '-') || (b == '*'))) {
  187. *e.var = 0;
  188. changed = 1;
  189. } else if ((!(*e.var)) && ((b == '+') || (b == '*'))) {
  190. *e.var = 1;
  191. changed = 1;
  192. }
  193. } else if ((e.min != e.max) && e.var && ((e.type == ENTRY_TYPE_DEC) || (e.type == ENTRY_TYPE_DEC))) {
  194. if ((*e.var > e.min) && (b == '-')) {
  195. *e.var -= e.step;
  196. changed = 1;
  197. } else if ((*e.var < e.max) && (b == '+')) {
  198. *e.var += e.step;
  199. changed = 1;
  200. }
  201. }
  202. /* Custom actions for '-', '+', '*' (after changes are applied) */
  203. if (b != 0 && e.action) {
  204. e.action(&e, b);
  205. changed = 1;
  206. }
  207. if (changed) {
  208. ui_display_menu_refresh();
  209. }
  210. }
  211. }
  212. void ui_init(void)
  213. {
  214. uint32_t now;
  215. int i;
  216. display_scroll(NULL, 0x3f);
  217. display_text(0, welcome_message0);
  218. display_text(1, welcome_message1);
  219. display_text(2, welcome_message2);
  220. display_text(3, welcome_message3);
  221. now = jiffies;
  222. for (i = 0x3f; i >= 0x20; i--) {
  223. display_scroll(NULL, i);
  224. while ((jiffies - now) < 20)
  225. WFI();
  226. now = jiffies;
  227. }
  228. for (i = display_getcontrast(NULL); i >= 0; i--) {
  229. display_setcontrast(NULL, i);
  230. while ((jiffies - now) < 16)
  231. WFI();
  232. now = jiffies;
  233. }
  234. display_scroll(NULL, display_cur_v);
  235. display_clear(NULL);
  236. display_setcontrast(NULL, 0xcf);
  237. ui_display_menu(CurrentMenu);
  238. now = jiffies;
  239. for (i = 1; i < 9; i++) {
  240. led_beat(i);
  241. while((jiffies - now < 10))
  242. WFI();
  243. now = jiffies;
  244. }
  245. }
  246. void ui_keepalive(uint32_t timeslice)
  247. {
  248. }