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

main.cpp

Committer:
foxbrianr
Date:
2019-09-12
Revision:
5:65f21c0b6b79
Parent:
3:ecaf9963341b
Child:
6:010ceb99f7b0

File content as of revision 5:65f21c0b6b79:

#include "mbed.h"
#include "rtos.h"
#include "stats_report.h"

#include "LCD.h"

#include "ButtonController.h"

#include "ESCMControlApp.h"

#include "Menu.h"
#include "EditTimeMenu.h"
#include "EditAddressMenu.h"
#include "DisplayCodesMenu.h"
#include "FactoryResetMenu.h"

#define SLEEP_TIME                  500 // (msec)
#define PRINT_AFTER_N_LOOPS         20

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);


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;


int dataRxCnt    = 0; 

int cur_address  = 0;    

/*-------------------------------------------------------------------
 * define led toggles for diagnostics
 *-------------------------------------------------------------------*/
void toggleLed1(){    led1 = !led1;}
void toggleLed2(){    led2 = !led2;}
void toggleLed3(){    led3 = !led3;}
void toggleLed4(){    led4 = !led4;}

Semaphore displaySemaphore;

/***********************************************************************
* Thread to read GPIO and handle events
***********************************************************************/

void ReadGPIOExtender(void) //const *name)
{
    uint8_t code = 0;

    pc.printf("Starting escmBtnController task\n" );
    toggleLed4();
    
    while (true) {
        escmBtnController.update();
        toggleLed4();
        Thread::wait(50);
    }
}

/***********************************************************************
* Thread to read GPIO and handle events
***********************************************************************/

void ESCMController_Update(void) //const *name)
{

    pc.printf("Starting escmIOController task\n" );
    
    if ( escmEventLog.size()> 0 )
    {
        int address = escmEventLog.index(0)->address;
        escmController.tx485Message ( address );
    }
    
    while(1) {
        escmController.update();
        Thread::wait(100);
    }
}


/***********************************************************************
* Update LCD Display Thread
***********************************************************************/

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 escmTerm task\n" );
    
    while (1)
    {
        int c;
        pc.printf("\n>>");
        pc.scanf("%d", &c);
        
        /* echo */
        pc.printf("\n%0d",c);
        
        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)
{
    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()
{
    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("= 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();
    
    toggleLed1();

    //Add any selections
    rootMenu.add(&showEvents);
    rootMenu.add(&editTime);
    rootMenu.add(&editAddress);
    rootMenu.add(&factoryReset);
    Menu::setCurrentMenu (&rootMenu);

    toggleLed1();
    
    EventQueue *stats_queue = mbed_event_queue();
    
    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
    
    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 ESCM");

    while(1) {
        toggleLed1();
        wait_ms(500);
    }
}