Core Base Classes for the Light Endpoints
Dependents: mbed_mqtt_endpoint_ublox_ethernet mbed_mqtt_endpoint_ublox_cellular mbed_nsp_endpoint_ublox_cellular mbed_nsp_endpoint_ublox_ethernet ... more
ErrorHandler.cpp@83:2f49051d6acf, 2014-03-11 (annotated)
- Committer:
- ansond
- Date:
- Tue Mar 11 20:42:29 2014 +0000
- Revision:
- 83:2f49051d6acf
- Parent:
- 82:24af66daaf17
- Child:
- 84:4a993dd7c38b
updates
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:4c9bfcb3e759 | 50 | this->resetLEDs(); |
ansond | 70:055ebf51f6ad | 51 | this->m_mutex = NULL; |
ansond | 70:055ebf51f6ad | 52 | this->m_close_mutex = NULL; |
ansond | 70:055ebf51f6ad | 53 | this->m_led_mutex = NULL; |
ansond | 83:2f49051d6acf | 54 | this->m_rgb_mutex = NULL; |
ansond | 70:055ebf51f6ad | 55 | #ifdef EH_USE_MUTEXES |
ansond | 61:6012d61573ea | 56 | this->m_mutex = new Mutex(); |
ansond | 70:055ebf51f6ad | 57 | this->m_close_mutex = new Mutex(); |
ansond | 61:6012d61573ea | 58 | this->m_led_mutex = new Mutex(); |
ansond | 83:2f49051d6acf | 59 | this->m_rgb_mutex = new Mutex(); |
ansond | 70:055ebf51f6ad | 60 | #endif |
ansond | 70:055ebf51f6ad | 61 | this->releaseMutexes(); |
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 | 70:055ebf51f6ad | 84 | if (this->m_mutex != NULL) this->m_mutex->lock(); |
ansond | 26:791d22d43cb4 | 85 | memset(this->m_message,0,MAX_LOG_MESSAGE+1); |
ansond | 0:4c9bfcb3e759 | 86 | va_list args; |
ansond | 0:4c9bfcb3e759 | 87 | va_start(args, format); |
ansond | 0:4c9bfcb3e759 | 88 | vsprintf(this->m_message, format, args); |
ansond | 0:4c9bfcb3e759 | 89 | va_end(args); |
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 | if (this->m_mutex != NULL) this->m_mutex->lock(); |
ansond | 74:b60149dd669e | 107 | memset(this->m_message,0,MAX_LOG_MESSAGE+1); |
ansond | 74:b60149dd669e | 108 | va_list args; |
ansond | 74:b60149dd669e | 109 | va_start(args, format); |
ansond | 74:b60149dd669e | 110 | vsprintf(this->m_message, format, args); |
ansond | 74:b60149dd669e | 111 | va_end(args); |
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 | 70:055ebf51f6ad | 122 | if (this->m_mutex != NULL) this->m_mutex->lock(); |
ansond | 26:791d22d43cb4 | 123 | memset(this->m_message,0,MAX_LOG_MESSAGE+1); |
ansond | 15:386dccd0000a | 124 | va_list args; |
ansond | 15:386dccd0000a | 125 | va_start(args, format); |
ansond | 15:386dccd0000a | 126 | vsprintf(this->m_message, format, args); |
ansond | 15:386dccd0000a | 127 | va_end(args); |
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 | 61:6012d61573ea | 137 | 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 | 83:2f49051d6acf | 237 | if (this->m_led_mutex != NULL) this->m_led_mutex->lock(); |
ansond | 0:4c9bfcb3e759 | 238 | // turn off all LEDs |
ansond | 0:4c9bfcb3e759 | 239 | led1 = 0; led2 = 0; led3 = 0; led4 = 0; |
ansond | 83:2f49051d6acf | 240 | if (this->m_led_mutex != NULL) this->m_led_mutex->unlock(); |
ansond | 82:24af66daaf17 | 241 | #endif |
ansond | 0:4c9bfcb3e759 | 242 | } |
ansond | 0:4c9bfcb3e759 | 243 | |
ansond | 0:4c9bfcb3e759 | 244 | // blink an LED |
ansond | 0:4c9bfcb3e759 | 245 | void ErrorHandler::blinkLED(DigitalOut led) { |
ansond | 82:24af66daaf17 | 246 | #ifndef HUSH_LEDS |
ansond | 72:46c94966311b | 247 | if (this->m_mutex != NULL) this->m_led_mutex->lock(); |
ansond | 0:4c9bfcb3e759 | 248 | led = 1; |
ansond | 0:4c9bfcb3e759 | 249 | wait_ms(BLINK_TIME); |
ansond | 0:4c9bfcb3e759 | 250 | led = 0; |
ansond | 72:46c94966311b | 251 | if (this->m_mutex != NULL) this->m_led_mutex->unlock(); |
ansond | 82:24af66daaf17 | 252 | #endif |
ansond | 0:4c9bfcb3e759 | 253 | } |
ansond | 0:4c9bfcb3e759 | 254 | |
ansond | 36:73e343ddca7f | 255 | // blink the Transport TX LED |
ansond | 36:73e343ddca7f | 256 | void ErrorHandler::blinkTransportTxLED() { this->blinkLED(led4); } |
ansond | 0:4c9bfcb3e759 | 257 | |
ansond | 36:73e343ddca7f | 258 | // blink the Transport RX LED |
ansond | 36:73e343ddca7f | 259 | void ErrorHandler::blinkTransportRxLED() { this->blinkLED(led1); } |