PushToGo on STM32F429-Disco Board
Dependencies: BSP_DISCO_F429ZI LCD_DISCO_F429ZI pushtogo usb
LCDConsole.cpp@6:1b97c5f92717, 2018-09-14 (annotated)
- Committer:
- caoyuan9642
- Date:
- Fri Sep 14 06:52:08 2018 +0000
- Revision:
- 6:1b97c5f92717
- Parent:
- 5:5ea2862a3493
Fix compiler issue
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
caoyuan9642 | 0:084d1dae2ea1 | 1 | /* |
caoyuan9642 | 0:084d1dae2ea1 | 2 | * LCDStreamHandle.cpp |
caoyuan9642 | 0:084d1dae2ea1 | 3 | * |
caoyuan9642 | 1:64c1fd738059 | 4 | * Created on: 2018��2��25�� |
caoyuan9642 | 0:084d1dae2ea1 | 5 | * Author: caoyuan9642 |
caoyuan9642 | 0:084d1dae2ea1 | 6 | */ |
caoyuan9642 | 0:084d1dae2ea1 | 7 | |
caoyuan9642 | 0:084d1dae2ea1 | 8 | #include <math.h> |
caoyuan9642 | 0:084d1dae2ea1 | 9 | #include <ctype.h> |
caoyuan9642 | 1:64c1fd738059 | 10 | #include <time.h> |
caoyuan9642 | 1:64c1fd738059 | 11 | #include "LCDConsole.h" |
caoyuan9642 | 0:084d1dae2ea1 | 12 | #include "MCULoadMeasurement.h" |
caoyuan9642 | 0:084d1dae2ea1 | 13 | |
caoyuan9642 | 0:084d1dae2ea1 | 14 | bool LCDConsole::inited = false; |
caoyuan9642 | 0:084d1dae2ea1 | 15 | Mutex LCDConsole::mutex; |
caoyuan9642 | 0:084d1dae2ea1 | 16 | LCD_DISCO_F429ZI LCDConsole::lcd; |
caoyuan9642 | 0:084d1dae2ea1 | 17 | int LCDConsole::x0 = 0, LCDConsole::y0 = 0, LCDConsole::width = lcd.GetXSize(), |
caoyuan9642 | 0:084d1dae2ea1 | 18 | LCDConsole::height = lcd.GetYSize(); |
caoyuan9642 | 0:084d1dae2ea1 | 19 | int LCDConsole::textheight = 0, LCDConsole::textwidth = 0, |
caoyuan9642 | 0:084d1dae2ea1 | 20 | LCDConsole::buffersize = 0; |
caoyuan9642 | 0:084d1dae2ea1 | 21 | int *LCDConsole::buffer, *LCDConsole::head, *LCDConsole::tail; |
caoyuan9642 | 0:084d1dae2ea1 | 22 | Semaphore LCDConsole::sem_update(0, 1); |
caoyuan9642 | 0:084d1dae2ea1 | 23 | Thread LCDConsole::thread(osPriorityLow, OS_STACK_SIZE, NULL, "LCD Console"); |
caoyuan9642 | 0:084d1dae2ea1 | 24 | |
caoyuan9642 | 0:084d1dae2ea1 | 25 | LCDConsole lcd_handle_out("lcd_stdout", LCD_COLOR_WHITE); |
caoyuan9642 | 0:084d1dae2ea1 | 26 | LCDConsole lcd_handle_err("lcd_stderr", LCD_COLOR_YELLOW); |
caoyuan9642 | 0:084d1dae2ea1 | 27 | |
caoyuan9642 | 0:084d1dae2ea1 | 28 | |
caoyuan9642 | 0:084d1dae2ea1 | 29 | #define BG_COLOR LCD_COLOR_BLACK |
caoyuan9642 | 0:084d1dae2ea1 | 30 | |
caoyuan9642 | 0:084d1dae2ea1 | 31 | void idle_hook() |
caoyuan9642 | 0:084d1dae2ea1 | 32 | { |
caoyuan9642 | 0:084d1dae2ea1 | 33 | core_util_critical_section_enter(); |
caoyuan9642 | 0:084d1dae2ea1 | 34 | MCULoadMeasurement::getInstance().setMCUActive(false); |
caoyuan9642 | 0:084d1dae2ea1 | 35 | // sleep_manager_lock_deep_sleep(); |
caoyuan9642 | 0:084d1dae2ea1 | 36 | // sleep(); |
caoyuan9642 | 0:084d1dae2ea1 | 37 | // __WFI(); |
caoyuan9642 | 0:084d1dae2ea1 | 38 | // sleep_manager_unlock_deep_sleep(); |
caoyuan9642 | 0:084d1dae2ea1 | 39 | int i = 1000; |
caoyuan9642 | 0:084d1dae2ea1 | 40 | while (i--) |
caoyuan9642 | 0:084d1dae2ea1 | 41 | ; |
caoyuan9642 | 0:084d1dae2ea1 | 42 | MCULoadMeasurement::getInstance().setMCUActive(true); |
caoyuan9642 | 0:084d1dae2ea1 | 43 | core_util_critical_section_exit(); |
caoyuan9642 | 0:084d1dae2ea1 | 44 | } |
caoyuan9642 | 0:084d1dae2ea1 | 45 | |
caoyuan9642 | 0:084d1dae2ea1 | 46 | void LCDConsole::init(int x0, int y0, int width, int height) |
caoyuan9642 | 0:084d1dae2ea1 | 47 | { |
caoyuan9642 | 0:084d1dae2ea1 | 48 | LCDConsole::x0 = x0; |
caoyuan9642 | 0:084d1dae2ea1 | 49 | LCDConsole::y0 = y0; |
caoyuan9642 | 0:084d1dae2ea1 | 50 | LCDConsole::width = width; |
caoyuan9642 | 0:084d1dae2ea1 | 51 | LCDConsole::height = height; |
caoyuan9642 | 0:084d1dae2ea1 | 52 | |
caoyuan9642 | 0:084d1dae2ea1 | 53 | // Clear area with background color |
caoyuan9642 | 0:084d1dae2ea1 | 54 | lcd.SetTextColor(BG_COLOR); |
caoyuan9642 | 0:084d1dae2ea1 | 55 | lcd.FillRect(x0, y0, width, height); |
caoyuan9642 | 0:084d1dae2ea1 | 56 | BSP_LCD_SetFont(&Font12); |
caoyuan9642 | 0:084d1dae2ea1 | 57 | |
caoyuan9642 | 0:084d1dae2ea1 | 58 | // Calculate width and height of the text area |
caoyuan9642 | 0:084d1dae2ea1 | 59 | textwidth = width / BSP_LCD_GetFont()->Width; |
caoyuan9642 | 0:084d1dae2ea1 | 60 | textheight = height / BSP_LCD_GetFont()->Height; |
caoyuan9642 | 0:084d1dae2ea1 | 61 | buffersize = textwidth * textheight; |
caoyuan9642 | 0:084d1dae2ea1 | 62 | |
caoyuan9642 | 0:084d1dae2ea1 | 63 | // Init buffer |
caoyuan9642 | 0:084d1dae2ea1 | 64 | buffer = new int[buffersize](); // Will be init to zero |
caoyuan9642 | 0:084d1dae2ea1 | 65 | head = tail = buffer; |
caoyuan9642 | 0:084d1dae2ea1 | 66 | |
caoyuan9642 | 0:084d1dae2ea1 | 67 | // Start task thread |
caoyuan9642 | 0:084d1dae2ea1 | 68 | thread.start(task_thread); |
caoyuan9642 | 0:084d1dae2ea1 | 69 | |
caoyuan9642 | 0:084d1dae2ea1 | 70 | // Register idle hook |
caoyuan9642 | 0:084d1dae2ea1 | 71 | Thread::attach_idle_hook(idle_hook); |
caoyuan9642 | 0:084d1dae2ea1 | 72 | MCULoadMeasurement::getInstance().reset(); |
caoyuan9642 | 0:084d1dae2ea1 | 73 | } |
caoyuan9642 | 0:084d1dae2ea1 | 74 | |
caoyuan9642 | 0:084d1dae2ea1 | 75 | void LCDConsole::task_thread() |
caoyuan9642 | 0:084d1dae2ea1 | 76 | { |
caoyuan9642 | 0:084d1dae2ea1 | 77 | int *buffer0 = new int[buffersize](); // Local buffer |
caoyuan9642 | 0:084d1dae2ea1 | 78 | char sbuf[64]; |
caoyuan9642 | 0:084d1dae2ea1 | 79 | // Main loop |
caoyuan9642 | 0:084d1dae2ea1 | 80 | while (true) |
caoyuan9642 | 0:084d1dae2ea1 | 81 | { |
caoyuan9642 | 0:084d1dae2ea1 | 82 | // Wait for update signal. |
caoyuan9642 | 0:084d1dae2ea1 | 83 | int s = sem_update.wait(1000); |
caoyuan9642 | 0:084d1dae2ea1 | 84 | if (s == 0) |
caoyuan9642 | 0:084d1dae2ea1 | 85 | { |
caoyuan9642 | 0:084d1dae2ea1 | 86 | // Timeout, update CPU usage |
caoyuan9642 | 0:084d1dae2ea1 | 87 | lcd.SetBackColor(LCD_COLOR_BLUE); |
caoyuan9642 | 0:084d1dae2ea1 | 88 | lcd.SetTextColor(LCD_COLOR_WHITE); |
caoyuan9642 | 0:084d1dae2ea1 | 89 | int len = sprintf(sbuf, "Load: %4.1f%% ", |
caoyuan9642 | 0:084d1dae2ea1 | 90 | MCULoadMeasurement::getInstance().getCPUUsage() * 100); |
caoyuan9642 | 0:084d1dae2ea1 | 91 | lcd.DisplayStringAt(0, lcd.GetYSize() - BSP_LCD_GetFont()->Height, |
caoyuan9642 | 0:084d1dae2ea1 | 92 | (unsigned char*) sbuf, LEFT_MODE); |
caoyuan9642 | 0:084d1dae2ea1 | 93 | MCULoadMeasurement::getInstance().reset(); |
caoyuan9642 | 0:084d1dae2ea1 | 94 | |
caoyuan9642 | 0:084d1dae2ea1 | 95 | time_t t = time(NULL); |
caoyuan9642 | 1:64c1fd738059 | 96 | |
caoyuan9642 | 6:1b97c5f92717 | 97 | #if !( defined(__ARMCC_VERSION) || defined(__CC_ARM) ) |
caoyu@caoyuan9642-desktop.MIT.EDU | 5:5ea2862a3493 | 98 | struct tm ts; |
caoyu@caoyuan9642-desktop.MIT.EDU | 5:5ea2862a3493 | 99 | localtime_r(&t, &ts); |
caoyu@caoyuan9642-desktop.MIT.EDU | 5:5ea2862a3493 | 100 | strftime(sbuf, sizeof(sbuf), "%T, %x", &ts); |
caoyu@caoyuan9642-desktop.MIT.EDU | 5:5ea2862a3493 | 101 | #else |
caoyuan9642 | 1:64c1fd738059 | 102 | core_util_critical_section_enter(); |
caoyuan9642 | 1:64c1fd738059 | 103 | struct tm &ts = *localtime(&t); |
caoyuan9642 | 0:084d1dae2ea1 | 104 | strftime(sbuf, sizeof(sbuf), "%T, %x", &ts); |
caoyuan9642 | 1:64c1fd738059 | 105 | core_util_critical_section_exit(); |
caoyu@caoyuan9642-desktop.MIT.EDU | 5:5ea2862a3493 | 106 | #endif |
caoyuan9642 | 1:64c1fd738059 | 107 | |
caoyuan9642 | 0:084d1dae2ea1 | 108 | strcat(sbuf, " UTC"); // append |
caoyuan9642 | 0:084d1dae2ea1 | 109 | |
caoyuan9642 | 0:084d1dae2ea1 | 110 | lcd.SetBackColor(0xFF00AF7F); |
caoyuan9642 | 0:084d1dae2ea1 | 111 | lcd.DisplayStringAt(BSP_LCD_GetFont()->Width * len, |
caoyuan9642 | 0:084d1dae2ea1 | 112 | lcd.GetYSize() - BSP_LCD_GetFont()->Height, |
caoyuan9642 | 0:084d1dae2ea1 | 113 | (unsigned char*) sbuf, LEFT_MODE); |
caoyuan9642 | 0:084d1dae2ea1 | 114 | |
caoyuan9642 | 0:084d1dae2ea1 | 115 | continue; |
caoyuan9642 | 0:084d1dae2ea1 | 116 | } |
caoyuan9642 | 0:084d1dae2ea1 | 117 | |
caoyuan9642 | 0:084d1dae2ea1 | 118 | mutex.lock(); // Lock the buffer. If any thread is still printing stuff to the buffer, this will wait for it to finish |
caoyuan9642 | 0:084d1dae2ea1 | 119 | memcpy(buffer0, buffer, buffersize * sizeof(*buffer)); // Copy buffer to a private one to work in |
caoyuan9642 | 0:084d1dae2ea1 | 120 | mutex.unlock(); // Unlock the buffer. If any thread is waiting for the mutex, it can now run (and potentially generating another update signal). |
caoyuan9642 | 0:084d1dae2ea1 | 121 | |
caoyuan9642 | 0:084d1dae2ea1 | 122 | int *head0 = buffer0 + (head - buffer); |
caoyuan9642 | 0:084d1dae2ea1 | 123 | // clear area; |
caoyuan9642 | 0:084d1dae2ea1 | 124 | // lcd.SetTextColor(BG_COLOR); |
caoyuan9642 | 0:084d1dae2ea1 | 125 | // lcd.FillRect(x0, y0, width, height); |
caoyuan9642 | 0:084d1dae2ea1 | 126 | |
caoyuan9642 | 0:084d1dae2ea1 | 127 | int line = 0, col = 0; |
caoyuan9642 | 0:084d1dae2ea1 | 128 | int x = x0, y = y0; |
caoyuan9642 | 0:084d1dae2ea1 | 129 | lcd.SetBackColor(BG_COLOR); |
caoyuan9642 | 0:084d1dae2ea1 | 130 | for (int *p = head0, i = 0; i < buffersize; i++) |
caoyuan9642 | 0:084d1dae2ea1 | 131 | { |
caoyuan9642 | 0:084d1dae2ea1 | 132 | // Set color from the buffer |
caoyuan9642 | 0:084d1dae2ea1 | 133 | lcd.SetTextColor((uint32_t(0xFF000000 | (*p >> 8)))); |
caoyuan9642 | 0:084d1dae2ea1 | 134 | |
caoyuan9642 | 0:084d1dae2ea1 | 135 | // Content to draw |
caoyuan9642 | 0:084d1dae2ea1 | 136 | unsigned char c = (*p) & 0xFF; |
caoyuan9642 | 0:084d1dae2ea1 | 137 | |
caoyuan9642 | 0:084d1dae2ea1 | 138 | // Display the char if displayable, otherwise put white space |
caoyuan9642 | 0:084d1dae2ea1 | 139 | if (isprint(c)) |
caoyuan9642 | 0:084d1dae2ea1 | 140 | lcd.DisplayChar(x, y, c); |
caoyuan9642 | 0:084d1dae2ea1 | 141 | else |
caoyuan9642 | 0:084d1dae2ea1 | 142 | lcd.DisplayChar(x, y, ' '); |
caoyuan9642 | 0:084d1dae2ea1 | 143 | |
caoyuan9642 | 0:084d1dae2ea1 | 144 | x += BSP_LCD_GetFont()->Width; |
caoyuan9642 | 0:084d1dae2ea1 | 145 | col++; |
caoyuan9642 | 0:084d1dae2ea1 | 146 | if (col == textwidth) |
caoyuan9642 | 0:084d1dae2ea1 | 147 | { |
caoyuan9642 | 0:084d1dae2ea1 | 148 | // Next line |
caoyuan9642 | 0:084d1dae2ea1 | 149 | line++; |
caoyuan9642 | 0:084d1dae2ea1 | 150 | y += BSP_LCD_GetFont()->Height; |
caoyuan9642 | 0:084d1dae2ea1 | 151 | col = 0; |
caoyuan9642 | 0:084d1dae2ea1 | 152 | x = 0; |
caoyuan9642 | 0:084d1dae2ea1 | 153 | } |
caoyuan9642 | 0:084d1dae2ea1 | 154 | p++; |
caoyuan9642 | 0:084d1dae2ea1 | 155 | if (p - buffer0 == buffersize) |
caoyuan9642 | 0:084d1dae2ea1 | 156 | p = buffer0; // wrap around the buffer |
caoyuan9642 | 0:084d1dae2ea1 | 157 | } |
caoyuan9642 | 0:084d1dae2ea1 | 158 | } |
caoyuan9642 | 0:084d1dae2ea1 | 159 | } |
caoyuan9642 | 0:084d1dae2ea1 | 160 | |
caoyuan9642 | 0:084d1dae2ea1 | 161 | LCDConsole::LCDConsole(const char * name, uint32_t color) : |
caoyuan9642 | 0:084d1dae2ea1 | 162 | FileLike(name) |
caoyuan9642 | 0:084d1dae2ea1 | 163 | { |
caoyuan9642 | 0:084d1dae2ea1 | 164 | this->color = color; |
caoyuan9642 | 0:084d1dae2ea1 | 165 | } |
caoyuan9642 | 0:084d1dae2ea1 | 166 | |
caoyuan9642 | 0:084d1dae2ea1 | 167 | ssize_t LCDConsole::read(void* buffer, size_t size) |
caoyuan9642 | 0:084d1dae2ea1 | 168 | { |
caoyuan9642 | 0:084d1dae2ea1 | 169 | // Not supported |
caoyuan9642 | 0:084d1dae2ea1 | 170 | return -1; |
caoyuan9642 | 0:084d1dae2ea1 | 171 | } |
caoyuan9642 | 0:084d1dae2ea1 | 172 | |
caoyuan9642 | 0:084d1dae2ea1 | 173 | ssize_t LCDConsole::write(const void* str, size_t size) |
caoyuan9642 | 0:084d1dae2ea1 | 174 | { |
caoyuan9642 | 0:084d1dae2ea1 | 175 | mutex.lock(); |
caoyuan9642 | 0:084d1dae2ea1 | 176 | char *pb = (char*) str; |
caoyuan9642 | 0:084d1dae2ea1 | 177 | for (char *p = pb; p < pb + size; p++) |
caoyuan9642 | 0:084d1dae2ea1 | 178 | { |
caoyuan9642 | 0:084d1dae2ea1 | 179 | char c = (int) (*p); |
caoyuan9642 | 0:084d1dae2ea1 | 180 | bool scroll = false; |
caoyuan9642 | 0:084d1dae2ea1 | 181 | if (isprint(c)) |
caoyuan9642 | 0:084d1dae2ea1 | 182 | { |
caoyuan9642 | 0:084d1dae2ea1 | 183 | *(tail++) = (color << 8) | c; // Put the current char and color into the buffer |
caoyuan9642 | 0:084d1dae2ea1 | 184 | if (tail >= buffer + buffersize) |
caoyuan9642 | 0:084d1dae2ea1 | 185 | tail -= buffersize; |
caoyuan9642 | 0:084d1dae2ea1 | 186 | if (tail == head) |
caoyuan9642 | 0:084d1dae2ea1 | 187 | scroll = true; |
caoyuan9642 | 0:084d1dae2ea1 | 188 | } |
caoyuan9642 | 0:084d1dae2ea1 | 189 | else if (c == '\b') |
caoyuan9642 | 0:084d1dae2ea1 | 190 | { |
caoyuan9642 | 0:084d1dae2ea1 | 191 | // Backspace, tail pointer go back by one |
caoyuan9642 | 0:084d1dae2ea1 | 192 | if (tail != head) // If the buffer is empty, do nothing |
caoyuan9642 | 0:084d1dae2ea1 | 193 | { |
caoyuan9642 | 0:084d1dae2ea1 | 194 | tail--; |
caoyuan9642 | 0:084d1dae2ea1 | 195 | if (tail < buffer) |
caoyuan9642 | 0:084d1dae2ea1 | 196 | tail += buffersize; |
caoyuan9642 | 0:084d1dae2ea1 | 197 | } |
caoyuan9642 | 0:084d1dae2ea1 | 198 | |
caoyuan9642 | 0:084d1dae2ea1 | 199 | } |
caoyuan9642 | 0:084d1dae2ea1 | 200 | else if (c == '\r') |
caoyuan9642 | 0:084d1dae2ea1 | 201 | { |
caoyuan9642 | 0:084d1dae2ea1 | 202 | // Roll back to start of line |
caoyuan9642 | 0:084d1dae2ea1 | 203 | int currpos = (tail - head + buffersize) % buffersize; // current position in buffer |
caoyuan9642 | 0:084d1dae2ea1 | 204 | int linestart = currpos - currpos % textwidth; // Position of the start of the line |
caoyuan9642 | 0:084d1dae2ea1 | 205 | tail = head + linestart; |
caoyuan9642 | 0:084d1dae2ea1 | 206 | if (tail >= buffer + buffersize) |
caoyuan9642 | 0:084d1dae2ea1 | 207 | tail -= buffersize; |
caoyuan9642 | 0:084d1dae2ea1 | 208 | } |
caoyuan9642 | 0:084d1dae2ea1 | 209 | else if (c == '\n') |
caoyuan9642 | 0:084d1dae2ea1 | 210 | { |
caoyuan9642 | 0:084d1dae2ea1 | 211 | // Newline |
caoyuan9642 | 0:084d1dae2ea1 | 212 | int currpos = (tail - head + buffersize) % buffersize; // current position in buffer |
caoyuan9642 | 0:084d1dae2ea1 | 213 | int nextlinestart = currpos - currpos % textwidth + textwidth; // Position of a new line start |
caoyuan9642 | 0:084d1dae2ea1 | 214 | tail = head + nextlinestart; |
caoyuan9642 | 0:084d1dae2ea1 | 215 | if (tail >= buffer + buffersize) |
caoyuan9642 | 0:084d1dae2ea1 | 216 | tail -= buffersize; |
caoyuan9642 | 0:084d1dae2ea1 | 217 | if (nextlinestart >= buffersize) // Scroll if the tail will overrun the head |
caoyuan9642 | 0:084d1dae2ea1 | 218 | scroll = true; |
caoyuan9642 | 0:084d1dae2ea1 | 219 | } |
caoyuan9642 | 0:084d1dae2ea1 | 220 | |
caoyuan9642 | 0:084d1dae2ea1 | 221 | // wrap |
caoyuan9642 | 0:084d1dae2ea1 | 222 | |
caoyuan9642 | 0:084d1dae2ea1 | 223 | if (scroll) |
caoyuan9642 | 0:084d1dae2ea1 | 224 | { |
caoyuan9642 | 0:084d1dae2ea1 | 225 | // Scroll a line |
caoyuan9642 | 0:084d1dae2ea1 | 226 | head += textwidth; // Increase head by one line |
caoyuan9642 | 0:084d1dae2ea1 | 227 | if (head >= buffer + buffersize) |
caoyuan9642 | 0:084d1dae2ea1 | 228 | { |
caoyuan9642 | 0:084d1dae2ea1 | 229 | head -= buffersize; // wrap |
caoyuan9642 | 0:084d1dae2ea1 | 230 | } |
caoyuan9642 | 0:084d1dae2ea1 | 231 | for (int *p = tail; p != head;) |
caoyuan9642 | 0:084d1dae2ea1 | 232 | { |
caoyuan9642 | 0:084d1dae2ea1 | 233 | *(p++) = 0; // Set everything between tail and head to null |
caoyuan9642 | 0:084d1dae2ea1 | 234 | if (p >= buffer + buffersize) |
caoyuan9642 | 0:084d1dae2ea1 | 235 | { |
caoyuan9642 | 0:084d1dae2ea1 | 236 | p -= buffersize; |
caoyuan9642 | 0:084d1dae2ea1 | 237 | } |
caoyuan9642 | 0:084d1dae2ea1 | 238 | } |
caoyuan9642 | 0:084d1dae2ea1 | 239 | } |
caoyuan9642 | 0:084d1dae2ea1 | 240 | } |
caoyuan9642 | 0:084d1dae2ea1 | 241 | sem_update.release(); // Signal the task to update the graphics |
caoyuan9642 | 0:084d1dae2ea1 | 242 | |
caoyuan9642 | 0:084d1dae2ea1 | 243 | mutex.unlock(); |
caoyuan9642 | 0:084d1dae2ea1 | 244 | return size; |
caoyuan9642 | 0:084d1dae2ea1 | 245 | } |
caoyuan9642 | 0:084d1dae2ea1 | 246 | |
caoyuan9642 | 0:084d1dae2ea1 | 247 | off_t LCDConsole::seek(off_t offset, int whence) |
caoyuan9642 | 0:084d1dae2ea1 | 248 | { |
caoyuan9642 | 0:084d1dae2ea1 | 249 | // Not supported |
caoyuan9642 | 0:084d1dae2ea1 | 250 | return -1; |
caoyuan9642 | 0:084d1dae2ea1 | 251 | } |
caoyuan9642 | 0:084d1dae2ea1 | 252 | |
caoyuan9642 | 0:084d1dae2ea1 | 253 | int LCDConsole::close() |
caoyuan9642 | 0:084d1dae2ea1 | 254 | { |
caoyuan9642 | 0:084d1dae2ea1 | 255 | return 0; |
caoyuan9642 | 0:084d1dae2ea1 | 256 | } |
caoyuan9642 | 0:084d1dae2ea1 | 257 | |
caoyuan9642 | 0:084d1dae2ea1 | 258 | void LCDConsole::redirect(bool tolcd) |
caoyuan9642 | 0:084d1dae2ea1 | 259 | { |
caoyuan9642 | 0:084d1dae2ea1 | 260 | if (tolcd) |
caoyuan9642 | 0:084d1dae2ea1 | 261 | { |
caoyuan9642 | 0:084d1dae2ea1 | 262 | freopen("/lcd_stdout", "w", stdout); |
caoyuan9642 | 0:084d1dae2ea1 | 263 | freopen("/lcd_stderr", "w", stderr); |
caoyuan9642 | 0:084d1dae2ea1 | 264 | } |
caoyuan9642 | 0:084d1dae2ea1 | 265 | else |
caoyuan9642 | 0:084d1dae2ea1 | 266 | { |
caoyuan9642 | 0:084d1dae2ea1 | 267 | freopen("/stdout", "w", stdout); |
caoyuan9642 | 0:084d1dae2ea1 | 268 | freopen("/stderr", "w", stderr); |
caoyuan9642 | 0:084d1dae2ea1 | 269 | } |
caoyuan9642 | 0:084d1dae2ea1 | 270 | } |
caoyuan9642 | 0:084d1dae2ea1 | 271 | |
caoyuan9642 | 0:084d1dae2ea1 | 272 | // Override the default fatal error handler |
caoyuan9642 | 0:084d1dae2ea1 | 273 | extern "C" void error(const char* format, ...) |
caoyuan9642 | 0:084d1dae2ea1 | 274 | { |
caoyuan9642 | 0:084d1dae2ea1 | 275 | static unsigned char buffer[257]; |
caoyuan9642 | 0:084d1dae2ea1 | 276 | core_util_critical_section_enter(); |
caoyuan9642 | 0:084d1dae2ea1 | 277 | #ifndef NDEBUG |
caoyuan9642 | 0:084d1dae2ea1 | 278 | |
caoyuan9642 | 0:084d1dae2ea1 | 279 | LCD_DISCO_F429ZI lcd; // Use local copy of the lcd, so that this function can be used at any stage of the initialization. |
caoyuan9642 | 0:084d1dae2ea1 | 280 | va_list arg; |
caoyuan9642 | 0:084d1dae2ea1 | 281 | va_start(arg, format); |
caoyuan9642 | 0:084d1dae2ea1 | 282 | int size = vsnprintf((char*) buffer, 256, format, arg); |
caoyuan9642 | 0:084d1dae2ea1 | 283 | if (size > 256) |
caoyuan9642 | 0:084d1dae2ea1 | 284 | { |
caoyuan9642 | 0:084d1dae2ea1 | 285 | // Properly terminate the string |
caoyuan9642 | 0:084d1dae2ea1 | 286 | size = 256; |
caoyuan9642 | 0:084d1dae2ea1 | 287 | buffer[256] = '\0'; |
caoyuan9642 | 0:084d1dae2ea1 | 288 | } |
caoyuan9642 | 0:084d1dae2ea1 | 289 | va_end(arg); |
caoyuan9642 | 0:084d1dae2ea1 | 290 | |
caoyuan9642 | 0:084d1dae2ea1 | 291 | BSP_LCD_SetFont(&Font20); |
caoyuan9642 | 0:084d1dae2ea1 | 292 | |
caoyuan9642 | 0:084d1dae2ea1 | 293 | lcd.Clear(LCD_COLOR_WHITE); |
caoyuan9642 | 0:084d1dae2ea1 | 294 | lcd.SetBackColor(LCD_COLOR_WHITE); |
caoyuan9642 | 0:084d1dae2ea1 | 295 | lcd.SetTextColor(LCD_COLOR_RED); |
caoyuan9642 | 0:084d1dae2ea1 | 296 | |
caoyuan9642 | 0:084d1dae2ea1 | 297 | int i = 0, line = 0; |
caoyuan9642 | 0:084d1dae2ea1 | 298 | while (i < size) |
caoyuan9642 | 0:084d1dae2ea1 | 299 | { |
caoyuan9642 | 0:084d1dae2ea1 | 300 | unsigned char c = buffer[i + 16]; |
caoyuan9642 | 0:084d1dae2ea1 | 301 | buffer[i + 16] = '\0'; |
caoyuan9642 | 0:084d1dae2ea1 | 302 | lcd.DisplayStringAtLine(line++, buffer + i); |
caoyuan9642 | 0:084d1dae2ea1 | 303 | buffer[i + 16] = c; |
caoyuan9642 | 0:084d1dae2ea1 | 304 | i += 16; |
caoyuan9642 | 0:084d1dae2ea1 | 305 | } |
caoyuan9642 | 0:084d1dae2ea1 | 306 | #endif |
caoyuan9642 | 0:084d1dae2ea1 | 307 | |
caoyuan9642 | 0:084d1dae2ea1 | 308 | core_util_critical_section_exit(); |
caoyuan9642 | 0:084d1dae2ea1 | 309 | exit(1); |
caoyuan9642 | 0:084d1dae2ea1 | 310 | } |
caoyuan9642 | 0:084d1dae2ea1 | 311 | |
caoyuan9642 | 0:084d1dae2ea1 | 312 |