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

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);
     }
 }