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:
6:010ceb99f7b0
Parent:
5:65f21c0b6b79
Child:
7:0244f1a26545
diff -r 65f21c0b6b79 -r 010ceb99f7b0 main.cpp
--- a/main.cpp	Thu Sep 12 11:28:26 2019 +0000
+++ b/main.cpp	Tue Sep 17 13:48:57 2019 +0000
@@ -1,7 +1,30 @@
+/**************************************************************************
+ * @file     main.cpp
+ * @brief    Main function for ESCM Control System
+ *           Application
+ * @version: V1.0
+ * @date:    9/17/2019
+
+ *
+ * @note
+ * Copyright (C) 2019 E3 Design. All rights reserved.
+ *
+ * @par
+ * E3 Designers LLC is supplying this software for use with Cortex-M3 LPC1768
+ * processor based microcontroller for the ESCM 2000 Monitor and Display.  
+ *  *
+ * @par
+ * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
+ * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
+ * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
+ * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
+ *
+ ******************************************************************************/
 #include "mbed.h"
 #include "rtos.h"
 #include "stats_report.h"
-
+#include "math.h"
 #include "LCD.h"
 
 #include "ButtonController.h"
@@ -15,33 +38,37 @@
 #include "FactoryResetMenu.h"
 
 #define SLEEP_TIME                  500 // (msec)
-#define PRINT_AFTER_N_LOOPS         20
+#define PRINT_AFTER_N_LOOPS         10
 
 DigitalOut led1(LED1);
 DigitalOut led2(LED2);
 DigitalOut led3(LED3);
 DigitalOut led4(LED4);
 
+SystemReport *sys_state;
+/*-------------------------------------------------------------------
+ * define displays
+ *-------------------------------------------------------------------*/
+Serial pc(USBTX, USBRX); // tx, rx
 
-Serial pc(USBTX, USBRX); // tx, rx
+#define MAX_THREADS 6
+Thread * threads [MAX_THREADS]; 
+OsTaskPerfData_t g_perfData;
 
 /*-------------------------------------------------------------------
  * 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
  *-------------------------------------------------------------------*/
@@ -52,11 +79,7 @@
  *-------------------------------------------------------------------*/
 ESCMControlApp escmController;
 
-
-int dataRxCnt    = 0; 
-
-int cur_address  = 0;    
-
+static int dataRxCnt = 0;
 /*-------------------------------------------------------------------
  * define led toggles for diagnostics
  *-------------------------------------------------------------------*/
@@ -65,23 +88,85 @@
 void toggleLed3(){    led3 = !led3;}
 void toggleLed4(){    led4 = !led4;}
 
-Semaphore displaySemaphore;
+static volatile uint64_t idle;
+
+void InitPerfData()
+{
+    for (int i=0;i<MAX_THREADS;i++) 
+   {
+      g_perfData.task[i].counter      = 0;
+      g_perfData.task[i].deltaTime    = 0;
+      g_perfData.task[i].deltaTimeMax = 0;
+      g_perfData.task[i].deltaTimeMin = 0xFFFFFFFFu;
+      g_perfData.task[i].deltaTimeAve = 0;
+      
+      g_perfData.task[i].cycleTimeMax = 0;
+      g_perfData.task[i].cycleTimeMin = 0xFFFFFFFFu;
+      g_perfData.task[i].cycleTimeAve = 0;
+      
+      g_perfData.task[i].timeStamp     = 0;
+      g_perfData.task[i].lastTimeStamp = 0;
+   }
+}
+
+void UpdatePerfDataStart(OsPerfData_t *data)
+{
+    #if 1
+    if (data != NULL) {
+        uint64_t now = Kernel::get_ms_count();
+        data->counter++;
+        data->timeStamp     = now;
+        data->cycleTime     = data->timeStamp - data->lastTimeStamp;
+        if (data->cycleTime > data->cycleTimeMax ) data->cycleTimeMax = data->cycleTime;
+        if (data->cycleTime < data->cycleTimeMin ) data->cycleTimeMin = data->cycleTime;
+        data->cycleTimeAve  = (data->cycleTime - data->cycleTimeAve)/2;
+        data->lastTimeStamp = data->timeStamp;
+    }
+    #endif
+}
+
+void UpdatePerfDataStop(OsPerfData_t *data)
+{
+    #if 1
+    if (data != NULL) {
+        uint64_t now = Kernel::get_ms_count();
+        data->deltaTime     = now - (data->timeStamp);
+        if (data->deltaTime > data->deltaTimeMax ) data->deltaTimeMax = data->deltaTime;
+        if (data->deltaTime < data->deltaTimeMin ) data->deltaTimeMin = data->deltaTime;
+        data->deltaTimeAve  = (data->deltaTime + data->deltaTimeAve)/2;
+        data->timeStamp     = now;
+
+    }
+    #endif
+}
+ 
+void ShowPerfData (OsPerfData_t *data)
+{
+}
+
 
 /***********************************************************************
 * Thread to read GPIO and handle events
 ***********************************************************************/
 
-void ReadGPIOExtender(void) //const *name)
+void ReadGPIOExtender(void) 
 {
     uint8_t code = 0;
 
+    Timer t;
+    
     pc.printf("Starting escmBtnController task\n" );
     toggleLed4();
     
     while (true) {
+        t.reset();
+        t.start();
         escmBtnController.update();
         toggleLed4();
-        Thread::wait(50);
+        ThisThread::sleep_for(50);
+        
+        t.stop();
+        //printf("<1> %d ms\n", t.read_ms());
     }
 }
 
@@ -89,20 +174,18 @@
 * Thread to read GPIO and handle events
 ***********************************************************************/
 
