Library which creates a serial test console, it supports pages and menu items. The items are added and the pages are added as necessary when the user sets it up. This is a great too for creating an easy to maintain menu system, whether for a test sytem, or anything else.
Dependencies: Terminal
Revision 6:e992366d0684, committed 2015-05-04
- Comitter:
- glansberry
- Date:
- Mon May 04 14:43:35 2015 +0000
- Parent:
- 5:4a240f717b9d
- Child:
- 7:903c8e16ed25
- Commit message:
- Modified to make terminal embedded in TestConsole class; More changes for debugging
Changed in this revision
--- a/menuitem.cpp Sat May 02 00:41:23 2015 +0000 +++ b/menuitem.cpp Mon May 04 14:43:35 2015 +0000 @@ -24,7 +24,7 @@ {} MenuItem::MenuItem(Page &target_page_p): - name(target_page_p.Name), + name(target_page_p.name), level(0), type(menu), action(NULL),
--- a/menuitem.h Sat May 02 00:41:23 2015 +0000 +++ b/menuitem.h Mon May 04 14:43:35 2015 +0000 @@ -9,6 +9,8 @@ typedef char * (*callback_function)(bool); // type for conciseness #define MAX_NAME_LEN (80-10-10) +#define MAKE_PORT(x, io) (new Menu##io(#x, io(x))) //use this macro to create a port (it saves name as well as creatign the IO +#define REUSE_PORT(x, io, port) (new Menu##io(#x, port)) //use this macro if you created the port externally class MenuAction; class Page;
--- a/page.cpp Sat May 02 00:41:23 2015 +0000 +++ b/page.cpp Mon May 04 14:43:35 2015 +0000 @@ -1,17 +1,19 @@ #include "page.h" - //default constructor + //default constructor Page::Page() : - make_active_flag(false), - Name(NULL), + make_active_flag(false), + name(NULL), + term(NULL), num_menuitems(0), data_start_x(0), page_num(0) - {} + {} -Page::Page(const char * Name_p): - make_active_flag(false), - Name(Name_p), +Page::Page(const char * name_p, Terminal * term_p): + make_active_flag(false), + name(name_p), + term(term_p), num_menuitems(0), data_start_x(0), max_upper_letter_cmd('A'-1), @@ -19,7 +21,7 @@ max_number_cmd('1'-1), page_num(0) { - term.printf("Page::Page('%s')\n",Name); + // term->printf("Page::Page('%s')\r\n",name); } Page& Page::add(MenuItem const &item_p) { @@ -50,31 +52,32 @@ } } - term.printf("Added menu item '%s' as index %d cmd %c\n", active_item->name, num_menuitems++, command_letter[num_menuitems]); + //term->printf("Added menu item '%s' as index %d cmd %c to page %s\r\n", active_item->name, num_menuitems, command_letter[num_menuitems], name); + num_menuitems++;; } - else term.printf("Failed to add menu item #%d, '%s'\n", num_menuitems, item_p.name); + else term->printf("Failed to add menu item #%d, '%s'\r\n", num_menuitems, item_p.name); return *this; } void Page::display(void){ - term.cls(); - term.HideCursor(); - term.locate(0,0); - term.printf("%s",Name); + term->cls(); + term->HideCursor(); + term->locate(0,0); + term->printf("%s",name); int index; for (index=0; index < num_menuitems; index++){ - term.locate(LEVEL_INDENT*(item[index].level+1),index+ITEM_ROW_START); + term->locate(LEVEL_INDENT*(item[index].level+1),index+ITEM_ROW_START); //don't print command letter for messages without them - if(command_letter[index] != 0) term.printf("%c) ", command_letter[index]); + if(command_letter[index] != 0) term->printf("%c) ", command_letter[index]); - term.printf("%s", item[index].name); + term->printf("%s", item[index].name); } index++; //add a space before the return line - term.locate(LEVEL_INDENT,index+ITEM_ROW_START); - term.printf("x) Back to previous page"); + term->locate(LEVEL_INDENT,index+ITEM_ROW_START); + term->printf("x) Back to previous page"); update(); } // Update the data on the Page @@ -83,11 +86,11 @@ for (int index=0; index < num_menuitems; index++){ if(!item[index].action) continue; - term.locate(data_start_x,index+ITEM_ROW_START); + term->locate(data_start_x,index+ITEM_ROW_START); item[index].action->getString(buf, sizeof(buf)); - term.printf("%s", buf); + term->printf("%s", buf); } - term.HideCursor(); + term->HideCursor(); }
--- a/page.h Sat May 02 00:41:23 2015 +0000 +++ b/page.h Mon May 04 14:43:35 2015 +0000 @@ -16,11 +16,12 @@ class Page{ private: - bool make_active_flag; + bool make_active_flag; public: Page(); - Page(const char * Name_p); - const char * Name; //reference to the name of the Page + Page(const char * name_p, Terminal * term_p); + const char * name; //reference to the name of the Page + Terminal * term; int num_menuitems; int data_start_x; //starting column for printing the data MenuItem item[MAX_MENUITEMS]; @@ -30,7 +31,7 @@ char max_number_cmd; int page_num; bool refresh_required; - Page& add(Page &page_p) { return add(MenuItem(page_p)); } + Page& add(Page *page_p) { return add(MenuItem((*page_p))); } Page& add(char const *text) { return add(MenuItem(text, NULL, 0, heading)); } Page& add(char const *text, MenuAction *action_p) { return add(MenuItem(text, action_p, 0, ::display, -1)); } Page& add(MenuItem const &item_p);
--- a/test_main.cpp Sat May 02 00:41:23 2015 +0000 +++ b/test_main.cpp Mon May 04 14:43:35 2015 +0000 @@ -1,13 +1,13 @@ #ifdef TEST //define test to make this an active main #include <mbed.h> #include "Terminal.h" -#include "SerialTerm.h" -#include "ASCIIGraph.h" #include "testconsole.h" #include "page.h" #include "menuitem.h" -Terminal term(SERIAL_TX, SERIAL_RX); + + +Terminal term(DEBUG_TX, DEBUG_RX); Ticker heartbeat; @@ -23,31 +23,6 @@ else ERROR_Overrun++ ; } -//prototype callback for the menu system, if the command key has been pressed, then cmd is true -//otherwise it should simple return a string that gets printed -char * test_callback(bool cmd){ - - static int i; - static bool count = true; - static char buffer[20]; - - if(cmd) { - term.locate(TERM_LOC_DEBUG); - term.printf("test_callback"); - } - if(cmd) count = !count; - - if(count) i++; - - sprintf(buffer, "%d", i); - return buffer; - } - -char * null_callback(bool cmd){ - - return NULL; - } - int main(void){ @@ -55,34 +30,48 @@ //create the Pages for the console // term.printf("\nsizeof page %d, menuitem %d\n",sizeof(Page), sizeof(MenuItem)); - TestConsole console("Test Program"); + TestConsole console("KV2 Test Program"); Page &pageHome = console.add_page(Page("Home")); - Page &pagePower = console.add_page(Page("Page1")); - Page &pageBattery = console.add_page(Page("Page2")); - Page &pageAccel = console.add_page(Page("Page3")); - - // pageHome.add_item(MenuItem(pagePower.Name, &pagePower.set_active(), 0, menu)); - #define CREATE_PAGE_SELECT_MENU_ITEM(x) add_item(MenuItem(x.Name, x.page_num)); - pageHome.CREATE_PAGE_SELECT_MENU_ITEM(pagePower); - pageHome.CREATE_PAGE_SELECT_MENU_ITEM(pageBattery); - pageHome.CREATE_PAGE_SELECT_MENU_ITEM(pageAccel); - - - pagePower.add_item(MenuItem("Display", NULL, 0, heading)); - pagePower.add_item(MenuItem("Eject Button Status", test_callback, 0, display)); + Page &page1 = console.add_page(Page("Page1")); + Page &page2 = console.add_page(Page("Page2")); + + // pageHome.add(pagePower.Name, &pagePower.set_active(), 0, menu)); + pageHome + .add(page1) + .add(page2) + +//These macros are actually in the menuitem.h file but commented here below for reference +//#define MAKE_PORT(x, io) (new Menu##io(#x, io(x))) //use this macro to create a port (it saves name as well as creatign the IO +//#define REUSE_PORT(x, io, port) (new Menu##io(#x, port)) //use this macro if you created the port externally + - pageBattery.add_item(MenuItem("Display", NULL, 0, heading)); - pageBattery.add_item(MenuItem("Battery Voltage", test_callback, 0, display)); + page1 + .add("DISPLAY") + .add("Eject Button Status", MAKE_PORT(PA_1, DigitalIn)) + .add("Push button status", MAKE_PORT(PUSH_BUT_IN, DigitalIn)) + .add("Battery voltage", MAKE_PORT(A1, AnalogIn)) + .add("Dock sense", MAKE_PORT(PA_2, DigitalIn)) + .add("CONTROL") + .add("MCU regulator disable", MAKE_PORT(PA_3, DigitalOut)) + .add("Battery Read Enable", MAKE_PORT(PA_4, DigitalOut)) + .add("Dock Read Enable", MAKE_PORT(PA_5, DigitalOut)); - pageAccel.add_item(MenuItem("Display", NULL, 0, heading)); - pageAccel.add_item(MenuItem("Battery Voltage", test_callback, 0, display)); + + page2 + .add("DISPLAY") + .add("Battery voltage", MAKE_PORT(A0, AnalogIn)) + .add("Accumulated Charge", new MenuNotImplementedAction("N/A")) + .add("CHRG line", MAKE_PORT(PA_0, DigitalIn)) + .add("High/Low Charge thresholds", new MenuNotImplementedAction("N/A")) + .add("Status Register", new MenuNotImplementedAction("N/A")) + .add("Control Register", new MenuNotImplementedAction("N/A")); heartbeat.attach(&tick_int, 0.1); // the address of the function to be attached (tick_int) and the interval 10000uS - wait(2); //give the man a chance to read the messages, if any + wait(2); while(1) {
--- a/testconsole.cpp Sat May 02 00:41:23 2015 +0000 +++ b/testconsole.cpp Mon May 04 14:43:35 2015 +0000 @@ -1,41 +1,53 @@ #include "testconsole.h" -TestConsole::TestConsole(const char * Name_p): - Name(Name_p), +TestConsole::TestConsole(const char * name_p, PinName tx, PinName rx, int baud_rate): + term(tx, rx), + name(name_p), num_pages(0), current_page(0) { - - // term.printf("TestConsole::TestConsole('%')\n",Name); + term.baud(baud_rate); + active_page = page[current_page]; + // term.printf("TestConsole::TestConsole('%')\r\n",name); term.HideCursor(); - page_change(current_page); + for(int i = 0; i < MAX_PAGES; i++) page[i] = NULL; //init all pages to NULL } -Page& TestConsole::add_page(Page const &page_p){ -term.printf("TestConsole::add_page\n"); - if(num_pages < MAX_PAGES) { - page[num_pages] = page_p; - page[num_pages].page_num = num_pages; //let the page know what number it is to help with lookups +//Page& TestConsole::add_page(Page const &page_p){ +Page* TestConsole::add_page(const char * name_p){ + if(num_pages >= MAX_PAGES) + { + term.printf("MAX_PAGES Exceeded adding'%s'\r\n", name_p); + return NULL; //return valid reference to home page on + + } + + page[num_pages] = new Page(name_p, &term); + Page* this_page = page[num_pages]; + this_page->page_num = num_pages; //let the page know what number it is to help with lookups if(num_pages == 0) { //if this is the first page, set it active - page[num_pages].set_active(); + this_page->set_active(); } - term.printf("Added page '%s'\n", page[num_pages].Name); - return page[num_pages++]; - } - - term.printf("Failed to add page'%s'\n", page_p.Name); - return page[MAX_PAGES-1]; //return 0 if no error + //term.printf("Added page '%s'\r\n", this_page->name); + num_pages++; + return this_page; } int TestConsole::page_change(int new_page){ + if(NULL == page[current_page]) { + term.printf("invalid page passed to page_chage\r\n"); + return current_page; + } previous_page = current_page; //save a copy of the page so we can go back current_page = new_page; - page[current_page].display(); + active_page = page[current_page]; + + active_page->display(); - page[current_page].ack_active(); + active_page->ack_active(); return current_page; } @@ -45,7 +57,7 @@ page_change(previous_page); return 0; } - Page* active_page = &page[current_page]; + for(int index=0; index < active_page->num_menuitems; index++) { MenuItem *item = &active_page->item[index]; if(active_page->command_letter[index] != cmd) continue; @@ -72,11 +84,15 @@ } //go through the list of pages, and see if any want to become active - for(int index=0; index < page[current_page].num_menuitems; index++){ - if(page[index].check_active()) page_change(index); + for(int index=0; index < num_pages; index++){ + if(active_page->check_active()){ + page_change(index); + term.locate((TERMINAL_WIDTH - strlen(name))/2, 0); + term.printf("%s", name); + } } - page[current_page].update(); + active_page->update(); return 0; }
--- a/testconsole.h Sat May 02 00:41:23 2015 +0000 +++ b/testconsole.h Mon May 04 14:43:35 2015 +0000 @@ -1,18 +1,22 @@ #ifndef __TESTCONSOLE_H #define __TESTCONSOLE_H - +#include "Terminal.h" #include "page.h" #include "menuitem.h" #define MAX_PAGES 9 +#define TERMINAL_WIDTH 80 class TestConsole { + private: + Page* active_page; public: - TestConsole(const char * Name_p); - const char * Name; //reference to the name of the Program + TestConsole(const char * Name_p, PinName tx, PinName rx, int baud_rate); + Terminal term; + const char * name; //reference to the name of the Program int num_pages; int current_page, previous_page; - Page page[MAX_PAGES]; - Page& add_page(Page const &page_p); + Page * page[MAX_PAGES]; + Page * add_page(const char * name_p); int process_cmd(char cmd); int tick(); int page_change(int page);