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

Committer:
ansond
Date:
Tue Mar 18 21:46:48 2014 +0000
Revision:
112:1fb53d4729af
Parent:
84:4a993dd7c38b
Child:
114:bd38ad417d6a
updates

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:4c9bfcb3e759 1 /* Copyright C2013 Doug Anson, MIT License
ansond 0:4c9bfcb3e759 2 *
ansond 0:4c9bfcb3e759 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
ansond 0:4c9bfcb3e759 4 * and associated documentation files the "Software", to deal in the Software without restriction,
ansond 0:4c9bfcb3e759 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
ansond 0:4c9bfcb3e759 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
ansond 0:4c9bfcb3e759 7 * furnished to do so, subject to the following conditions:
ansond 0:4c9bfcb3e759 8 *
ansond 0:4c9bfcb3e759 9 * The above copyright notice and this permission notice shall be included in all copies or
ansond 0:4c9bfcb3e759 10 * substantial portions of the Software.
ansond 0:4c9bfcb3e759 11 *
ansond 0:4c9bfcb3e759 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
ansond 0:4c9bfcb3e759 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
ansond 0:4c9bfcb3e759 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
ansond 0:4c9bfcb3e759 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
ansond 0:4c9bfcb3e759 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ansond 0:4c9bfcb3e759 17 */
ansond 0:4c9bfcb3e759 18
ansond 0:4c9bfcb3e759 19 #include "ErrorHandler.h"
ansond 0:4c9bfcb3e759 20
ansond 18:bc165829bb88 21 // Annunciations
ansond 0:4c9bfcb3e759 22 DigitalOut led1(LED1);
ansond 73:3e6478c7649f 23 DigitalOut led2(LED2);
ansond 73:3e6478c7649f 24 DigitalOut led3(LED3);
ansond 0:4c9bfcb3e759 25 DigitalOut led4(LED4);
ansond 0:4c9bfcb3e759 26
ansond 0:4c9bfcb3e759 27 // Multi-color LED support
ansond 72:46c94966311b 28 PwmOut r(p23);
ansond 72:46c94966311b 29 PwmOut g(p24);
ansond 72:46c94966311b 30 PwmOut b(p25);
ansond 0:4c9bfcb3e759 31
ansond 71:90bf61bc3727 32 // Memory statistics macro
ansond 74:b60149dd669e 33 #define MEM_STATS(x) \
ansond 71:90bf61bc3727 34 int s##x=0;\
ansond 71:90bf61bc3727 35 int *h##x = new int [1];\
ansond 71:90bf61bc3727 36 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);\
ansond 71:90bf61bc3727 37 if (h##x > &s##x)\
ansond 71:90bf61bc3727 38 error("collision\n");\
ansond 71:90bf61bc3727 39 delete [] h##x;\
ansond 71:90bf61bc3727 40 __nop();
ansond 71:90bf61bc3727 41
ansond 71:90bf61bc3727 42 // close down connections
ansond 20:f2dbbd852e08 43 extern void closedown(int code);
ansond 0:4c9bfcb3e759 44
ansond 0:4c9bfcb3e759 45 // default constructor
ansond 68:e6431dfe2f30 46 ErrorHandler::ErrorHandler(Serial *pc,C12832_LCD *lcd) {
ansond 0:4c9bfcb3e759 47 this->m_pc = pc;
ansond 0:4c9bfcb3e759 48 this->m_lcd = lcd;
ansond 26:791d22d43cb4 49 memset(this->m_message,0,MAX_LOG_MESSAGE+1);
ansond 70:055ebf51f6ad 50 this->m_mutex = NULL;
ansond 70:055ebf51f6ad 51 this->m_close_mutex = NULL;
ansond 70:055ebf51f6ad 52 this->m_led_mutex = NULL;
ansond 83:2f49051d6acf 53 this->m_rgb_mutex = NULL;
ansond 70:055ebf51f6ad 54 #ifdef EH_USE_MUTEXES
ansond 61:6012d61573ea 55 this->m_mutex = new Mutex();
ansond 70:055ebf51f6ad 56 this->m_close_mutex = new Mutex();
ansond 61:6012d61573ea 57 this->m_led_mutex = new Mutex();
ansond 83:2f49051d6acf 58 this->m_rgb_mutex = new Mutex();
ansond 70:055ebf51f6ad 59 #endif
ansond 70:055ebf51f6ad 60 this->releaseMutexes();
ansond 84:4a993dd7c38b 61 this->resetLEDs();
ansond 0:4c9bfcb3e759 62 }
ansond 0:4c9bfcb3e759 63
ansond 0:4c9bfcb3e759 64 // default destructor
ansond 0:4c9bfcb3e759 65 ErrorHandler::~ErrorHandler() {
ansond 70:055ebf51f6ad 66 this->releaseMutexes();
ansond 70:055ebf51f6ad 67 if (this->m_mutex != NULL) delete this->m_mutex;
ansond 70:055ebf51f6ad 68 if (this->m_close_mutex != NULL) delete this->m_close_mutex;
ansond 70:055ebf51f6ad 69 if (this->m_led_mutex != NULL) delete this->m_led_mutex;
ansond 83:2f49051d6acf 70 if (this->m_rgb_mutex != NULL) delete this->m_rgb_mutex;
ansond 70:055ebf51f6ad 71 }
ansond 70:055ebf51f6ad 72
ansond 70:055ebf51f6ad 73 // release all mutexes
ansond 70:055ebf51f6ad 74 void ErrorHandler::releaseMutexes() {
ansond 70:055ebf51f6ad 75 if (this->m_mutex != NULL) this->m_mutex->unlock();
ansond 70:055ebf51f6ad 76 if (this->m_close_mutex != NULL) this->m_close_mutex->unlock();
ansond 70:055ebf51f6ad 77 if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
ansond 83:2f49051d6acf 78 if (this->m_rgb_mutex != NULL) this->m_rgb_mutex->unlock();
ansond 0:4c9bfcb3e759 79 }
ansond 0:4c9bfcb3e759 80
ansond 0:4c9bfcb3e759 81 // log information
ansond 0:4c9bfcb3e759 82 void ErrorHandler::log(const char *format, ...) {
ansond 82:24af66daaf17 83 #ifndef HUSH_LOG
ansond 26:791d22d43cb4 84 memset(this->m_message,0,MAX_LOG_MESSAGE+1);
ansond 0:4c9bfcb3e759 85 va_list args;
ansond 0:4c9bfcb3e759 86 va_start(args, format);
ansond 0:4c9bfcb3e759 87 vsprintf(this->m_message, format, args);
ansond 0:4c9bfcb3e759 88 va_end(args);
ansond 84:4a993dd7c38b 89 if (this->m_mutex != NULL) this->m_mutex->lock();
ansond 0:4c9bfcb3e759 90 this->m_pc->printf(this->m_message);
ansond 64:7e494186e2ec 91 #ifdef ENABLE_MEMORY_DEBUG
ansond 66:3361be4bfd38 92 MEM_STATS(0);
ansond 64:7e494186e2ec 93 #endif
ansond 0:4c9bfcb3e759 94 this->m_pc->printf("\r\n");
ansond 0:4c9bfcb3e759 95 this->m_lcd->cls();
ansond 0:4c9bfcb3e759 96 this->m_lcd->locate(0,0);
ansond 0:4c9bfcb3e759 97 this->m_lcd->printf(this->m_message);
ansond 70:055ebf51f6ad 98 if (this->m_mutex != NULL) this->m_mutex->unlock();
ansond 82:24af66daaf17 99 #endif
ansond 0:4c9bfcb3e759 100 }
ansond 0:4c9bfcb3e759 101
ansond 74:b60149dd669e 102 // log information
ansond 74:b60149dd669e 103 void ErrorHandler::log_memory(const char *format, ...) {
ansond 82:24af66daaf17 104 #ifndef HUSH_LOG
ansond 74:b60149dd669e 105 #ifdef MEMORY_LOGGING
ansond 74:b60149dd669e 106 memset(this->m_message,0,MAX_LOG_MESSAGE+1);
ansond 74:b60149dd669e 107 va_list args;
ansond 74:b60149dd669e 108 va_start(args, format);
ansond 74:b60149dd669e 109 vsprintf(this->m_message, format, args);
ansond 74:b60149dd669e 110 va_end(args);
ansond 84:4a993dd7c38b 111 if (this->m_mutex != NULL) this->m_mutex->lock();
ansond 74:b60149dd669e 112 this->m_pc->printf(this->m_message);
ansond 74:b60149dd669e 113 MEM_STATS(0);
ansond 74:b60149dd669e 114 if (this->m_mutex != NULL) this->m_mutex->unlock();
ansond 74:b60149dd669e 115 #endif
ansond 82:24af66daaf17 116 #endif
ansond 74:b60149dd669e 117 }
ansond 74:b60149dd669e 118
ansond 15:386dccd0000a 119 // pause
ansond 15:386dccd0000a 120 void ErrorHandler::pause(const char *format, ...) {
ansond 82:24af66daaf17 121 #ifndef HUSH_LOG
ansond 26:791d22d43cb4 122 memset(this->m_message,0,MAX_LOG_MESSAGE+1);
ansond 15:386dccd0000a 123 va_list args;
ansond 15:386dccd0000a 124 va_start(args, format);
ansond 15:386dccd0000a 125 vsprintf(this->m_message, format, args);
ansond 15:386dccd0000a 126 va_end(args);
ansond 84:4a993dd7c38b 127 if (this->m_mutex != NULL) this->m_mutex->lock();
ansond 15:386dccd0000a 128 this->m_pc->printf(this->m_message);
ansond 15:386dccd0000a 129 this->m_pc->printf("\r\n");
ansond 15:386dccd0000a 130 this->m_lcd->cls();
ansond 15:386dccd0000a 131 this->m_lcd->locate(0,0);
ansond 15:386dccd0000a 132 this->m_lcd->printf(this->m_message);
ansond 18:bc165829bb88 133 this->m_pc->printf("Press any key to continue...ctrl-c to stop\r\n");
ansond 16:fda7dbb8b47a 134 char c = this->m_pc->getc();
ansond 16:fda7dbb8b47a 135 if (c == 0x03) { // CTRL-C ASCII
ansond 16:fda7dbb8b47a 136 this->m_pc->printf("ctrl-c: closing down...\r\n");
ansond 84:4a993dd7c38b 137 if (this->m_mutex != NULL) this->m_mutex->unlock();
ansond 20:f2dbbd852e08 138 closedown(1);
ansond 16:fda7dbb8b47a 139 }
ansond 70:055ebf51f6ad 140 if (this->m_mutex != NULL) this->m_mutex->unlock();
ansond 82:24af66daaf17 141 #endif
ansond 15:386dccd0000a 142 }
ansond 15:386dccd0000a 143
ansond 0:4c9bfcb3e759 144 // check for exit
ansond 15:386dccd0000a 145 void ErrorHandler::checkForExit() {
ansond 70:055ebf51f6ad 146 if (this->m_close_mutex != NULL) this->m_close_mutex->lock();
ansond 0:4c9bfcb3e759 147 if (this->m_pc->readable()) {
ansond 0:4c9bfcb3e759 148 char c = this->m_pc->getc();
ansond 0:4c9bfcb3e759 149 if (c == 0x03) { // CTRL-C ASCII
ansond 0:4c9bfcb3e759 150 this->m_pc->printf("ctrl-c: closing down...\r\n");
ansond 20:f2dbbd852e08 151 closedown(1);
ansond 0:4c9bfcb3e759 152 }
ansond 0:4c9bfcb3e759 153 }
ansond 70:055ebf51f6ad 154 if (this->m_close_mutex != NULL) this->m_close_mutex->unlock();
ansond 0:4c9bfcb3e759 155 }
ansond 0:4c9bfcb3e759 156
ansond 0:4c9bfcb3e759 157 // set the color LED
ansond 0:4c9bfcb3e759 158 void ErrorHandler::setRGBLED(float H, float S, float V) {
ansond 82:24af66daaf17 159 #ifndef HUSH_LEDS
ansond 83:2f49051d6acf 160 if (this->m_rgb_mutex != NULL) this->m_rgb_mutex->lock();
ansond 0:4c9bfcb3e759 161 float f,h,p,q,t;
ansond 0:4c9bfcb3e759 162 int i;
ansond 0:4c9bfcb3e759 163 if( S == 0.0) {
ansond 0:4c9bfcb3e759 164 r = 1.0 - V; // invert pwm !
ansond 0:4c9bfcb3e759 165 g = 1.0 - V;
ansond 0:4c9bfcb3e759 166 b = 1.0 - V;
ansond 0:4c9bfcb3e759 167 return;
ansond 0:4c9bfcb3e759 168 }
ansond 0:4c9bfcb3e759 169 if(H > 360.0) H = 0.0; // check values
ansond 0:4c9bfcb3e759 170 if(S > 1.0) S = 1.0;
ansond 0:4c9bfcb3e759 171 if(S < 0.0) S = 0.0;
ansond 0:4c9bfcb3e759 172 if(V > 1.0) V = 1.0;
ansond 0:4c9bfcb3e759 173 if(V < 0.0) V = 0.0;
ansond 0:4c9bfcb3e759 174 h = H / 60.0;
ansond 0:4c9bfcb3e759 175 i = (int) h;
ansond 0:4c9bfcb3e759 176 f = h - i;
ansond 0:4c9bfcb3e759 177 p = V * (1.0 - S);
ansond 0:4c9bfcb3e759 178 q = V * (1.0 - (S * f));
ansond 0:4c9bfcb3e759 179 t = V * (1.0 - (S * (1.0 - f)));
ansond 0:4c9bfcb3e759 180
ansond 0:4c9bfcb3e759 181 switch(i) {
ansond 0:4c9bfcb3e759 182 case 0:
ansond 0:4c9bfcb3e759 183 r = 1.0 - V; // invert pwm !
ansond 0:4c9bfcb3e759 184 g = 1.0 - t;
ansond 0:4c9bfcb3e759 185 b = 1.0 - p;
ansond 0:4c9bfcb3e759 186 break;
ansond 0:4c9bfcb3e759 187 case 1:
ansond 0:4c9bfcb3e759 188 r = 1.0 - q;
ansond 0:4c9bfcb3e759 189 g = 1.0 - V;
ansond 0:4c9bfcb3e759 190 b = 1.0 - p;
ansond 0:4c9bfcb3e759 191 break;
ansond 0:4c9bfcb3e759 192 case 2:
ansond 0:4c9bfcb3e759 193 r = 1.0 - p;
ansond 0:4c9bfcb3e759 194 g = 1.0 - V;
ansond 0:4c9bfcb3e759 195 b = 1.0 - t;
ansond 0:4c9bfcb3e759 196 break;
ansond 0:4c9bfcb3e759 197 case 3:
ansond 0:4c9bfcb3e759 198 r = 1.0 - p;
ansond 0:4c9bfcb3e759 199 g = 1.0 - q;
ansond 0:4c9bfcb3e759 200 b = 1.0 - V;
ansond 0:4c9bfcb3e759 201 break;
ansond 0:4c9bfcb3e759 202 case 4:
ansond 0:4c9bfcb3e759 203 r = 1.0 - t;
ansond 0:4c9bfcb3e759 204 g = 1.0 - p;
ansond 0:4c9bfcb3e759 205 b = 1.0 - V;
ansond 0:4c9bfcb3e759 206 break;
ansond 0:4c9bfcb3e759 207 case 5:
ansond 0:4c9bfcb3e759 208 default:
ansond 0:4c9bfcb3e759 209 r = 1.0 - V;
ansond 0:4c9bfcb3e759 210 g = 1.0 - p;
ansond 0:4c9bfcb3e759 211 b = 1.0 - q;
ansond 0:4c9bfcb3e759 212 break;
ansond 0:4c9bfcb3e759 213 }
ansond 83:2f49051d6acf 214 if (this->m_rgb_mutex != NULL) this->m_rgb_mutex->unlock();
ansond 82:24af66daaf17 215 #endif
ansond 0:4c9bfcb3e759 216 }
ansond 0:4c9bfcb3e759 217
ansond 0:4c9bfcb3e759 218 // turn the RGB LED specific colors
ansond 0:4c9bfcb3e759 219 void ErrorHandler::turnLEDRed() { this->setRGBLED(0.0,1.0,0.2); }
ansond 0:4c9bfcb3e759 220 void ErrorHandler::turnLEDGreen() { this->setRGBLED(120.0,1.0,0.2); }
ansond 0:4c9bfcb3e759 221 void ErrorHandler::turnLEDBlue() { this->setRGBLED(200.0,1.0,0.2); }
ansond 0:4c9bfcb3e759 222 void ErrorHandler::turnLEDBlack() { this->setRGBLED(0,0,0); }
ansond 0:4c9bfcb3e759 223 void ErrorHandler::turnLEDYellow() { this->setRGBLED(60.0,1.0,0.133); }
ansond 73:3e6478c7649f 224 void ErrorHandler::dimRGB(float value) {
ansond 82:24af66daaf17 225 #ifndef HUSH_LEDS
ansond 73:3e6478c7649f 226 float H, S, V;
ansond 73:3e6478c7649f 227 H = 120.0 - (120.0*(1.0 - value));
ansond 73:3e6478c7649f 228 S = 1.0 - (1.0*(1.0 - value));
ansond 73:3e6478c7649f 229 V = 0.2 - (0.2*(1.0 - value));
ansond 73:3e6478c7649f 230 this->setRGBLED(H,S,V);
ansond 82:24af66daaf17 231 #endif
ansond 73:3e6478c7649f 232 }
ansond 0:4c9bfcb3e759 233
ansond 0:4c9bfcb3e759 234 // reset LEDs
ansond 0:4c9bfcb3e759 235 void ErrorHandler::resetLEDs() {
ansond 82:24af66daaf17 236 #ifndef HUSH_LEDS
ansond 0:4c9bfcb3e759 237 // turn off all LEDs
ansond 0:4c9bfcb3e759 238 led1 = 0; led2 = 0; led3 = 0; led4 = 0;
ansond 82:24af66daaf17 239 #endif
ansond 0:4c9bfcb3e759 240 }
ansond 0:4c9bfcb3e759 241
ansond 0:4c9bfcb3e759 242 // blink an LED
ansond 0:4c9bfcb3e759 243 void ErrorHandler::blinkLED(DigitalOut led) {
ansond 82:24af66daaf17 244 #ifndef HUSH_LEDS
ansond 84:4a993dd7c38b 245 if (this->m_led_mutex != NULL) this->m_led_mutex->lock();
ansond 0:4c9bfcb3e759 246 led = 1;
ansond 84:4a993dd7c38b 247 if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
ansond 0:4c9bfcb3e759 248 wait_ms(BLINK_TIME);
ansond 84:4a993dd7c38b 249 if (this->m_led_mutex != NULL) this->m_led_mutex->lock();
ansond 0:4c9bfcb3e759 250 led = 0;
ansond 84:4a993dd7c38b 251 if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
ansond 82:24af66daaf17 252 #endif
ansond 0:4c9bfcb3e759 253 }
ansond 0:4c9bfcb3e759 254
ansond 84:4a993dd7c38b 255 void ErrorHandler::changeLED(DigitalOut led,bool onoff) {
ansond 84:4a993dd7c38b 256 if (this->m_led_mutex != NULL) this->m_led_mutex->lock();
ansond 84:4a993dd7c38b 257 if (onoff) led = 1;
ansond 84:4a993dd7c38b 258 else led = 0;
ansond 84:4a993dd7c38b 259 if (this->m_led_mutex != NULL) this->m_led_mutex->unlock();
ansond 84:4a993dd7c38b 260 }
ansond 84:4a993dd7c38b 261
ansond 84:4a993dd7c38b 262 void ErrorHandler::led2On() { this->changeLED(led2,true); }
ansond 84:4a993dd7c38b 263 void ErrorHandler::led2Off() { this->changeLED(led2,false); }
ansond 84:4a993dd7c38b 264 void ErrorHandler::led3On() { this->changeLED(led3,true); }
ansond 84:4a993dd7c38b 265 void ErrorHandler::led3Off() { this->changeLED(led3,false); }
ansond 84:4a993dd7c38b 266
ansond 112:1fb53d4729af 267 void ErrorHandler::setEndpoint(void *endpoint) { this->m_endpoint = endpoint; }
ansond 112:1fb53d4729af 268 void *ErrorHandler::getEndpoint() { return this->m_endpoint; }
ansond 112:1fb53d4729af 269
ansond 36:73e343ddca7f 270 // blink the Transport TX LED
ansond 36:73e343ddca7f 271 void ErrorHandler::blinkTransportTxLED() { this->blinkLED(led4); }
ansond 0:4c9bfcb3e759 272
ansond 36:73e343ddca7f 273 // blink the Transport RX LED
ansond 36:73e343ddca7f 274 void ErrorHandler::blinkTransportRxLED() { this->blinkLED(led1); }