diff --git a/source/io.h b/source/io.h index 9be6c98..faaf233 100644 --- a/source/io.h +++ b/source/io.h @@ -20,6 +20,9 @@ #define PIN_POWER_CTL (PORT1, 16) #define PIN_ESTOP (PORT1, 17) +#define PIN_KEY_UP (PORT0, 2) +#define PIN_KEY_DOWN (PORT0, 3) + #define _P1(p1, p2) p1 #define _P2(p1, p2) p2 diff --git a/source/keys.c b/source/keys.c index 8f9db51..5633587 100644 --- a/source/keys.c +++ b/source/keys.c @@ -18,6 +18,7 @@ #include "keys.h" #include "timer.h" +#include "io.h" /******************************************************************************* * Definitions diff --git a/source/keys.h b/source/keys.h index 4024951..9646062 100644 --- a/source/keys.h +++ b/source/keys.h @@ -12,7 +12,7 @@ #define KEY_NUM 6 //number of keys /* Key event_bits structure - * bits 0 - 5 are KEY0 - 5 long presses + * bits 0 - 5 are KEY0 - 5 short presses * bits 6 - 11 are KEY0 - 5 long presses * KEY_SHORT_PRESS is 0 and KEY_LONG_PRESS is 6 * Accessing key data: diff --git a/source/main.c b/source/main.c index f776457..a258725 100644 --- a/source/main.c +++ b/source/main.c @@ -257,25 +257,6 @@ uint32_t tmp; - if (sys.guiMode == GUI_MODE_MENU) - { - Menu_service(); - } - else - { - switch(KEY_GetPressed()) - { - case MENU_KEY: - { - - Menu_mainMenu(); - break; - - } - } - Display_Update(); - } - #if !BYPASS_USB_SAFETY if((tickCount++ % 10 == 0) && !GPIO_READ(PIN_VBUS)) //every 10 ticks = 100mS AND !USB @@ -284,6 +265,28 @@ uint32_t tmp; #endif { + uint32_t pressed = 0; + + if (sys.guiMode == GUI_MODE_MENU) + { + Menu_service(); + } + else + { + pressed = KEY_GetPressed(); + + switch(pressed) + { + case MENU_KEY: + { + + Menu_mainMenu(); + break; + + } + } + Display_Update(); + } switch (Task) @@ -300,7 +303,7 @@ uint32_t tmp; break; case PRIMARY_TASK: - //pro_key(); // process primary keys front 6 first menu + pro_key(pressed); // process primary keys front 6 first menu break; case MENU_TASK: // Allows user to select options diff --git a/source/menu.c b/source/menu.c index 35fa954..3acac0a 100644 --- a/source/menu.c +++ b/source/menu.c @@ -33,6 +33,7 @@ #include "menu.h" #include "ports.h" #include "display.h" +#include "io.h" /******************************************************************************* * Definitions @@ -40,38 +41,7 @@ #define MENU_TIMER_PERIOD_MS (100) //100mS for 10Hz update -#define MENU_STACK_SIZE 4 -#define MENU_ITEM_SIZE 10 -typedef struct Menu_s Menu_t; - -typedef int (*MenuHandler_t)(Menu_t *menu); - - -struct Menu_s -{ - MenuHandler_t handler; - bool init; - bool draw; - int selected; - MENU_ITEM_t items[MENU_ITEM_SIZE]; - int itemCount; - int displayIndex; - -}; - -typedef struct MenuData_s -{ - int stackCount; - Menu_t menuStack[MENU_STACK_SIZE]; - Menu_t *currentMenu; - -} MenuData_t; - - -typedef struct { - bool exitToMainScreen; -} MENU_t; @@ -90,9 +60,9 @@ static MenuData_t _menuData; MENU_t menu; -MENU_ITEM_t mainMenu[MAIN_MENU_NUM_TX10]; -MENU_ITEM_t linkMenu[LINK_MENU_NUM]; -MENU_ITEM_t langMenu[LANG_MENU_NUM]; +MenuItem_t mainMenu[MAIN_MENU_NUM_TX10]; +MenuItem_t linkMenu[LINK_MENU_NUM]; +MenuItem_t langMenu[LANG_MENU_NUM]; extern const char *languageNames[]; @@ -109,7 +79,7 @@ extern uint8_t Dds_Pot_Val[]; extern uint8_t Port_State[]; extern HARDWARE_FIX_t hwf; - +extern uint32_t systemTime; @@ -117,9 +87,10 @@ extern HARDWARE_FIX_t hwf; * Static Function Declarations ******************************************************************************/ + static Menu_t* getNewMenu(MenuHandler_t handler); +static int handleSystemInfoMenu(Menu_t *menu); - -static void ClearMenuItems(MENU_ITEM_t items[], uint32_t num); +static void ClearMenuItems(MenuItem_t items[], uint32_t num); static void DrawMenuScrollBar(uint32_t displayIndex, uint32_t numItems); @@ -141,68 +112,121 @@ static void DisplayRegulatoryInfo(void); /******************************************************************************* * Static Functions ******************************************************************************/ - -static int handleMainMenu(Menu_t *menu) +static void createMenuItem(MenuItemId_t id, MenuItem_t *item) { - if (menu->init) + + item->id = id; + switch (id) { - int itemCount = 0; + case MENU_ID_SYSINFO: + { + item->pMonoIcon = menuMore; + strcpy(item->text, "System Information"); + item->handler = handleSystemInfoMenu; + break; + } - menu->items[itemCount].pMonoIcon = menuMore; - menu->items[itemCount].id = MENU_ID_SYSINFO; - strcpy(menu->items[itemCount].text, "System Information"); //System info screen - itemCount++; + case MENU_ID_FREQUENCIES: + { + item->pMonoIcon = menuMore; + strcpy(item->text, "Frequencies"); + break; + } - menu->items[itemCount].pMonoIcon = menuMore; - menu->items[itemCount].id = MENU_ID_FREQUENCIES; - strcpy(menu->items[itemCount].text, "Frequencies"); //Frequency Selection Menu - itemCount++; + case MENU_ID_AUTOSHUTDOWN: + { + item->pMonoIcon = 0; + strcpy(item->text, "Auto Shutdown"); + break; + } - menu->items[itemCount].pMonoIcon = 0; - menu->items[itemCount].id = MENU_ID_AUTOSHUTDOWN; - strcpy(menu->items[itemCount].text, "Auto Shutdown"); //Auto Shutdown selection - itemCount++; + case MENU_ID_LANGUAGE: + { + item->pMonoIcon = menuMore; + strcpy(item->text, "Language"); + break; + } + } + +} - menu->items[itemCount].pMonoIcon = menuMore; - menu->items[itemCount].id = MENU_ID_LANGUAGE; - strcpy(menu->items[itemCount].text, "Language"); //Language Selection Menu - itemCount++; - - menu->itemCount = itemCount; - menu->init = false; - - menu->draw = true; +static void handleUpDown(uint32_t pressed, Menu_t *menu) +{ + switch (menu->longPress) + { + case (KEY_UP << KEY_LONG_PRESS): + { + if (!GPIO_READ(PIN_KEY_UP)) + { + if (systemTime >= menu->nextRepeat) + { + pressed = KEY_UP; + menu->nextRepeat = systemTime + 100; + } + } + else + { + menu->longPress = 0; + } + break; + } + case (KEY_DOWN << KEY_LONG_PRESS): + { + if (!GPIO_READ(PIN_KEY_DOWN)) + { + if (systemTime >= menu->nextRepeat) + { + pressed = KEY_DOWN; + menu->nextRepeat = systemTime + 100; + } + } + else + { + menu->longPress = 0; + } + break; + } } - - switch(KEY_GetPressed()) + switch(pressed) { case KEY_UP: { - if(--menu->selected < 0) + menu->selected--; + + if(menu->selected < 0) { menu->selected = 0; } menu->draw = true; break; } + case KEY_DOWN: { - if(++menu->selected >= menu->itemCount) + menu->selected++; + + if(menu->selected >= menu->itemCount) { menu->selected = menu->itemCount - 1; } menu->draw = true; + + break; + } + + case (KEY_UP << KEY_LONG_PRESS): + case (KEY_DOWN << KEY_LONG_PRESS): + { + menu->longPress = pressed; + menu->nextRepeat = 0; break; } } if (menu->draw) { - - LCD_Clear(); - if(menu->selected >= (menu->displayIndex + MENU_MAX_LINES_DISPLAYED)) { menu->displayIndex++; @@ -211,10 +235,181 @@ static int handleMainMenu(Menu_t *menu) { menu->displayIndex--; } + } +} + +static void drawScrollBar(Menu_t *menu) +{ + DrawMenuScrollBar(menu->displayIndex, menu->itemCount); +} + +static Menu_t* getNewMenu(MenuHandler_t handler) +{ + Menu_t *menu = NULL; + + if (_menuData.stackCount < MENU_STACK_SIZE) + { + + menu = &_menuData.menuStack[_menuData.stackCount]; + menu->handler = handler; + menu->init = true; + menu->selected = 0; + menu->displayIndex = 0; + menu->exitCode = MENU_OK; + + _menuData.currentMenu = menu; + + _menuData.stackCount++; + + } + + return menu; +} + +static int handleSystemInfoMenu(Menu_t *menu) +{ + if (menu == NULL) + { + menu = getNewMenu(handleSystemInfoMenu); + + if (menu == NULL) + { + return MENU_EXIT; + } + } + + if (menu->init) + { + int itemCount = 0; + + createMenuItem(MENU_ID_SYSINFO , &menu->items[itemCount++]); + createMenuItem(MENU_ID_FREQUENCIES , &menu->items[itemCount++]); + + menu->itemCount = itemCount; + menu->init = false; + menu->draw = true; + + } + + uint32_t pressed = KEY_GetPressed(); + + handleUpDown(pressed, menu); + + if (pressed == KEY_BACK) + { + menu->exitCode = MENU_EXIT; + } + else + if (pressed == KEY_ENTER) + { + if (menu->items[menu->selected].handler != NULL) + { + menu->items[menu->selected].handler(NULL); + } + } + + if (menu->draw) + { + + LCD_Clear(); + + // Draw menu items - MENU_ITEM_t *item; + MenuItem_t *item; + + for(uint32_t i = menu->displayIndex; i < menu->displayIndex + menu->itemCount; i++) //this can draw extra lines off the screen but we don't care + { + item = &menu->items[i]; + + //Menu strings + FL_DrawTranslatedString(item->text, MENU_MAIN_TEXT_X, MENU_MAIN_TEXT_Y_START + (i-menu->displayIndex)*MENU_LINE_HEIGHT, MENU_FONT, LCD_DRAW_SET, FL_ALIGN_LEFT); + + + // Draw item status + if (item->pMonoIcon != NULL) + { + GL_DrawMonoBitmap(item->pMonoIcon, MENU_MAIN_STATUS_X, MENU_MAIN_TEXT_Y_START + (i-menu->displayIndex)*MENU_LINE_HEIGHT + MENU_MAIN_STATUS_Y_OFF, LCD_DRAW_SET); + } + + + } + + //Draw selection bar + uint32_t selRectY0 = MENU_MAIN_TEXT_Y_START + (menu->selected - menu->displayIndex)*MENU_LINE_HEIGHT; + GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); + + drawScrollBar(menu); + + LCD_Update(); + + menu->draw = false; + } + + return menu->exitCode; + + //SystemInfoMenu(); +} + +static int handleMainMenu(Menu_t *menu) +{ + if (menu == NULL) + { + // get new menu on stack and init + menu = getNewMenu(handleMainMenu); + //menu->handler = handleMainMenu; + + } + + if (menu->init) + { + int itemCount = 0; + + + createMenuItem(MENU_ID_SYSINFO , &menu->items[itemCount++]); + createMenuItem(MENU_ID_FREQUENCIES , &menu->items[itemCount++]); + createMenuItem(MENU_ID_AUTOSHUTDOWN , &menu->items[itemCount++]); + createMenuItem(MENU_ID_LANGUAGE , &menu->items[itemCount++]); + + createMenuItem(MENU_ID_SYSINFO , &menu->items[itemCount++]); + createMenuItem(MENU_ID_FREQUENCIES , &menu->items[itemCount++]); + createMenuItem(MENU_ID_AUTOSHUTDOWN , &menu->items[itemCount++]); + createMenuItem(MENU_ID_LANGUAGE , &menu->items[itemCount++]); + + menu->itemCount = itemCount; + menu->init = false; + menu->draw = true; + + } + + uint32_t pressed = KEY_GetPressed(); + + handleUpDown(pressed, menu); + + if (pressed == KEY_BACK) + { + menu->exitCode = MENU_EXIT; + } + else + if (pressed == KEY_ENTER) + { + if (menu->items[menu->selected].handler != NULL) + { + menu->items[menu->selected].handler(NULL); + return MENU_OK; + } + } + + + if (menu->draw) + { + + LCD_Clear(); + + + // Draw menu items + MenuItem_t *item; for(uint32_t i = menu->displayIndex; i < menu->displayIndex + menu->itemCount; i++) //this can draw extra lines off the screen but we don't care { @@ -242,10 +437,7 @@ static int handleMainMenu(Menu_t *menu) uint32_t selRectY0 = MENU_MAIN_TEXT_Y_START + (menu->selected - menu->displayIndex)*MENU_LINE_HEIGHT; GL_DrawFilledRectangle(MENU_SEL_RECT_X0, selRectY0, MENU_SEL_RECT_X1, selRectY0 + MENU_LINE_HEIGHT, LCD_DRAW_XOR); - //Draw menu icons - //Use DrawMenuBitmap(mainMenu[i], x, y) - - //DrawMenuScrollBar(displayIndex, menuNum); + drawScrollBar(menu); LCD_Update(); @@ -254,19 +446,18 @@ static int handleMainMenu(Menu_t *menu) - return 0; + return menu->exitCode; } //Clear an array of MENU_ITEM_t -static void ClearMenuItems(MENU_ITEM_t items[], uint32_t num) +static void ClearMenuItems(MenuItem_t items[], uint32_t num) { for(uint32_t i = 0; i < num; i++) { - items[i].pMonoIcon = 0; //Init mono icon pointer to null - - items[i].text[0] = 0; //Init first char to null + items[i].pMonoIcon = NULL; //Init mono icon pointer to null + items[i].text[0] = NULL; //Init first char to null } } @@ -1266,10 +1457,12 @@ void Menu_init(void) for (int i=0; ihandler = handleMainMenu; - menu->selected = 0; - menu->init = true; - - _menuData.currentMenu = menu; } void Menu_service(void) { + int exitCode = MENU_OK; + // run the menu state machine and prevent blocking if (_menuData.currentMenu != NULL) { - _menuData.currentMenu->handler(_menuData.currentMenu); + exitCode = _menuData.currentMenu->handler(_menuData.currentMenu); + + switch (exitCode) + { + case MENU_HOME: + { + _menuData.stackCount = 0; + break; + } + + case MENU_EXIT: + { + // pop the menu off the stack + _menuData.stackCount--; + + if (_menuData.stackCount > 0) + { + _menuData.currentMenu = &_menuData.menuStack[_menuData.stackCount-1]; + _menuData.currentMenu->draw = true; + } + break; + } + } + + if (_menuData.stackCount == 0) + { + sys.guiMode = GUI_MODE_NORMAL; + } } } diff --git a/source/menu.h b/source/menu.h index a95067c..57e9c15 100644 --- a/source/menu.h +++ b/source/menu.h @@ -60,6 +60,12 @@ #define MENU_SEL_RECT_RADIUS 5 +#define MENU_STACK_SIZE 4 +#define MENU_ITEM_SIZE 10 + +typedef struct Menu_s Menu_t; +typedef int (*MenuHandler_t)(Menu_t *menu); + typedef enum { MENU_ID_NONE = 0, @@ -75,8 +81,44 @@ typedef struct MENU_ITEM_s uint32_t * pMonoIcon; // bitmap char text[MENU_MAX_STRING_LENGTH]; MenuItemId_t id; + int (*handler)(Menu_t *menu); -} MENU_ITEM_t; +} MenuItem_t; + +typedef enum +{ + MENU_OK = 0, + MENU_HOME, + MENU_EXIT +} MenuExitCode_t; + +struct Menu_s +{ + MenuHandler_t handler; + bool init; + bool draw; + int selected; + MenuItem_t items[MENU_ITEM_SIZE]; + int itemCount; + int displayIndex; + int exitCode; + int nextRepeat; + uint32_t longPress; + +}; + +typedef struct MenuData_s +{ + int stackCount; + Menu_t menuStack[MENU_STACK_SIZE]; + Menu_t *currentMenu; + +} MenuData_t; + + +typedef struct { + bool exitToMainScreen; +} MENU_t; void Menu_init(void); diff --git a/source/pro_key.c b/source/pro_key.c index a66c4be..cc5b06f 100644 --- a/source/pro_key.c +++ b/source/pro_key.c @@ -26,11 +26,11 @@ uint8_t keyval; extern uint8_t Port_State[]; #if 1 -void pro_key(void) +void pro_key(uint32_t pressed) { uint32_t tmp_frqx; - switch(KEY_GetPressed())//(key_bits) + switch(pressed)//(key_bits) { //TODO: cases need to use the key #defines from keys.c and keys.h case ON_OFF_KEY: // Begin Primary Key @@ -75,9 +75,9 @@ void pro_key(void) break; - case MENU_KEY: - Task = MENU_TASK; // display the menus - break; + // case MENU_KEY: + // Task = MENU_TASK; // display the menus + // break; case MODE_KEY: // End Primary Key diff --git a/source/pro_key.h b/source/pro_key.h index 5cd9b72..392c458 100644 --- a/source/pro_key.h +++ b/source/pro_key.h @@ -19,7 +19,7 @@ -void pro_key(void); +void pro_key(uint32_t pressed); void LD_key_process(void); #endif /* PRO_KEY_H_ */ diff --git a/source/testMenu.c b/source/testMenu.c index e2a06b3..bd9171e 100644 --- a/source/testMenu.c +++ b/source/testMenu.c @@ -43,8 +43,8 @@ * Variables ******************************************************************************/ -MENU_ITEM_t testMenu[TEST_MENU_NUM]; -MENU_ITEM_t hwFixMenu[HWFIX_MENU_NUM]; +MenuItem_t testMenu[TEST_MENU_NUM]; +MenuItem_t hwFixMenu[HWFIX_MENU_NUM]; uint8_t * fixStrings[] = {"NOT YET...", "DONE"}; //1 = fix done uint8_t * onOffStrings[] = {"OFF", "ON"}; //1 = on @@ -56,7 +56,7 @@ extern uint8_t Diag_Flag; * Static Function Declarations ******************************************************************************/ -static void ClearTestMenuItems(MENU_ITEM_t items[], uint32_t num); +static void ClearTestMenuItems(MenuItem_t items[], uint32_t num); static uint8_t * GetFixStatusString(uint32_t index); static void HwFixMenu(void); static void DisplayHwFixMenu(uint32_t selected); @@ -68,7 +68,7 @@ static void DrawTestMenuScrollBar(uint32_t displayIndex, uint32_t numItems); ******************************************************************************/ //Clear an array of MENU_ITEM_t -static void ClearTestMenuItems(MENU_ITEM_t items[], uint32_t num) +static void ClearTestMenuItems(MenuItem_t items[], uint32_t num) { for(uint32_t i = 0; i < num; i++) {