![](/media/cache/group/download_IjbieK2.png.50x50_q85.png)
demo new haven display
Dependencies: LCD Menu ButtonCtrl TimeManagement EventLog AddressMap emic2
ESCM 2000 Control and Display application provides interface for the LPC1768 processor boards with the ECSM 2000 system.
This application implements SW interface : - RX 485 Receive from physical system - RX 485 Interface to send toECOM / ESCM board - CAN Interface to send to ECOM / ESCM board - 4x40 LCD with menu controls - RTC configuration -EMIC2 Sound Card - GPIO Extender to push buttons etc
Diff: main.cpp
- Revision:
- 5:65f21c0b6b79
- Parent:
- 3:ecaf9963341b
- Child:
- 6:010ceb99f7b0
--- a/main.cpp Thu Jul 25 00:46:02 2019 +0000 +++ b/main.cpp Thu Sep 12 11:28:26 2019 +0000 @@ -1,5 +1,6 @@ #include "mbed.h" #include "rtos.h" +#include "stats_report.h" #include "LCD.h" @@ -9,14 +10,12 @@ #include "Menu.h" #include "EditTimeMenu.h" +#include "EditAddressMenu.h" #include "DisplayCodesMenu.h" +#include "FactoryResetMenu.h" -//#include "EditDateMenu.h" -//#include "EditAddressMenu.h" -//#include "DisplayFaultAddressMenu.h" - -#include "Navigator.h" -#include "Selection.h" +#define SLEEP_TIME 500 // (msec) +#define PRINT_AFTER_N_LOOPS 20 DigitalOut led1(LED1); DigitalOut led2(LED2); @@ -24,120 +23,86 @@ DigitalOut led4(LED4); -Thread gpioThread (osPriorityHigh, 2000); - -Thread ioThread (osPriorityHigh, 2000); - -Thread soundThread(osPriorityLow, 2000); - -Thread displayThread(osPriorityNormal, 2000); - - -//EventQueue messageQueue(32 * EVENTS_EVENT_SIZE); - -typedef struct { - int event; - char msg[40]; -} event_t; - - - -CircularBuffer<event_t, 64> event_queue; -CircularBuffer<event_t, 64> playback_queue; - - Serial pc(USBTX, USBRX); // tx, rx +/*------------------------------------------------------------------- + * define displays + *-------------------------------------------------------------------*/ + LCD lcd; +#define MAX_THREADS 6 +Thread * threads [MAX_THREADS]; +/*------------------------------------------------------------------- + * define displays + *-------------------------------------------------------------------*/ + +Menu rootMenu ("root menu"); +EditTimeMenu editTime ("Edit Time"); +EditAddressMenu editAddress ("Edit Addresses"); +DisplayCodesMenu showEvents ("Display Events" ); +FactoryResetMenu factoryReset("Factory Reset" ); +/*------------------------------------------------------------------- + * define display escmBtnController + *-------------------------------------------------------------------*/ +ButtonController escmBtnController; + +/*------------------------------------------------------------------- + * define application + *-------------------------------------------------------------------*/ +ESCMControlApp escmController; -Menu rootMenu ("root menu"); -EditTimeMenu editTime ("Edit Time"); -//EditDateMenu editDate ("Edit Date"); -//EditAddressMenu editAdress ("Edit Addresses"); - -DisplayCodesMenu showEvents ("Display Events" ); +int dataRxCnt = 0; - -Navigator navigator(&rootMenu, &lcd); - - -Menu * currentMenu = &showEvents; - -ButtonController controller(&navigator); - +int cur_address = 0; -ESCMControlApp escmController; +/*------------------------------------------------------------------- + * define led toggles for diagnostics + *-------------------------------------------------------------------*/ +void toggleLed1(){ led1 = !led1;} +void toggleLed2(){ led2 = !led2;} +void toggleLed3(){ led3 = !led3;} +void toggleLed4(){ led4 = !led4;} -void toggleLed1(void* obj) -{ - led1 = !led1; -} -void toggleLed2(void* obj) -{ - led2 = !led2; -} -void toggleLed3(void* obj) -{ - led3 = !led3; -} -void toggleLed4() -{ - led4 = !led4; -} +Semaphore displaySemaphore; + /*********************************************************************** * Thread to read GPIO and handle events ***********************************************************************/ -void ReadGPIOExtender(void const *name) +void ReadGPIOExtender(void) //const *name) { uint8_t code = 0; - - pc.printf("Starting %s task\n", name ); - - led4 = !led4; + + pc.printf("Starting escmBtnController task\n" ); + toggleLed4(); while (true) { - - controller.update(); - - code = controller.currentValue & 0x1F; // filter code(s) - - if (code) - { - event_t e; - e.event = code; - - if (!event_queue.full()){ - pc.printf("<%02x>\n",e.event); - event_queue.push(e); - } - - } - - led4 = !led4; - Thread::wait(10); + escmBtnController.update(); + toggleLed4(); + Thread::wait(50); } - - } /*********************************************************************** * Thread to read GPIO and handle events ***********************************************************************/ -void ESCMController_Update(void const *name) +void ESCMController_Update(void) //const *name) { + + pc.printf("Starting escmIOController task\n" ); - pc.printf("Starting %s task\n", name ); - + if ( escmEventLog.size()> 0 ) + { + int address = escmEventLog.index(0)->address; + escmController.tx485Message ( address ); + } while(1) { - escmController.update(); - - Thread::wait(1000); + Thread::wait(100); } } @@ -146,166 +111,247 @@ * Update LCD Display Thread ***********************************************************************/ -void UpdateDisplay(void const *name) +void UpdateDisplay(void) +{ + static int counter = 0; + Menu *activeMenu = Menu::setCurrentMenu (&editAddress); + + pc.printf("Starting escmDisplay task\n" ); + + lcd.init(); + lcd.cls(); + lcd.locate(0,0); + lcd.printf ("Initializing System.."); + + event_t ex;// = (event_t*)(event_queue.alloc()); + int event =0; + + toggleLed3(); + activeMenu->update_needed = 1; + + while (true) { + + if (counter==0) { + activeMenu->update_needed = 1; + counter = 100; + } + + if (activeMenu == NULL){ + lcd.printf ("ERROR: Invalid Menu Selected.."); + continue; + } + else { + + if ( activeMenu != Menu::getCurrentMenu() ) + { + activeMenu = Menu::getCurrentMenu() ; + activeMenu->update_needed = 1; + } + else + { + + escmBtnController.processCmdQueue(activeMenu); + } + + activeMenu->DrawDisplay(&lcd); + } + + toggleLed3(); + Thread::wait(10); + counter--; + + } +} +/*********************************************************************** +* Handle Terminal Prompts +* TODO: should have its own queue. +***********************************************************************/ + +void TerminalPrompt(void) // const *name) { - pc.printf("Starting %s task\n", name ); - - lcd.init(); - lcd.locate(0,0); - lcd.cls(); - - lcd.writeLine (0, "Initializing System.."); + pc.printf("Starting escmTerm task\n" ); - event_t ex;// = (event_t*)(event_queue.alloc()); - int event =0; - - currentMenu->update_needed = 1; - - while (true) { + while (1) + { + int c; + pc.printf("\n>>"); + pc.scanf("%d", &c); - #if 1 + /* echo */ + pc.printf("\n%0d",c); - while (!event_queue.empty()) { - event_queue.pop(ex); - - switch(ex.event) - { - case 0x01://up - currentMenu->pressUp(); - break; - - case 0x02://down - currentMenu->pressDown(); - break; - - case 0x04://clear - currentMenu->pressClear(); - break; - - case 0x08://mode - currentMenu->pressMode(); - break; - - case 0x10://set - currentMenu->pressSet(); - break; - default: - break; - } - } - - currentMenu->lcd = &lcd; - currentMenu->display(&lcd); -#endif - - led3 = !led3; - - Thread::wait(50); - + if ( c >= 0 && c < 99) { + ESCMControlApp::postEvent((uint16_t)c); + } + else if (c==555) + { + addressMap.reset(); + } + else if (c==666) + { + escmEventLog.reset(); + } + else if (c==999) + { + pc.printf("\nThread | size | free | used | max | "); + pc.printf("\n------------------------------------ "); + for(int i = 0; i<MAX_THREADS; i++) { + pc.printf("\n%-8d | %4d | %4d | %4d | %4d |", + i, + threads[i]->stack_size(), + threads[i]->free_stack(), + threads[i]->used_stack(), + threads[i]->max_stack() + ) ; + } + } + else + { + } } } - /*********************************************************************** * Play sounds * TODO: should have its own queue. ***********************************************************************/ -void PlaySound(void const *name) +void PlaySound(void) // const *name) { - char msg[40]; - - event_t e; - - pc.printf("Starting %s task\n", name ); - - while (true) { - - while (!playback_queue.empty()) { - playback_queue.pop(e); - - sprintf(msg, "Unit %d is open\r",e.event); - speaker.speakf("S");//Speak command starts with "S" - speaker.speakf(msg); // Send the desired string to convert to speech - speaker.speakf("\r"); //marks end of speak command - speaker.ready(); //ready waits for speech to finish from last command with a ":" response - led2 = !led2; - } - Thread::wait(2000); + led2 = 1; + pc.printf("Starting escmSound task\n" ); + + while (1) { + toggleLed2(); + escmController.processSoundQueue(); + Thread::wait(200); } } + +/*********************************************************************** +* Dumps thread stats +***********************************************************************/ + +void PrintSystemStats (void) +{ + uint32_t frameCount = 0; + while(1) { + frameCount++; + if ((0 == frameCount) || (PRINT_AFTER_N_LOOPS == frameCount)) { + // Following the main thread wait, report on the current system status + //sys_state.report_state(); +#if 0 + pc.printf("\nThread | size | free | used | max | "); + pc.printf("\n------------------------------------ "); + for(int i = 0; i<MAX_THREADS; i++) { + pc.printf("\n%-8d | %4d | %4d | %4d | %4d |", + i, + threads[i]->stack_size(), + threads[i]->free_stack(), + threads[i]->used_stack(), + threads[i]->max_stack() + ) ; + } +#endif + escmEventLog.save(); + frameCount = 0; + } + + Thread::wait(500); + } +} + +#if 0 +/*********************************************************************** +* process incoming messages from rx485 serial (ISR) +***********************************************************************/ + +void rx485Message() { + // Note: you need to actually read from the serial to clear the RX interrupt + int dataRxBuffer[4]; + int value = rs485port1.getc(); + + if (value){ + dataRxBuffer[dataRxCnt++]=value; + + if(dataRxCnt==4) { + cur_address = 10*(dataRxBuffer[0] -0x30) + (dataRxBuffer[1] -0x30); + memset(dataRxBuffer,0,sizeof(dataRxBuffer)); + dataRxCnt=0; + } + else + { + // do nothing + } + } +} + +#endif + /*********************************************************************** * Main Loop ***********************************************************************/ -int main() { +int main() +{ + SystemReport sys_state( SLEEP_TIME * PRINT_AFTER_N_LOOPS /* Loop delay time in ms */); led1=1; led1=!led1; pc.printf("\n\r"); + pc.printf("=====================================\n\r"); - pc.printf("= LCD TEST =\n\r"); + pc.printf("= ESCM 2000 =\n\r"); + pc.printf("= %s %s =\n\r", __DATE__ , __TIME__); + pc.printf("= v0.01 =\n\r"); pc.printf("=====================================\n\r"); + + // initialize main controller escmController.init(); - escmController.tx485Message(0); - led1=!led1; - - #if 0 - Menu ledMenu1("Events menu"); - Menu ledMenu2("Address menu"); - Menu ledMenu3("Set Time"); - Menu ledMenu4("Set Date"); - //Add any selections - ledMenu1.add(Selection(&toggleLed1, 0, NULL, "Toggle LED1")); - ledMenu1.add(Selection(&toggleLed2, 0, NULL, "Toggle LED2")); - ledMenu1.add(Selection(&toggleLed3, 0, NULL, "Toggle LED3")); - ledMenu1.add(Selection(&toggleLed4, 0, NULL, "Toggle LED4")); - ledMenu1.add(Selection(NULL, 0, &rootMenu, "Go back")); - - //add a selection to go back up in the menu hierarchy. - // Do this by letting the child menu point to the previous menu + toggleLed1(); + + //Add any selections + rootMenu.add(&showEvents); + rootMenu.add(&editTime); + rootMenu.add(&editAddress); + rootMenu.add(&factoryReset); + Menu::setCurrentMenu (&rootMenu); + + toggleLed1(); - ledMenu2.add(Selection(&toggleLed4, 0, NULL, "Current Address Code")); - ledMenu2.add(Selection(NULL, 0, &rootMenu, "Go back")); - - ledMenu3.add(Selection(&toggleLed4, 0, NULL, "Current Time")); - ledMenu3.add(Selection(NULL, 0, &rootMenu, "Go back")); - - ledMenu4.add(Selection(&toggleLed4, 0, NULL, "Current Date")); - ledMenu4.add(Selection(NULL, 0, &rootMenu, "Go back")); + EventQueue *stats_queue = mbed_event_queue(); - #endif - - - //add submenus to the root (as selections with child parameters set to the submenus) -// rootMenu.add(Selection(NULL, 0, &showEvents, "View Events")); -// rootMenu.add(Selection(NULL, 1, &editAdress, "Modify Addresses")); - rootMenu.add(Selection(NULL, 2, &editTime, "Set Time")); -// rootMenu.add(Selection(NULL, 3, &editDate, "Set Date")); - - led1=!led1; - - ioThread.start (callback(ESCMController_Update , (void *)"io")); + threads[0] = new Thread(osPriorityNormal5, 0x300 ); + threads[1] = new Thread(osPriorityNormal4, 0x500 ); + threads[2] = new Thread(osPriorityNormal3, 0x1000 ); + threads[3] = new Thread(osPriorityNormal2, 0x400 ); + threads[4] = new Thread(osPriorityNormal1, 0x200 ); + threads[5] = new Thread(osPriorityLow, 0x100 ); + +#if 0 + for (int i = 0; i < 100 ; i++ ) { + escmController.tx485Message(i); + escmController.txCanMessage502(i); + wait_ms(5); + } +#endif - gpioThread.start (callback(ReadGPIOExtender , (void *)"gpio")); - - soundThread.start(callback(PlaySound, (void *)"audio")); - - displayThread.start (callback(UpdateDisplay, (void *)"display")); + threads[0]->start(ESCMController_Update); + threads[1]->start(ReadGPIOExtender); + threads[2]->start(UpdateDisplay); + threads[3]->start(PlaySound); + threads[4]->start(PrintSystemStats); + //threads[5]->start(TerminalPrompt); - escmController.say("Welcome"); - - uint32_t frameCount = 0; - + escmController.say("Welcome ESCM"); + while(1) { - wait_ms(500); - frameCount++; - led1=!led1; - + toggleLed1(); + wait_ms(500); } }