2 #include <mbed.h> |
2 #include <mbed.h> |
3 #include <rtos.h> |
3 #include <rtos.h> |
4 #include "display.h" |
4 #include "display.h" |
5 |
5 |
6 |
6 |
|
7 static DSP table[] = |
|
8 { // cmd, fg, bg, x0, y0, fmt, maxsize, width, font |
|
9 { 0x00, 0xF, 0x0, 0, 0, FMT_ASCII, MAX_BUFF, 255, Mono19x27}, // main display |
|
10 { 0x0C, 0xF, 0x0,194, 38, FMT_ASCII, 3, 45, Mono15x22}, // channels display |
|
11 { 0x0A, 0xF, 0x0, 0, 57, FMT_FLAGS, 4, 0, Terminal6x8}, // flags + bits |
|
12 }; |
|
13 |
|
14 // 9x10 |
|
15 const unsigned char icon_alarm[] __attribute__((aligned (2))) = |
|
16 { |
|
17 0x1c, 0x0, |
|
18 0x3e, 0x0, |
|
19 0x7f, 0x0, |
|
20 0x7f, 0x0, |
|
21 0x7f, 0x0, |
|
22 0x7f, 0x0, |
|
23 0x7f, 0x0, |
|
24 0x7f, 0x0, |
|
25 0xff, 0x80, |
|
26 0x10, 0x0 |
|
27 }; |
|
28 |
|
29 const unsigned char icon_curve[] __attribute__((aligned (2))) = |
|
30 { |
|
31 0x80, 0x0, |
|
32 0x80, 0x0, |
|
33 0x80, 0x80, |
|
34 0x81, 0x0, |
|
35 0x9e, 0x0, |
|
36 0xa0, 0x0, |
|
37 0xc0, 0x0, |
|
38 0x80, 0x0, |
|
39 0x80, 0x0, |
|
40 0xff, 0x80 |
|
41 }; |
|
42 |
|
43 static const flags_map flags = { |
|
44 // id x0 y0 rev. msg icon |
|
45 { 0x00, {246, 27, 0, 0, false, NULL, icon_alarm}}, // F1.0 01 00 00 00 |
|
46 { 0x01, {246, 38, 0, 0, false, NULL, icon_curve}}, // F1.1 02 00 00 00 |
|
47 { 0x02, {192, 32, 240, 60, false, NULL, NULL}}, // F1.2 04 00 00 00 - Channel frame |
|
48 { 0x03, {195, 29, 0, 0, false, "CHANNEL", NULL}}, // F1.3 08 00 00 00 |
|
49 { 0x1c, {0, 38, 0, 0, false, "MON", NULL}}, // F4.4 00 00 00 10 |
|
50 { 0x1b, {0, 47, 0, 0, false, "VIEW", NULL}}, // F4.3 00 00 00 08 |
|
51 { 0x1d, {0, 29, 0, 0, true, "SCAN", NULL}}, // F4.5 00 00 00 20 |
|
52 { 0x1e, {0, 56, 0, 0, true, "CONFIG", NULL}}, // F4.6 00 00 00 40 |
|
53 { 0x1a, {40, 56, 0, 0, false, "*", NULL}}, // F4.2 00 00 00 04 |
|
54 { 0x19, {50, 56, 0, 0, false, "ADRS", NULL}}, // F4.1 00 00 00 02 |
|
55 { 0x18, {80, 56, 0, 0, false, "RMT", NULL}}, // F4.0 00 00 00 01 |
|
56 { 0x17, {104, 56, 0, 0, true, "ERROR", NULL}}, // F3.7 00 00 80 00 |
|
57 { 0x16, {86, 38, 0, 0, false, "EXT", NULL}}, // F3.6 00 00 40 00 |
|
58 { 0x15, {60, 38, 0, 0, false, "ONCE", NULL}}, // F3.5 00 00 20 00 |
|
59 { 0x13, {40, 38, 0, 0, false, "MEM", NULL}}, // F3.3 00 00 08 00 |
|
60 { 0x0c, {244, 47, 0, 0, false, "4W", NULL}}, // F2.4 00 10 00 00 |
|
61 { 0x0d, {244, 56, 0, 0, false, "OC", NULL}}, // F2.5 00 20 00 00 |
|
62 { 0x12, {40, 47, 0, 0, false, "LAST", NULL}}, // F3.2 00 00 04 00 |
|
63 { 0x11, {66, 47, 0, 0, false, "MIN", NULL}}, // F3.1 00 00 02 00 |
|
64 { 0x10, {86, 47, 0, 0, false, "MAX", NULL}}, // F3.0 00 00 01 00 |
|
65 { 0x0f, {106, 47, 0, 0, false, "AVG", NULL}}, // F2.7 00 80 00 00 |
|
66 { 0x05, {152, 29, 0, 0, false, "Alarm", NULL}}, // F1.5 20 00 00 00 |
|
67 { 0x08, {152, 39, 0, 0, false, "H", NULL}}, // F1.6 40 00 00 00 |
|
68 { 0x07, {158, 39, 0, 0, false, "1", NULL}}, // F2.3 00 08 00 00 |
|
69 { 0x06, {164, 39, 0, 0, false, "2", NULL}}, // F2.0 00 01 00 00 |
|
70 { 0x04, {170, 39, 0, 0, false, "3", NULL}}, // F2.2 00 04 00 00 |
|
71 { 0x09, {176, 39, 0, 0, false, "4", NULL}}, // F2.1 00 02 00 00 |
|
72 { 0x0a, {182, 39, 0, 0, false, "L", NULL}}, // F1.4 00 10 00 00 |
|
73 { 0x0b, {149, 32, 190, 50, false, NULL, NULL}}, // F1.7 - alarm frame |
|
74 |
|
75 { 0x0e, {152, 56, 0, 0, true, "SHIFT", NULL}}, // not an actual command, managed by the front panel |
|
76 |
|
77 { 0x14, {0xFF, 0xFF, 0xFF, 0xFF, false, NULL, NULL}}, // not an actual command, for the sake of completeness |
|
78 { 0x1f, {0xFF, 0xFF, 0xFF, 0xFF, false, NULL, NULL}}, // not an actual command, for the sake of completeness |
|
79 |
|
80 }; |
|
81 |
|
82 |
7 Display::Display(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, |
83 Display::Display(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, |
8 const char* name) |
84 const char* name) |
9 : SSD1322(Hz, mosi, miso, sclk, CS, reset, DC, name) |
85 : SSD1322(Hz, mosi, miso, sclk, CS, reset, DC, name) |
10 { |
86 { |
11 must_refresh = 0; |
87 must_refresh = 0; |
|
88 for (flags_map::const_iterator it=flags.cbegin(); it!=flags.cend(); ++it) |
|
89 { |
|
90 flags_status[it->first] = false; |
|
91 flags_dim[it->first] = false; |
|
92 } |
12 } |
93 } |
13 |
94 |
14 Display::~Display() |
95 Display::~Display() |
15 { |
96 { |
16 } |
97 } |
156 } |
233 } |
157 } |
234 } |
158 must_refresh = 1; |
235 must_refresh = 1; |
159 } |
236 } |
160 } |
237 } |
161 /* |
238 |
162 if (table[i].fmt & FMT_HEX ) { |
|
163 // hex |
|
164 for (uint8_t j=0;; j++) { |
|
165 if (txt[j] == 0x00) |
|
166 break; |
|
167 this->printf("%02X ", txt[j]); |
|
168 } |
|
169 for (uint8_t j=3*strlen(txt); j<table[i].maxsize; j++) |
|
170 this->printf(" "); |
|
171 } |
|
172 */ |
|
173 if (table[i].fmt & FMT_FLAGS ) // flag indicators |
239 if (table[i].fmt & FMT_FLAGS ) // flag indicators |
174 { |
240 { |
175 uint8_t nbyte; |
241 uint8_t id; |
176 uint8_t nbit; |
242 uint8_t c; |
177 uint16_t color; |
243 id = 0; |
178 // flags |
244 for (uint8_t nc=0; nc<4; nc++) |
179 for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l) |
|
180 { |
245 { |
181 nbyte = flags[l].flag / 8; |
246 c = intxt[nc]; |
182 nbit = flags[l].flag % 8; |
247 for (uint8_t nb=0; nb<8; nb++) |
183 if (flags[l].dimm) |
248 { |
184 color = fgcolor/4; |
249 if (c & (0x01 << nb)) |
185 else |
250 set_flag_status(id, true); |
186 color = fgcolor; |
251 else |
187 |
252 set_flag_status(id, false); |
188 if (intxt[nbyte] & (1 << nbit)) |
253 draw_flag(id); |
189 { // draw the flag, possibly reversed fg/bg |
254 id++; |
190 foreground(flags[l].reverse ? bgcolor : color); |
|
191 background(flags[l].reverse ? color : bgcolor); |
|
192 } |
|
193 else |
|
194 { // erase the flag |
|
195 foreground(bgcolor); |
|
196 background(bgcolor); |
|
197 } |
|
198 if (flags[l].msg != NULL) |
|
199 { // flag is a string |
|
200 locate(flags[l].x, flags[l].y); |
|
201 this->printf(flags[l].msg);} |
|
202 else |
|
203 { // flag is an icon |
|
204 Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon}; |
|
205 Bitmap_BW(pic, flags[l].x, flags[l].y); |
|
206 } |
255 } |
207 } |
256 } |
208 |
|
209 // draw frames (Alarm and Channel) |
|
210 for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l) |
|
211 { |
|
212 nbyte = frames[l].flag / 8; |
|
213 nbit = frames[l].flag % 8; |
|
214 if (intxt[nbyte] & (1 << nbit)) |
|
215 color = fgcolor/6; |
|
216 else |
|
217 color = bgcolor; |
|
218 hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color); |
|
219 hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color); |
|
220 hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color); |
|
221 |
|
222 vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color); |
|
223 vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color); |
|
224 } |
|
225 must_refresh = 1; //|= zones[m].flag; |
|
226 } |
257 } |
227 |
258 |
228 for(uint8_t j=0; j<table[i].maxsize; j++) |
259 for(uint8_t j=0; j<table[i].maxsize; j++) |
229 oldv[j] = txt[j]; |
260 oldv[j] = txt[j]; |
230 break; |
261 break; |
231 } |
262 } |
232 } |
263 } |
233 pixel_buffer_mutex.unlock(); |
264 pixel_buffer_mutex.unlock(); |
234 |
265 } |
235 //free(txt); |
266 } |
236 //this->copy_to_lcd(); |
267 |
237 } |
268 |
238 } |
269 void Display::set_flag_status(uint8_t flagid, bool show) |
239 |
270 { |
240 |
271 flags_status[flagid] = show; |
241 void Display::set_flag(uint8_t flag, bool show, bool dimm) |
272 } |
|
273 |
|
274 void Display::set_flag_dim(uint8_t flagid, bool dim) |
|
275 { |
|
276 flags_dim[flagid] = dim; |
|
277 } |
|
278 |
|
279 void Display::draw_flag(uint8_t flagid) |
242 { |
280 { |
243 uint8_t i; |
281 uint8_t i; |
244 uint8_t bgcolor = 0x00, fgcolor = 0x0F; |
282 uint8_t bgcolor = 0x00, fgcolor = 0x0F; |
245 |
283 |
246 if (dimm) |
284 ::printf(" FLAG %X:", flagid); |
|
285 const FLAG flag = flags.at(flagid); // can't use the [] operator on a const map... |
|
286 if (flag.msg != NULL) |
|
287 ::printf("%s ", flag.msg); |
|
288 else if (flag.icon != NULL) |
|
289 ::printf("ICN "); |
|
290 else if (flag.x0 > 0) |
|
291 ::printf("FR[%dx%d] ", flag.x0, flag.y0); |
|
292 else |
|
293 ::printf(" WTF? "); |
|
294 |
|
295 if (flags_status[flagid]) |
|
296 { |
|
297 if (flags_dim[flagid]) |
|
298 ::printf(" DIM\n"); |
|
299 else |
|
300 ::printf(" ON\n"); |
|
301 } |
|
302 else |
|
303 ::printf(" OFF\n"); |
|
304 |
|
305 if ((flag.msg == NULL) && (flag.icon == NULL) && (flag.x0 == 0xFF) && (flag.y0 == 0xFF)) |
|
306 // noop command |
|
307 return; |
|
308 |
|
309 if (flags_dim[flagid]) |
247 fgcolor = fgcolor / 4; |
310 fgcolor = fgcolor / 4; |
248 |
311 else if ((flag.msg == NULL) && (flag.icon == NULL)) |
249 for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l) |
312 fgcolor = fgcolor / 6; // it's a frame |
250 { |
313 |
251 if (flag == flags[l].flag) |
314 if (flags_status[flagid]) |
252 { |
315 { |
253 set_font((unsigned char*)Terminal6x8); |
316 foreground(flag.reverse ? bgcolor : fgcolor); |
254 ::printf(" %s flag %x %s\n", show ? "show": "hide", flag, dimm ? "dimmed":"bright"); |
317 background(flag.reverse ? fgcolor : bgcolor); |
255 if (show) |
318 } |
256 { |
319 else |
257 foreground(flags[l].reverse ? bgcolor : fgcolor); |
320 { |
258 background(flags[l].reverse ? fgcolor : bgcolor); |
321 foreground(bgcolor); |
259 } |
322 background(bgcolor); |
260 else |
323 } |
261 { |
324 |
262 foreground(bgcolor); |
325 if (flag.msg != NULL) |
263 background(bgcolor); |
326 { |
264 } |
327 set_font((unsigned char*)Terminal6x8); |
265 if (flags[l].msg != NULL) |
328 locate(flag.x0, flag.y0); |
266 { // flag is a string |
329 this->printf(flag.msg); |
267 locate(flags[l].x, flags[l].y); |
330 } |
268 ::printf("Move cursor at %dx%d\n", flags[l].x, flags[l].y); |
331 else if (flag.icon != NULL) |
269 ::printf(" using fgcolor=%x\n", fgcolor); |
332 { // flag is an icon |
270 this->printf(flags[l].msg);} |
333 Bitmap_s pic = {9, 10, 2, (char*) flag.icon}; |
271 else |
334 Bitmap_BW(pic, flag.x0, flag.y0); |
272 { // flag is an icon |
335 } |
273 Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon}; |
336 else |
274 Bitmap_BW(pic, flags[l].x, flags[l].y); |
337 { // draw frames (Alarm and Channel) |
275 } |
338 hline(flag.x0+1, flag.x0+3, flag.y0, foreground()); |
276 } |
339 hline(flag.x1-3, flag.x1-1, flag.y0, foreground()); |
277 } |
340 hline(flag.x0+1, flag.x1-1, flag.y1, foreground()); |
278 |
341 |
279 // draw frames (Alarm and Channel) |
342 vline(flag.x0, flag.y0+1, flag.y1-1, foreground()); |
280 for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l) |
343 vline(flag.x1, flag.y0+1, flag.y1-1, foreground()); |
281 { |
344 } |
282 if (flag == frames[l].flag) |
345 |
283 { |
|
284 uint16_t color; |
|
285 if (show) |
|
286 color = fgcolor/6; |
|
287 else |
|
288 color = bgcolor; |
|
289 hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color); |
|
290 hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color); |
|
291 hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color); |
|
292 |
|
293 vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color); |
|
294 vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color); |
|
295 } |
|
296 } |
|
297 must_refresh = 1; |
346 must_refresh = 1; |
298 } |
347 } |
299 |
|
300 |
|
301 void Display::test_dsp() |
|
302 { |
|
303 const FRAME *z; |
|
304 printf("TEST DSP\r\n"); |
|
305 cls(); |
|
306 printf("TEST DSP #2\r\n"); |
|
307 show(0x00, "8g8g8g8g8g8g8", 13); // main dsp |
|
308 show(0x0C, "888", 3); // channel dsp |
|
309 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags |
|
310 copy_to_lcd(); |
|
311 ThisThread::sleep_for(3ms); |
|
312 cls(); |
|
313 printf("TEST DSP #3\r\n"); |
|
314 /* |
|
315 for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++) |
|
316 { |
|
317 z = &zones[i]; |
|
318 fillrect(z->x0, z->y0, z->x1, z->y1, 4+i); |
|
319 locate(z->x0+1, z->y0+1); |
|
320 this->printf("%d", i); |
|
321 } |
|
322 */ |
|
323 /* |
|
324 for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++) |
|
325 { |
|
326 z = &zones[i]; |
|
327 printf("Zone %d [%x]: %d, %d, %d, %d\n", i, z->flag, |
|
328 z->x0, z->y0, z->x1, z->y1); |
|
329 must_refresh = z->flag; |
|
330 wait(1); |
|
331 } |
|
332 printf("Done\n"); |
|
333 wait(2); |
|
334 printf("Copy ALL\n"); |
|
335 copy_to_lcd(); |
|
336 */ |
|
337 ThisThread::sleep_for(2ms); |
|
338 cls(); |
|
339 printf("TEST DSP DONE\r\n"); |
|
340 } |
|