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 ESCMControlApp.cpp
--- a/ESCMControlApp.cpp	Thu Sep 12 11:28:26 2019 +0000
+++ b/ESCMControlApp.cpp	Tue Sep 17 13:48:57 2019 +0000
@@ -1,40 +1,62 @@
+/**************************************************************************
+ * @file     ESCMControlApp.cpp
+ * @brief    Main class for wrapping the interface with ESCM Control 
+ *           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 "ESCMControlApp.h"
 #include "SPI_MX25R.h"
 
 // ---------------------------------------------------------------------
-// External IO for the ESCM Control Board
-// 
+// External IO for the ESCM Io Board
 // ---------------------------------------------------------------------
 Serial escmRs485_Input(p9, p10, 9600); //tx,rx,baud
 DigitalOut escmRs485_Mode (p11); //Transmit = 1, Receive = 0
 
+// ---------------------------------------------------------------------
+// External IO for the MicroComm ESCM Control Board
+// ---------------------------------------------------------------------
 Serial microCommRs485_Tx(p13, p14, 9600); //tx,rx,baud
 DigitalOut microCommRs485_Mode (p12); //Transmit = 1, Receive = 0
 
 CAN microCommCanItf (p30, p29, 50000);       // rx,tx
 DigitalOut microCommCan_Mode (p25); //Silent Mode = 1, Normal = 0
 
-
 // ---------------------------------------------------------------------
 // External IO for the Speaker / EMIC2 board
 // ---------------------------------------------------------------------
 emic2 speaker(p28, p27); //serial RX,TX pins to emic
-
+Mutex  sound_mutex;
 // ---------------------------------------------------------------------
-// External MEMORY for the FAULT AND ADDRESS MAPS
+// External MEMORY for the FAULT AND ADDRESS MAPS (not used)
 // ---------------------------------------------------------------------
 SPI_MX25R spi_memory (p5, p6, p7, p8);
 
+// ---------------------------------------------------------------------
+ESCM_EventLog escmEventLog;
 
 // ---------------------------------------------------------------------
-Mutex  sound_mutex;
-
-ESCM_EventLog escmEventLog;
-
 AddressMap  addressMap;
 
+// ---------------------------------------------------------------------
 RealTimeClock rtc;
 
 /* for incoming messages */
@@ -47,6 +69,7 @@
 CircularBuffer<playbackMessage_t, 10> playback_queue;
 
 
+// ---------------------------------------------------------------------
 void setCurrentTime (char* timeBuf)
 {
     
@@ -71,6 +94,7 @@
     
 }
 
