![](/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:
- 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); } }