Core Base Classes for the Light Endpoints

Dependencies:   BufferedSerial

Dependents:   mbed_mqtt_endpoint_ublox_ethernet mbed_mqtt_endpoint_ublox_cellular mbed_nsp_endpoint_ublox_cellular mbed_nsp_endpoint_ublox_ethernet ... more

ErrorHandler.cpp

Committer:
ansond
Date:
2014-09-12
Revision:
180:eb43d5cd0ed7
Parent:
179:35e88daf2d75

File content as of revision 180:eb43d5cd0ed7:

/* Copyright C2013 Doug Anson, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 * and associated documentation files the "Software", to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include "ErrorHandler.h"
 #include "MBEDEndpoint.h"
 
#ifdef _ENDPOINT_UBLOX_PLATFORM
    // Annunciations
    DigitalOut led1(P3_25);
    DigitalOut led2(P3_25);
    DigitalOut led3(P3_25);
    DigitalOut led4(P3_25);
    
    // Multi-color LED support
    PwmOut r(D5);
    PwmOut g(D9);
    PwmOut b(D8);  
#endif

#ifdef _ENDPOINT_NXP_PLATFORM
   // Annunciations
    DigitalOut led1(LED1);
    DigitalOut led2(LED2);
    DigitalOut led3(LED3);
    DigitalOut led4(LED4);  
    
    // Multi-color LED support
    PwmOut r(p23);
    PwmOut g(p24);
    PwmOut b(p25);  
#endif

#ifdef _ENDPOINT_FREEDOM_PLATFORM   
    // Annunciations
    DigitalOut led1(LED1);
    DigitalOut led2(LED2);
    DigitalOut led3(LED3);
    DigitalOut led4(LED4);
    
    // Multi-color LED support
    PwmOut r(p23);
    PwmOut g(p24);
    PwmOut b(p25);  
#endif

// Memory statistics macro
#define ERROR_HANDLER_MEM_STATS(x) \
    int s##x=0;\
    int *h##x = new int [1];\
    if (this->m_pc != NULL) this->m_pc->printf("\r\nMEMORY: stack: 0x%08x  heap: 0x%08x  avail: %d bytes\r\n", &s##x, h##x, &s##x-h##x);\
    if (h##x > &s##x)\
    error("collision\n");\
    delete [] h##x;\
    __nop();

 // close down connections
 extern void closedown(int code);
 
 // default constructor
 ErrorHandler::ErrorHandler(BufferedSerial *pc,LCDCLASS *lcd) {
     this->m_pc = pc;
     this->m_lcd = lcd;
     this->m_status_lcd = false;
     memset(this->m_message,0,MAX_LOG_MESSAGE+1);    
#ifdef EH_USE_MUTEXES
     this->m_mutex = NULL;
     this->m_close_mutex = NULL;
     this->m_led_mutex = NULL;
     this->m_rgb_mutex = NULL;
     this->m_mutex = new Mutex();
     this->m_close_mutex = new Mutex();
     this->m_led_mutex = new Mutex();
     this->m_rgb_mutex = new Mutex();
     this->releaseMutexes();
#endif
     this->resetLEDs();
 }
 
 // default destructor
 ErrorHandler::~ErrorHandler() {
#ifdef EH_USE_MUTEXES
     this->releaseMutexes();
     if (this->m_mutex != NULL) delete this->m_mutex;
     if (this->m_close_mutex != NULL) delete this->m_close_mutex;
     if (this->m_led_mutex != NULL) delete this->m_led_mutex;
     if (this->m_rgb_mutex != NULL) delete this->m_rgb_mutex;
#endif
 }
 
 // enable LCD to only show summary status
 void ErrorHandler::lcdStatusOnly(bool status_lcd) { this->m_status_lcd = status_lcd; }
 
 #ifdef EH_USE_MUTEXES
 // release all mutexes
 void ErrorHandler::releaseMutexes() {
     if (this->m_mutex != NULL) this->m_mutex->unlock();
     if (this->m_close_mutex != NULL) this->m_close_mutex->unlock();
     if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
     if (this->m_rgb_mutex != NULL) this->m_rgb_mutex->unlock();
 }
 #endif
 
 // log information
 void ErrorHandler::log(const char *format, ...) {
#ifndef HUSH_LOG
    memset(this->m_message,0,MAX_LOG_MESSAGE+1);
    va_list args;
    va_start(args, format);
    vsprintf(this->m_message, format, args);
    va_end(args);
#ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->lock();
#endif
    if (this->m_pc != NULL) this->m_pc->printf(this->m_message);
    #ifdef ENABLE_MEMORY_DEBUG
    ERROR_HANDLER_MEM_STATS(0);
    #endif
    if (this->m_pc != NULL) this->m_pc->printf("\r\n");
    if (this->m_status_lcd) {
        MBEDEndpoint *endpoint = (MBEDEndpoint *)this->m_endpoint;
        if (endpoint != NULL) {
            this->m_lcd->cls();
            this->m_lcd->locate(0,0);
            this->m_lcd->printf(endpoint->getLCDStatus());
        }
    }
    else {
        this->m_lcd->cls();
        this->m_lcd->locate(0,0);
        this->m_lcd->printf(this->m_message);
    }
#ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->unlock();
#endif
#else
#ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->lock();
#endif
    if (this->m_status_lcd) {
        MBEDEndpoint *endpoint = (MBEDEndpoint *)this->m_endpoint;
        if (endpoint != NULL) {
            this->m_lcd->cls();
            this->m_lcd->locate(0,0);
            this->m_lcd->printf(endpoint->getLCDStatus());
        }
    }
#ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->unlock();
#endif
#endif
 }
 
 // log information
 void ErrorHandler::log_memory(const char *format, ...) {
 #ifndef HUSH_LOG
 #ifdef MEMORY_LOGGING
    memset(this->m_message,0,MAX_LOG_MESSAGE+1);
    va_list args;
    va_start(args, format);
    vsprintf(this->m_message, format, args);
    va_end(args);
 #ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->lock();
 #endif
    if (this->m_pc != NULL) this->m_pc->printf(this->m_message);
    ERROR_HANDLER_MEM_STATS(0);
 #ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->unlock();
 #endif
 #endif
 #endif
 }
 
 // pause
 void ErrorHandler::pause(const char *format, ...) {
 #ifndef HUSH_LOG
    memset(this->m_message,0,MAX_LOG_MESSAGE+1);
    va_list args;
    va_start(args, format);
    vsprintf(this->m_message, format, args);
    va_end(args);
 #ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->lock();
 #endif
    if (this->m_pc != NULL) this->m_pc->printf(this->m_message);
    if (this->m_pc != NULL) this->m_pc->printf("\r\n");
    this->m_lcd->cls();
    this->m_lcd->locate(0,0);
    this->m_lcd->printf(this->m_message);
    if (this->m_pc != NULL) { 
        this->m_pc->printf("Press any key to continue...ctrl-c to stop\r\n");
        char c = this->m_pc->getc();
        if (c == 0x03) {    // CTRL-C ASCII
        this->m_pc->printf("ctrl-c: closing down...\r\n");
 #ifdef EH_USE_MUTEXES
        if (this->m_mutex != NULL) this->m_mutex->unlock();
 #endif
            closedown(1);
        }
    }
 #ifdef EH_USE_MUTEXES
    if (this->m_mutex != NULL) this->m_mutex->unlock();
 #endif
 #endif
 }
 
 // check for exit
 void ErrorHandler::checkForExit() {
 #ifdef EH_USE_MUTEXES
    if (this->m_close_mutex != NULL) this->m_close_mutex->lock();
 #endif
    if (this->m_pc != NULL && this->m_pc->readable()) {
        char c = this->m_pc->getc();
        if (c == 0x03) {    // CTRL-C ASCII
            this->m_pc->printf("ctrl-c: closing down...\r\n");
            closedown(1);
        }
    }
 #ifdef EH_USE_MUTEXES
    if (this->m_close_mutex != NULL) this->m_close_mutex->unlock();
 #endif
}

// set the color LED 
void ErrorHandler::setRGBLED(float H, float S, float V) {
#ifndef HUSH_LEDS
#ifdef EH_USE_MUTEXES
    if (this->m_rgb_mutex != NULL) this->m_rgb_mutex->lock();
#endif
    float f,h,p,q,t;
    int i;
    if( S == 0.0) {
        r = 1.0 - V;  // invert pwm !
        g = 1.0 - V;
        b = 1.0 - V;
        return;
    }
    if(H > 360.0) H = 0.0;   // check values
    if(S > 1.0) S = 1.0; 
    if(S < 0.0) S = 0.0;
    if(V > 1.0) V = 1.0;
    if(V < 0.0) V = 0.0;
    h = H / 60.0;
    i = (int) h;
    f = h - i;
    p = V * (1.0 - S);
    q = V * (1.0 - (S * f));
    t = V * (1.0 - (S * (1.0 - f)));

    switch(i) {
        case 0:
            r = 1.0 - V;  // invert pwm !
            g = 1.0 - t;
            b = 1.0 - p;
            break;
        case 1:
            r = 1.0 - q;
            g = 1.0 - V;
            b = 1.0 - p;
            break;
        case 2:
            r = 1.0 - p;
            g = 1.0 - V;
            b = 1.0 - t;
            break;
        case 3:
            r = 1.0 - p;
            g = 1.0 - q;
            b = 1.0 - V;
            break;
        case 4:
            r = 1.0 - t;
            g = 1.0 - p;
            b = 1.0 - V;
            break;
        case 5:
        default:
            r = 1.0 - V;
            g = 1.0 - p;
            b = 1.0 - q;
            break;
    }
 #ifdef EH_USE_MUTEXES
    if (this->m_rgb_mutex != NULL) this->m_rgb_mutex->unlock();
 #endif
 #endif
}

// turn the RGB LED specific colors
void ErrorHandler::turnLEDRed() { this->setRGBLED(0.0,1.0,0.2); }
void ErrorHandler::turnLEDGreen() { this->setRGBLED(120.0,1.0,0.2); }
void ErrorHandler::turnLEDBlue() { this->setRGBLED(200.0,1.0,0.2); }
void ErrorHandler::turnLEDPurple() { this->setRGBLED(261.9,1.0,0.2); }
void ErrorHandler::turnLEDOrange() { this->setRGBLED(51.0,1.0,0.2); }
void ErrorHandler::turnLEDBlack() { this->setRGBLED(0,0,0); }
void ErrorHandler::turnLEDYellow() { this->setRGBLED(60.0,1.0,0.133); }

// reset LEDs
void ErrorHandler::resetLEDs() {
#ifndef HUSH_LEDS
    // turn off all LEDs
    led1 = 0; led2 = 0; led3 = 0; led4 = 0;
#endif
}

// blink an LED
void ErrorHandler::blinkLED(DigitalOut led) {
#ifndef HUSH_LEDS
#ifdef EH_USE_MUTEXES
    if (this->m_led_mutex != NULL) this->m_led_mutex->lock();
#endif
    led = 1;
#ifdef EH_USE_MUTEXES
    if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
#endif
    Thread::wait(BLINK_TIME);
#ifdef EH_USE_MUTEXES
    if (this->m_led_mutex != NULL) this->m_led_mutex->lock();
#endif
    led = 0;
#ifdef EH_USE_MUTEXES
    if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
#endif
#endif
}

void ErrorHandler::changeLED(DigitalOut led,bool onoff) { 
#ifdef EH_USE_MUTEXES
    if (this->m_led_mutex != NULL) this->m_led_mutex->lock();
#endif
    if (onoff) led = 1;
    else led = 0;
#ifdef EH_USE_MUTEXES
    if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
#endif
}

void ErrorHandler::led2On() { this->changeLED(led2,true); }
void ErrorHandler::led2Off() { this->changeLED(led2,false); }
void ErrorHandler::led3On() { this->changeLED(led3,true); }
void ErrorHandler::led3Off() { this->changeLED(led3,false); }

void  ErrorHandler::setEndpoint(void *endpoint) { this->m_endpoint = endpoint; }
void *ErrorHandler::getEndpoint() { return this->m_endpoint; }

// blink the Transport TX LED
void ErrorHandler::blinkTransportTxLED() { this->blinkLED(led4); }

// blink the Transport RX LED
void ErrorHandler::blinkTransportRxLED() { this->blinkLED(led1); }