+// ---------------------------------------------------------------------
 void ESCMControlApp::init()
 {
     // set on power, should not change
@@ -79,12 +103,12 @@
     microCommCan_Mode   = 0; // Normal mode (turn on CNA transeiver)
     
     
-    //escmRs485_Input.attach(&rx485Message); 
-    
     escmEventLog.init();
     
     addressMap.init();
     
+    cur_address = 0;
+    
     if (escmEventLog.size()>0)
     {
         cur_address = escmEventLog.index(0)->address;
@@ -92,74 +116,65 @@
 }
 
 
+// ---------------------------------------------------------------------
 void ESCMControlApp::update(void)
 {
-    static int new_address = -1;
-    static int rxCount   =  0;
     static int counter     =  0;
+    
     char value;
+    int msgCount       = 0;
+    int nChar          = 0;
+    int new_address    = 0;
     bool update_needed = 0;
-    #if 1
-    if(escmRs485_Input.readable() ) 
-    {
+    
+    char dataRxBuffer[4];
+    
+    if(escmRs485_Input.readable() ) {
         //rx485Message();
-        
-        int dataRxBuffer[4];
-        while ( value = escmRs485_Input.getc() ) {
-            dataRxBuffer[rxCount++]=value;
-            if(rxCount==4) { // read 4 characters
+        while (msgCount < 10 && (value = escmRs485_Input.getc())) {
+            //printf("%02x ",value);
+            dataRxBuffer[nChar++]=value;
+            if(nChar==4) { // read 4 characters
                 if (dataRxBuffer[2] == 0xd && dataRxBuffer[3] == 0xa) {
                     new_address = 10*(dataRxBuffer[0] -0x30) + (dataRxBuffer[1] -0x30);
-                    printf("ADDR=%d\n",new_address);
-                    update_needed = 1;
+                    printf("ADDR = %d ",new_address);
+                    update_needed = 1; // receive at least 1
+                    nChar       = 0;
                     dataRxCnt++;
-                    break; 
+                    msgCount++;
+                    break;
                 }
-            }            
+            }
+            
         }
-        // reset cnt;
-        rxCount = 0;
-        memset(dataRxBuffer,0,sizeof(dataRxBuffer));
     }
     
-    #endif
     
     if (update_needed)
     {
         if (new_address >= 0 && new_address < 100  )
         {
             cur_address = new_address;
-            printf("ADDR=%d\n",cur_address);
+            printf("New Addr=%d\n",cur_address);
             postEvent(cur_address,0);
             counter     = 0;
             new_address = -1;
         } else {
             
-            printf("ERROR: INVALID_ADDR=%d\n",new_address);
+            for (int i=0;i<4;i++)
+                printf( "%0x ", dataRxBuffer[i]);
+            
+            error("ERROR: INVALID_ADDR=[%d] [%d]\n",
+                cur_address,
+                new_address);
+                
         }
     }
 
-        
-    if (cur_address >= 0 && cur_address < 100  )
-    {
-        
-        if (counter == 0 ) {
-
-            tx485Message(cur_address); //send on rs485
-#if 1
-            txCanMessage501(cur_address);//send on can
-            txCanMessage502(cur_address);
-#else
-            txCanMessage580(cur_address);
-#endif
-            counter = 5; //send .5 sec
-            dataTxCnt++;
-            //printf("Current_Address is %d \n\r", cur_address );
-        }
-    } 
-    else 
-    {
-        printf("ERROR: INVALID_ADDR=%d\n",cur_address);
+    if (counter == 0 ) {
+        relayMessage (cur_address);
+        counter = 5; //send .5 sec
+        dataTxCnt++;
     }
     counter--;
 }
@@ -173,11 +188,9 @@
         return;
     
     while (!message_queue.empty()) {
-        message_queue.pop(e);
-        
+        message_queue.pop(e);        
         tx485Message(e.event);
-        
-        Thread::wait(100);
+        ThisThread::sleep_for(100);
     }
 }
 
@@ -188,17 +201,64 @@
     
     if (playback_queue.empty())
         return;
-    
+        
+    // drain the queue
     while (!playback_queue.empty()) {
         playback_queue.pop(e);
-        speaker.speakf("S");  //Speak command starts with "S"
-        speaker.speakf(e.message);  // 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
+        ThisThread::sleep_for(500);
+    }
+    
+    // emic is very slow so play last message
+    speaker.speakf("S");  //Speak command starts with "S"
+    speaker.speakf(e.message);  // 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
+    
+}
+/*************************************************************************/
+void ESCMControlApp::info (char *format, ...)
+{
+    char buffer[128];
+    va_list args;
+    va_start(args, format);
+    vsprintf(buffer,format,args);
+    printf("\nINFO:%s");
+    va_end(args);
+}
+/*************************************************************************/
+void ESCMControlApp::warning (char *format, ...)
+{
+    
+    char buffer[128];
+    va_list args;
+    va_start(args, format);
+    vsprintf(buffer,format,args);
+    printf("\nWARNING:%s");
+    va_end(args);
+}
+/*************************************************************************/
+void ESCMControlApp::error (char *format, ...)
+{
+    char buffer[128];
+    va_list args;
+    va_start(args, format);
+    vsprintf(buffer,format,args);
+    
+    printf("\n---------------------------------------------------");
+    printf("\nERROR:%s");
+    va_end(args);
+}
+
+/*************************************************************************/
+void ESCMControlApp::say (int address)
+{
+    char * desc = addressMap.getDescription(address);
+    if (strlen(desc) > 0) {
+        escmController.say("%s is open", desc );
+    } else {
+        escmController.say("Unit %d is open", address );
     }
 }
-
-
 /*************************************************************************/
 void ESCMControlApp::say (char *format, ...)
 {
@@ -209,6 +269,7 @@
     va_list args;
     va_start(args, format);
     vsprintf(e.message,format,args);
+    // note: immediately going to the emic blocks calling thread 
 #if 0
     speaker.speakf("S");//Speak command starts with "S"
     speaker.speakf(e.message);  
@@ -250,8 +311,6 @@
     if ( address >= 0 && address < 100 )
     {
         escmEventLog.add(address, source); 
-        //escmEventLog.save();
-        
         ESCMControlApp::refresh_display();
         
 #if 0
@@ -268,10 +327,17 @@
     }
 }
 
+/*************************************************************************/
+
 void ESCMControlApp::refresh_display(void)
 {
-    printf("$");
-    Menu::getCurrentMenu()->update_needed=1;
+    // Note: we only refresh the event log display to avoid LCD flashing
+    // --
+#if 1
+    showEvents.update_needed=1;
+#else
+    Menu::getCurrentMenu()->update_needed=1
+#endif
 }
 
 /*************************************************************************
@@ -293,7 +359,7 @@
     int months  = timeinfo->tm_mon + 1 ;
     int days    = timeinfo->tm_mday;
     
-    sprintf(timeBuf,"%0d/%0d/%04d %02d:%02d:%02d\0", 
+    sprintf(timeBuf,"%0d/%0d/%04d %02d:%02d:%02d", 
         months,days,years,hours,mins,secs );
         
     printf("TIME: %s\n", timeBuf);
@@ -319,7 +385,26 @@
     set_time(mktime(&t));
 }
 
-
+/*************************************************************************/
+void ESCMControlApp::relayMessage (int address) 
+{
+    
+    //printf("Current_Address is %d \n\r", cur_address );
+    if (address >= 0 && address < 100  )
+    {
+        tx485Message(address); //send on rs485
+#if 1 // currently 501 & 502 control output
+        txCanMessage501(address);//send on can
+        txCanMessage502(address);
+#else
+        txCanMessage580(address);
+#endif
+    } 
+    else 
+    {
+        error("relay: INVALID_ADDR=%d\n",  address);
+    }
+}
 /*************************************************************************
  * The following information is from the MicroComm_gen_input.doc
  * 
@@ -386,7 +471,7 @@
         }
         
     } else {
-        printf ("Error: invalid address %d",address );
+        warning("tx485: invalid address %d",address );
     }
     
 }
@@ -449,7 +534,7 @@
         }
         
     } else {
-        printf ("Error: invalid address %d",address );
+        warning("tx501: invalid address %d",address );
     }
     
 }
@@ -493,15 +578,14 @@
 
 
         if(microCommCanItf.write(CANMessage(0x502, data, 8))) {
-            printf("Message 502: (%d) sent via CAN: %d\n\r",counterTx, address);
+            //printf("Message 502: (%d) sent via CAN: %d\n\r",counterTx, address);
             counterTx++;
         } else {
-            //printf("Message 502: Reset\n\r");
             microCommCanItf.reset();
         }
 
     } else {
-        printf ("Error: invalid address %d",address );
+        warning("tx503: invalid address %d",address );
     }
 }
 
@@ -564,13 +648,12 @@
             //printf("Message 580: (%d) sent via CAN: %d\n\r",counterTx, address);
             counterTx++;
         } else {
-            //printf("Message 580: Reset\n\r");
             microCommCanItf.reset();
         }
 
 
     } else {
-        printf ("Error: invalid address %d",address );
+        warning ("tx580: invalid address %d",address );
     }
     
 }