-void ESCMController_Update(void) //const *name)
+void ESCMController_Update(void) 
 {
 
     pc.printf("Starting escmIOController task\n" );
-    
-    if ( escmEventLog.size()> 0 )
-    {
-        int address = escmEventLog.index(0)->address;
-        escmController.tx485Message ( address );
-    }
-    
+
     while(1) {
+        
+        UpdatePerfDataStart(&g_perfData.task[0]);
         escmController.update();
-        Thread::wait(100);
+        
+        UpdatePerfDataStop(&g_perfData.task[0]);
+        ThisThread::sleep_for(200);
     }
 }
 
@@ -114,7 +197,6 @@
 void UpdateDisplay(void)
 {
     static int counter = 0;
-    Menu *activeMenu = Menu::setCurrentMenu (&editAddress);
     
     pc.printf("Starting escmDisplay task\n" );
 
@@ -122,20 +204,22 @@
     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;
-
+    
+    Menu *activeMenu = Menu::setCurrentMenu (&editAddress);
+    
     while (true) {
 
+        UpdatePerfDataStart(&g_perfData.task[2]);
+        #if 0
+        // note force a refresh
         if (counter==0) {
             activeMenu->update_needed = 1;
             counter = 100;
         }
-        
+        counter--;
+        #endif
         if (activeMenu == NULL){
             lcd.printf ("ERROR: Invalid Menu Selected..");
             continue;
@@ -157,8 +241,9 @@
         }
 
         toggleLed3();
-        Thread::wait(10);
-        counter--;
+        
+        UpdatePerfDataStop(&g_perfData.task[2]);
+        ThisThread::sleep_for(10);
 
     }
 }
@@ -222,8 +307,12 @@
     pc.printf("Starting escmSound task\n" );
 
     while (1) {
+        
+        UpdatePerfDataStart(&g_perfData.task[3]);
         toggleLed2();
         escmController.processSoundQueue();
+        
+        UpdatePerfDataStop(&g_perfData.task[3]);
         Thread::wait(200);
     }
 }
@@ -240,10 +329,31 @@
         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
+            sys_state->report_state();
+#if 1
+
+            pc.printf("IDLE=%d", idle);
+            pc.printf("\nThread   | cntr  | T     | Cycle Time             | Delta Time ");
+            pc.printf("\n-------------------------------------------------------------------- ");
+            pc.printf("\n");
+            
+            for(int i = 0; i<MAX_THREADS; i++) {
+                pc.printf("%-8d | %-5d | %-5d | %-5d | %-5d | %-5d | %-5d | %-5d | %-5d \n\r",
+                    i ,
+                    g_perfData.task[i].counter ,
+                    g_perfData.task[i].timeStamp ,
+                    g_perfData.task[i].cycleTimeAve ,
+                    g_perfData.task[i].cycleTimeMax ,
+                    g_perfData.task[i].cycleTimeMin ,
+                    g_perfData.task[i].deltaTimeAve ,
+                    g_perfData.task[i].deltaTimeMax ,
+                    g_perfData.task[i].deltaTimeMin );
+            }
+#else
             pc.printf("\nThread | size | free | used |  max | ");
             pc.printf("\n------------------------------------ ");
+            pc.printf("\n");
+            
             for(int i = 0; i<MAX_THREADS; i++) {
                 pc.printf("\n%-8d | %4d | %4d | %4d | %4d |",
                           i,
@@ -252,22 +362,30 @@
                           threads[i]->used_stack(),
                           threads[i]->max_stack()
                          ) ;
+
             }
 #endif
+
+            pc.printf("\n------------------------------------ ");
+            pc.printf("\n");
+            
             escmEventLog.save();
             frameCount = 0;
         }
         
-        Thread::wait(500);
+        Thread::wait(200);
     }
 }
 
-#if 0
 /***********************************************************************
 * process incoming messages from rx485 serial (ISR)
 ***********************************************************************/
 
 void rx485Message() {
+    
+#if 1
+    dataRxCnt++;
+#else
     // Note: you need to actually read from the serial to clear the RX interrupt
     int dataRxBuffer[4];
     int value = rs485port1.getc();
@@ -285,22 +403,21 @@
             // do nothing
         }
     }
+#endif
 }
-
-#endif
-
+/***********************************************************************
+* Main Loop
+***********************************************************************/
+void backgroundTask(void)
+{
+    idle++;
+}
 /***********************************************************************
 * Main Loop
 ***********************************************************************/
 
 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("=====================================\n\r");
     pc.printf("= ESCM 2000                         =\n\r");
@@ -308,10 +425,31 @@
     pc.printf("= v0.01                             =\n\r");
     pc.printf("=====================================\n\r");
 
+    sys_state = new SystemReport( SLEEP_TIME * PRINT_AFTER_N_LOOPS /* Loop delay time in ms */);
+    
+    
+    Kernel::attach_idle_hook(&backgroundTask);
+    
+    led1=1;
+    led1=!led1;
+
+    
+    InitPerfData();
+   
+    lcd.init();
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf ("Initializing System..");
+   
+    // test speaker
+    escmController.say("Welcome ESCM");
 
     // initialize main controller
     escmController.init();
     
+    //escmRs485_Input.attach ( &rx485Message );
+    //addressMap.display(&pc);
+    
     toggleLed1();
 
     //Add any selections
@@ -332,14 +470,7 @@
     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
-    
+   
     threads[0]->start(ESCMController_Update);
     threads[1]->start(ReadGPIOExtender);
     threads[2]->start(UpdateDisplay);
@@ -347,11 +478,10 @@
     threads[4]->start(PrintSystemStats);
     //threads[5]->start(TerminalPrompt);
     
-    escmController.say("Welcome ESCM");
 
     while(1) {
         toggleLed1();
-        wait_ms(500);
+        ThisThread::sleep_for(500);
     }
 }