reform

MNT Reform: Open Source Portable Computer
Log (Feed) | Files | Refs (Tags) | README

menu.c (6663B)


      1 /*
      2   MNT Reform 2.0 Keyboard Firmware
      3   See keyboard.c for Copyright
      4   SPDX-License-Identifier: MIT
      5 */
      6 
      7 #include "backlight.h"
      8 #include "constants.h"
      9 #include "keyboard.h"
     10 #include "menu.h"
     11 #include "oled.h"
     12 #include "powersave.h"
     13 #include "remote.h"
     14 #include "scancodes.h"
     15 
     16 int current_menu_y = 0;
     17 int current_scroll_y = 0;
     18 int current_menu_page = 0;
     19 int8_t logo_timeout_ticks = 0;
     20 
     21 #define KEYMODS_NUM_ITEMS 5
     22 const MenuItem keymods_items[] = {
     23   { "        SHIFT        ", KEY_ESCAPE },
     24   { "        CNTRL        ", KEY_ESCAPE },
     25   { "         AGR         ", KEY_ESCAPE },
     26   { "         ALT         ", KEY_ESCAPE },
     27   { "        SUPER        ", KEY_ESCAPE },
     28 };
     29 
     30 #define HYPER_HELP_NUM_ITEMS 4
     31 const MenuItem help_items[] = {
     32   { "Delete      Backspace", KEY_ESCAPE },
     33   { "Home/End/Pg    Arrows", KEY_ESCAPE },
     34   { "Player          F7-F9", KEY_ESCAPE },
     35   { "Volume        F10-F12", KEY_ESCAPE },
     36 };
     37 
     38 #ifdef KBD_MODE_STANDALONE
     39 #define MENU_NUM_ITEMS 5
     40 const MenuItem menu_items[] = {
     41   { "Exit Menu         ESC", KEY_ESCAPE },
     42   { "Key Backlight-     F1", KEY_F1 },
     43   { "Key Backlight+     F2", KEY_F2 },
     44   { "System Status       s", KEY_S },
     45   { "USB Flashing Mode   x", KEY_X },
     46 };
     47 #else
     48 #define MENU_NUM_ITEMS 9
     49 const MenuItem menu_items[] = {
     50   { "Exit Menu         ESC", KEY_ESCAPE },
     51   { "Power On            1", KEY_1 },
     52   { "Power Off           0", KEY_0 },
     53   { "Reset               r", KEY_R },
     54   { "Battery Status      b", KEY_B },
     55   { "Key Backlight-     F1", KEY_F1 },
     56   { "Key Backlight+     F2", KEY_F2 },
     57   { "Wake              SPC", KEY_SPACE },
     58   { "System Status       s", KEY_S },
     59 
     60   // Only needed for debugging.
     61   // The keyboard will go to sleep when turning off
     62   // main system power.
     63   { "KBD Power-Off       p", KEY_P },
     64 };
     65 #endif
     66 
     67 void reset_menu() {
     68   current_scroll_y = 0;
     69   current_menu_y = 0;
     70   current_menu_page = MENU_PAGE_NONE;
     71 }
     72 
     73 void reset_and_render_menu() {
     74   reset_menu();
     75   render_menu(current_scroll_y);
     76 }
     77 
     78 void render_menu(int y) {
     79   gfx_clear();
     80   gfx_invert_row(current_menu_y-y);
     81   for (int i=0; i<MENU_NUM_ITEMS; i++) {
     82     gfx_poke_str(0,i-y,menu_items[i].title);
     83   }
     84   gfx_on();
     85   gfx_flush();
     86 }
     87 
     88 void render_keymods(int keymods) {
     89   gfx_clear();
     90   int line=0;
     91   for (int i=0; i<KEYMODS_NUM_ITEMS; i++) {
     92     if ((int)(pow(2, i)+0.5) & keymods) {
     93       gfx_poke_str(0,line++,keymods_items[i].title);
     94     }
     95 	if (line>3) break;
     96   }
     97   gfx_on();
     98   gfx_flush();
     99 }
    100 
    101 void render_help() {
    102   gfx_clear();
    103   for (int i=0; i<HYPER_HELP_NUM_ITEMS; i++) {
    104     gfx_poke_str(0,i,help_items[i].title);
    105   }
    106   gfx_on();
    107   gfx_flush();
    108 }
    109 
    110 void clear_display() {
    111   gfx_clear();
    112   gfx_flush();
    113 }
    114 
    115 // automatically refresh the current menu page if needed
    116 void refresh_menu_page() {
    117   if (current_menu_page == MENU_PAGE_BATTERY_STATUS) {
    118     remote_get_voltages();
    119   } else if (current_menu_page == MENU_PAGE_MNT_LOGO && --logo_timeout_ticks <= 0) {
    120     gfx_clear();
    121     gfx_flush();
    122     reset_menu();
    123   }
    124 }
    125 
    126 int execute_menu_function(int y) {
    127   current_menu_page = MENU_PAGE_NONE;
    128 
    129   if (y>=0 && y<MENU_NUM_ITEMS) {
    130     current_menu_page = MENU_PAGE_OTHER;
    131     return execute_meta_function(menu_items[y].keycode);
    132   }
    133   return execute_meta_function(KEY_ESCAPE);
    134 }
    135 
    136 #define BOOTLOADER_START_ADDRESS ((0x8000-0x1000) >> 1)
    137 void jump_to_bootloader(void) {
    138   ((void (*)(void))BOOTLOADER_START_ADDRESS)();
    139 }
    140 
    141 // returns 1 for navigation function (stay in meta mode), 0 for terminal function
    142 int execute_meta_function(int keycode) {
    143   if (keycode == KEY_0) {
    144     // TODO: are you sure?
    145     anim_goodbye();
    146     remote_turn_off_som();
    147     keyboard_power_off();
    148     reset_keyboard_state();
    149     // Directly enter menu again
    150     return 2;
    151   }
    152   else if (keycode == KEY_1) {
    153     kbd_brightness_init();
    154     if (remote_turn_on_som()) {
    155       anim_hello();
    156     }
    157     return 0;
    158   }
    159   else if (keycode == KEY_R) {
    160     // TODO: are you sure?
    161     remote_reset_som();
    162   }
    163   else if (keycode == KEY_SPACE) {
    164     remote_wake_som();
    165   }
    166   /*else if (keycode == KEY_V) {
    167     remote_turn_off_aux();
    168   }*/
    169 #ifndef KBD_MODE_STANDALONE
    170   else if (keycode == KEY_B) {
    171     current_menu_page = MENU_PAGE_BATTERY_STATUS;
    172     remote_get_voltages();
    173     return 0;
    174   }
    175 #endif
    176   else if (keycode == KEY_S) {
    177     remote_get_status();
    178     return 0;
    179   }
    180   else if (keycode == KEY_F1) {
    181     kbd_brightness_dec();
    182     return 1;
    183   }
    184   else if (keycode == KEY_F2) {
    185     kbd_brightness_inc();
    186     return 1;
    187   }
    188   else if (keycode == HID_KEYBOARD_SC_UP_ARROW) {
    189     current_menu_y--;
    190     if (current_menu_y<0) current_menu_y = 0;
    191     if (current_menu_y<=current_scroll_y) current_scroll_y--;
    192     if (current_scroll_y<0) current_scroll_y = 0;
    193     render_menu(current_scroll_y);
    194     return 1;
    195   }
    196   else if (keycode == HID_KEYBOARD_SC_DOWN_ARROW) {
    197     current_menu_y++;
    198     if (current_menu_y>=MENU_NUM_ITEMS) current_menu_y = MENU_NUM_ITEMS-1;
    199     if (current_menu_y>=current_scroll_y+3) current_scroll_y++;
    200     render_menu(current_scroll_y);
    201     return 1;
    202   }
    203   else if (keycode == KEY_ENTER) {
    204     return execute_menu_function(current_menu_y);
    205   }
    206   else if (keycode == KEY_ESCAPE) {
    207     clear_display();
    208   }
    209   else if (keycode == KEY_X) {
    210     gfx_clear();
    211     gfx_poke_str(1, 1, "Entered firmware");
    212     gfx_poke_str(1, 2, "update mode.");
    213     gfx_on();
    214     gfx_flush();
    215     jump_to_bootloader();
    216   }
    217   else if (keycode == KEY_L) {
    218     anim_hello();
    219     return 0;
    220   }
    221 
    222   gfx_clear();
    223   gfx_flush();
    224 
    225   return 0;
    226 }
    227 
    228 #ifndef KBD_MODE_STANDALONE
    229 void anim_kbd_hello(void) {
    230   kbd_brightness_set(0);
    231   for (int b = 0; b < 8; ++b) {
    232     kbd_brightness_inc();
    233     Delay_MS(90);
    234   }
    235   for (int b = 0; b < 4; ++b) {
    236     kbd_brightness_dec();
    237     Delay_MS(110);
    238   }
    239 }
    240 #endif
    241 
    242 void anim_hello(void) {
    243   current_menu_page = MENU_PAGE_MNT_LOGO;
    244   logo_timeout_ticks = 10; // ~30sec
    245   gfx_clear();
    246   kbd_brightness_set(0);
    247   gfx_on();
    248   for (int y=0; y<3; y++) {
    249     for (int x=0; x<12; x++) {
    250       gfx_poke(x+4,y+1,(5+y)*32+x);
    251       gfx_flush();
    252     }
    253   }
    254   for (int y=0; y<0xff; y++) {
    255     if ((y % 32) == 0) {
    256       kbd_brightness_inc();
    257     }
    258     gfx_contrast(y);
    259     Delay_MS(2);
    260   }
    261   for (int y=0; y<0xff; y++) {
    262     if ((y % 64) == 0) {
    263       kbd_brightness_dec();
    264     }
    265     gfx_contrast(0xff-y);
    266     Delay_MS(2);
    267   }
    268 }
    269 
    270 void anim_goodbye(void) {
    271   gfx_clear();
    272   gfx_on();
    273   for (int y=0; y<3; y++) {
    274     for (int x=0; x<12; x++) {
    275       gfx_poke(x+4,y+1,(5+y)*32+x);
    276     }
    277   }
    278   for (int y=0; y<3; y++) {
    279     for (int x=0; x<12; x++) {
    280       gfx_poke(x+4,y+1,' ');
    281       gfx_flush();
    282     }
    283   }
    284   int16_t brt = kbd_brightness_get();
    285   while (brt--) {
    286     kbd_brightness_dec();
    287     Delay_MS(64);
    288   }
    289   gfx_off();
    290 }
    291 /* vim: set tabstop=2:softtabstop=2:shiftwidth=2:expandtab */