108 uint8_t curchar; |
101 uint8_t curchar; |
109 //uint8_t curcmd; |
102 //uint8_t curcmd; |
110 uint8_t nchars; |
103 uint8_t nchars; |
111 char buffer[MAX_BUFF+1]; |
104 char buffer[MAX_BUFF+1]; |
112 |
105 |
|
106 void refresh_display(void); |
|
107 |
113 void timeout_h() { |
108 void timeout_h() { |
114 #if defined(HAS_LED) |
109 #if defined(HAS_LED) |
115 led = !led; |
110 led = !led; |
116 #endif |
111 #endif |
117 } |
112 } |
118 |
|
119 typedef struct _DSP |
|
120 { |
|
121 uint8_t cmd; |
|
122 uint8_t color; |
|
123 uint8_t bgcolor; |
|
124 uint8_t x0; |
|
125 uint8_t y0; |
|
126 uint8_t fmt; // 0x01=>ascii, 0x02=>hex, 0x04=>bits, 0x08=>flags, 0x80=>ignore |
|
127 uint8_t maxsize; |
|
128 uint8_t width; |
|
129 const unsigned char* font; |
|
130 char buffer[MAX_BUFF+1]; |
|
131 } DSP; |
|
132 |
|
133 static DSP table[] = |
|
134 { |
|
135 { 0x00, 0xF, 0x0, 0, 0, 0x01, MAX_BUFF, 245, Mono19x27}, // main display |
|
136 { 0x0C, 0xF, 0x0,196, 34, 0x01, 3, 45, Mono15x22}, // channels display |
|
137 { 0x0A, 0xF, 0x0, 0, 57, 0x08, 4, 0, Terminal6x8}, // flags + bits |
|
138 }; |
|
139 |
|
140 // 9x10 |
|
141 const unsigned char icon_alarm[] __attribute__((aligned (2))) = |
|
142 { |
|
143 0x1c, 0x0, |
|
144 0x3e, 0x0, |
|
145 0x7f, 0x0, |
|
146 0x7f, 0x0, |
|
147 0x7f, 0x0, |
|
148 0x7f, 0x0, |
|
149 0x7f, 0x0, |
|
150 0x7f, 0x0, |
|
151 0xff, 0x80, |
|
152 0x10, 0x0 |
|
153 }; |
|
154 |
|
155 const unsigned char icon_curve[] __attribute__((aligned (2))) = |
|
156 { |
|
157 0x80, 0x0, |
|
158 0x80, 0x0, |
|
159 0x80, 0x80, |
|
160 0x81, 0x0, |
|
161 0x9e, 0x0, |
|
162 0xa0, 0x0, |
|
163 0xc0, 0x0, |
|
164 0x80, 0x0, |
|
165 0x80, 0x0, |
|
166 0xff, 0x80 |
|
167 }; |
|
168 |
|
169 typedef struct _FLAG |
|
170 { |
|
171 uint8_t flag; |
|
172 uint8_t x; |
|
173 uint8_t y; |
|
174 bool reverse; |
|
175 const char* msg; |
|
176 const unsigned char* icon; |
|
177 } FLAG; |
|
178 |
|
179 typedef struct _FRAME |
|
180 { |
|
181 uint16_t flag; |
|
182 uint8_t x0; |
|
183 uint8_t y0; |
|
184 uint8_t x1; |
|
185 uint8_t y1; |
|
186 } FRAME; |
|
187 |
|
188 static const FLAG flags[] = |
|
189 { |
|
190 // flag, zone, x0, y0, reverse, msg, icon |
|
191 // right-side icons area |
|
192 { 0x00, 246, 0, false, NULL, icon_alarm}, // F1.0 |
|
193 { 0x01, 246, 11, false, NULL, icon_curve}, // F1.1 |
|
194 |
|
195 // F1.2 == Channel frame |
|
196 { 0x03, 197, 27, false, "Channel"}, // F1.3 |
|
197 // F1.7 == Alarm frame |
|
198 |
|
199 { 0x34, 0, 28+8, false, "MON"}, // F4.4 |
|
200 { 0x33, 0, 28+16, false, "VIEW"}, // F4.3 |
|
201 { 0x35, 0, 28, true, "SCAN"}, // F4.5 |
|
202 { 0x36, 0, 28+25, true, "CONFIG"}, // F4.6 |
|
203 |
|
204 { 0x32, 40, 52, false, "*"}, // F4.2 |
|
205 { 0x31, 50, 52, false, "ADRS"}, // F4.1 |
|
206 { 0x30, 80, 52, false, "RMT"}, // F4.0 |
|
207 { 0x27, 104, 52, true, "ERROR"}, // F3.7 |
|
208 |
|
209 { 0x26, 140, 52, false, "EXT"}, // F3.6 |
|
210 { 0x25, 164, 52, false, "ONCE"}, // F3.5 |
|
211 |
|
212 { 0x23, 104, 28+16, false, "MEM"}, // F3.3 |
|
213 |
|
214 |
|
215 // col 5 |
|
216 { 0x14, 244, 22, false, "4W"}, // F2.4 |
|
217 { 0x15, 244, 30, false, "OC"}, // F2.5 |
|
218 { 0x22, 129, 28+16, false, "LAST"}, // F3.2 |
|
219 { 0x21, 129, 28+16, false, "MIN"}, // F3.1 |
|
220 { 0x20, 129, 28+16, false, "MAX"}, // F3.0 |
|
221 { 0x17, 129, 28+16, false, "AVG"}, // F2.7 |
|
222 |
|
223 { 0x05, 154+0, 17+10, false, "Alarm"}, // F1.5 |
|
224 { 0x06, 154+0, 17+20, false, "H"}, // F1.6 |
|
225 { 0x13, 154+6, 17+20, false, "1"}, // F2.3 |
|
226 { 0x10, 154+12, 17+20, false, "2"}, // F2.0 |
|
227 { 0x12, 154+18, 17+20, false, "3"}, // F2.2 |
|
228 { 0x11, 154+24, 17+20, false, "4"}, // F2.1 |
|
229 { 0x04, 154+30, 17+20, false, "L"}, // F1.4 |
|
230 |
|
231 }; |
|
232 |
|
233 static const FRAME zones[] = |
|
234 { // flag, x0, y0, x1, y1 |
|
235 { 0x001, 0, 0, 245, 27}, // main display area |
|
236 { 0x002, 246, 0, 255, 27}, // right notif area |
|
237 { 0x004, 208, 35, 254, 62}, // channels display area |
|
238 { 0x008, 160, 28, 202, 54}, // alarms area |
|
239 { 0x010, 0, 28, 32, 54}, // flags col1 |
|
240 { 0x020, 33, 28, 70, 54}, // flags col2 |
|
241 { 0x040, 71, 28, 103, 54}, // flags col3 |
|
242 { 0x080, 104, 28, 128, 54}, // flags col4 |
|
243 { 0x100, 129, 28, 159, 54}, // flags col5 |
|
244 |
|
245 // { 0x8000, 0, 55, 255, 63}, // flags bits display area |
|
246 }; |
|
247 |
|
248 static const FRAME frames[] = |
|
249 { |
|
250 { 0x02, 194, 30, 243, 53}, // F1.2 - channel frame |
|
251 { 0x07, 151, 30, 192, 46}, // F1.7 - alarm frame |
|
252 }; |
|
253 |
|
254 |
113 |
255 #ifdef DEBUG |
114 #ifdef DEBUG |
256 |
115 |
257 DigitalOut dbgpin(DBGPIN); |
116 DigitalOut dbgpin(DBGPIN); |
258 inline void pulse(uint8_t count=1, bool stayup=false) |
117 inline void pulse(uint8_t count=1, bool stayup=false) |
359 printf(" DSP_MISO=%d\r\n", DSP_MISO); |
215 printf(" DSP_MISO=%d\r\n", DSP_MISO); |
360 printf(" DSP_SCLK=%d\r\n", DSP_SCLK); |
216 printf(" DSP_SCLK=%d\r\n", DSP_SCLK); |
361 printf(" DSP_CS=%d\r\n", DSP_CS); |
217 printf(" DSP_CS=%d\r\n", DSP_CS); |
362 printf(" DSP_RST=%d\r\n", DSP_RST); |
218 printf(" DSP_RST=%d\r\n", DSP_RST); |
363 printf(" DSP_DC=%d\r\n", DSP_DC); |
219 printf(" DSP_DC=%d\r\n", DSP_DC); |
364 dsp = new SSD1322(20000000, DSP_MOSI, DSP_MISO, DSP_SCLK, DSP_CS, |
220 dsp = new Display(20000000, DSP_MOSI, DSP_MISO, DSP_SCLK, DSP_CS, |
365 DSP_RST, DSP_DC, "SSD1322"); |
221 DSP_RST, DSP_DC, "SSD1322"); |
366 |
|
367 printf(" configure DSP\r\n"); |
|
368 dsp->background(Black); // set background to black |
|
369 dsp->foreground(0xF); |
|
370 dsp->cls(); |
|
371 |
222 |
372 //curcmd = 0xFF; |
223 //curcmd = 0xFF; |
373 curchar = 0; |
224 curchar = 0; |
374 nchars = 0; |
225 nchars = 0; |
375 |
226 |
376 for (uint8_t i=0; i<sizeof(table)/sizeof(table[0]); ++i) |
227 for (uint8_t i=0; i<sizeof(table)/sizeof(table[0]); ++i) |
377 memset(table[i].buffer, 0, MAX_BUFF+1); |
228 memset(table[i].buffer, 0, MAX_BUFF+1); |
378 |
229 |
379 printf(" display splash screen\r\n"); |
230 printf(" display splash screen\r\n"); |
380 dsp->locate(30, 10); |
231 dsp->show_splashscreen(); |
381 dsp->set_font((unsigned char*)Mono19x27); |
|
382 dsp->printf("HP34970A"); |
|
383 dsp->set_font((unsigned char*)Terminal6x8); |
|
384 dsp->locate(90, 40); |
|
385 dsp->printf("David Douard"); |
|
386 dsp->locate(0, 52); |
|
387 dsp->printf("Clock = %d ", SystemCoreClock); |
|
388 |
|
389 RCC_OscInitTypeDef cfg; |
|
390 HAL_RCC_GetOscConfig(&cfg); |
|
391 if (cfg.HSEState == RCC_HSE_BYPASS) |
|
392 dsp->printf("HSE:EXT "); |
|
393 else if (cfg.HSEState == RCC_HSE_ON) |
|
394 dsp->printf("HSE:XTAL "); |
|
395 else |
|
396 dsp->printf("HSE:OFF "); |
|
397 |
|
398 if (cfg.HSIState == RCC_HSI_ON) |
|
399 dsp->printf("HSI:ON "); |
|
400 else |
|
401 dsp->printf("HSI:OFF "); |
|
402 |
|
403 dsp->copy_to_lcd(); |
|
404 |
232 |
405 printf("Starting LCD thread\r\n"); |
233 printf("Starting LCD thread\r\n"); |
406 tdsp.start(©_to_lcd); |
234 tdsp.start(&refresh_display); |
407 |
235 |
408 printf("Starting Event thread\r\n"); |
236 //printf("Starting Event thread\r\n"); |
409 tloop.start(&loop); |
237 //tloop.start(&loop); |
410 |
238 |
411 /* |
239 /* |
412 dsp->clrbuff(); |
240 dsp->clrbuff(); |
413 show(0x00, "HH:MM:\tSS\t:mmmm", 15); // main dsp |
241 show(0x00, "HH:MM:\tSS\t:mmmm", 15); // main dsp |
414 show(0x0C, "888", 3); // channel dsp |
242 show(0x0C, "888", 3); // channel dsp |
415 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags |
243 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags |
416 */ |
244 */ |
417 |
245 |
418 printf("Attaching timers\r\n"); |
246 printf("Attaching timers\r\n"); |
419 splashscreen = true; |
247 splashscreen = true; |
420 splashscreen_timer.attach(callback(&end_splashscreen), 2); |
248 splashscreen_timer.attach(callback(&end_splashscreen), 2ms); |
421 rst.fall(&reset_irq); |
249 rst.fall(&reset_irq); |
422 |
250 |
423 printf("SETUP DONE\r\n"); |
251 printf("SETUP DONE\r\n"); |
424 } |
252 } |
425 |
253 |
476 mask = 1; |
303 mask = 1; |
477 } |
304 } |
478 */ |
305 */ |
479 pulse(0, false); |
306 pulse(0, false); |
480 |
307 |
481 ThisThread::sleep_for(30); |
308 ThisThread::sleep_for(30ms); |
482 } |
309 } |
483 } |
310 } |
484 |
|
485 void show(uint8_t cmd, const char *intxt, uint8_t nchar=0) |
|
486 { |
|
487 uint8_t i; |
|
488 // uint8_t len; |
|
489 uint16_t bgcolor, fgcolor; |
|
490 char *oldv; |
|
491 // char *txt; |
|
492 char *txtp; |
|
493 static char txt[256]; |
|
494 |
|
495 |
|
496 if (cmd == 0xFF) // cls |
|
497 { |
|
498 dsp->clrbuff(); |
|
499 } |
|
500 else |
|
501 { |
|
502 //txt = (char *)malloc(strlen(intxt)+1); |
|
503 strcpy(txt, intxt); |
|
504 txtp = txt; |
|
505 |
|
506 pulse(1, true); |
|
507 |
|
508 // len = MAX_BUFF; |
|
509 |
|
510 for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) { |
|
511 if (table[i].cmd == cmd) { |
|
512 bgcolor = table[i].bgcolor; |
|
513 fgcolor = table[i].color; |
|
514 dsp->background(bgcolor); |
|
515 dsp->foreground(fgcolor); |
|
516 dsp->set_font((unsigned char*) table[i].font); |
|
517 oldv = table[i].buffer; |
|
518 |
|
519 dsp->locate(table[i].x0, table[i].y0); |
|
520 |
|
521 if (table[i].fmt & 0x01) // ASCII text |
|
522 { |
|
523 if (strncmp(oldv, txt, table[i].maxsize) != 0) |
|
524 { |
|
525 if (table[i].width > 0) |
|
526 dsp->fillrect(table[i].x0, |
|
527 table[i].y0, |
|
528 table[i].x0 + table[i].width, |
|
529 table[i].y0 + table[i].font[2], |
|
530 bgcolor); |
|
531 for (uint8_t k=0; ;k++) |
|
532 { |
|
533 if (txtp[k] == 0x00) |
|
534 { |
|
535 dsp->printf(txtp); |
|
536 break; |
|
537 } |
|
538 if (txtp[k] == 0x09) |
|
539 { // \t is a special char for 'unselected' display value |
|
540 txtp[k] = 0x00; |
|
541 dsp->printf(txtp); |
|
542 |
|
543 if (fgcolor == table[i].color) |
|
544 fgcolor /= 2; |
|
545 else |
|
546 fgcolor = table[i].color; |
|
547 dsp->foreground(fgcolor); |
|
548 txtp = &(txtp[k+1]); |
|
549 k = 0; |
|
550 } |
|
551 } |
|
552 if (cmd == 0x00) // main area |
|
553 must_refresh |= 0x01; |
|
554 if (cmd == 0x0C) // channels area |
|
555 must_refresh |= 0x04; |
|
556 } |
|
557 } |
|
558 /* |
|
559 if (table[i].fmt & 0x02 ) { |
|
560 // hex |
|
561 for (uint8_t j=0;; j++) { |
|
562 if (txt[j] == 0x00) |
|
563 break; |
|
564 dsp->printf("%02X ", txt[j]); |
|
565 } |
|
566 for (uint8_t j=3*strlen(txt); j<table[i].maxsize; j++) |
|
567 dsp->printf(" "); |
|
568 } |
|
569 */ |
|
570 if (table[i].fmt & 0x08 ) // flag indicators |
|
571 { |
|
572 // flags |
|
573 for (uint8_t j=0; j<max(nchar, table[i].maxsize) ; j++) |
|
574 { |
|
575 for (uint8_t k=0; k<8; k++) |
|
576 { |
|
577 if (1) |
|
578 { //(txt[j] & (1 << k) ) != (oldv[j] & (1 << k))) { |
|
579 for (uint8_t l=0; |
|
580 l<(sizeof(flags)/sizeof(flags[0])); ++l) |
|
581 { |
|
582 if (flags[l].flag == ((j<<4) + k)) { |
|
583 if (txtp[j] & (1 << k)) |
|
584 { |
|
585 dsp->foreground(flags[l].reverse ? bgcolor : fgcolor); |
|
586 dsp->background(flags[l].reverse ? fgcolor : bgcolor); |
|
587 } |
|
588 else |
|
589 { |
|
590 dsp->foreground(bgcolor); |
|
591 dsp->background(bgcolor); |
|
592 } |
|
593 if (flags[l].msg != NULL) |
|
594 { // a string |
|
595 dsp->locate(flags[l].x, flags[l].y); |
|
596 dsp->printf(flags[l].msg);} |
|
597 else |
|
598 { // an icon |
|
599 Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon}; |
|
600 dsp->Bitmap_BW(pic, flags[l].x, flags[l].y); |
|
601 } |
|
602 must_refresh = 1; //|= zones[m].flag; |
|
603 break; |
|
604 } |
|
605 } |
|
606 } |
|
607 } |
|
608 } |
|
609 |
|
610 // draw frames (Alarm and Channel) |
|
611 for (uint8_t l=0; |
|
612 l<(sizeof(frames)/sizeof(frames[0])); ++l) |
|
613 { |
|
614 uint16_t color; |
|
615 if (frames[l].flag & txt[0]) // frame flags are on the 1st byte only |
|
616 color = fgcolor/6; |
|
617 else |
|
618 color = bgcolor; |
|
619 dsp->hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color); |
|
620 dsp->hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color); |
|
621 dsp->hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color); |
|
622 |
|
623 dsp->vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color); |
|
624 dsp->vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color); |
|
625 } |
|
626 } |
|
627 |
|
628 for(uint8_t j=0; j<table[i].maxsize; j++) |
|
629 oldv[j] = txt[j]; |
|
630 break; |
|
631 } |
|
632 } |
|
633 //free(txt); |
|
634 //dsp->copy_to_lcd(); |
|
635 pulse(1, false); |
|
636 } |
|
637 } |
|
638 |
|
639 void test_dsp() |
|
640 { |
|
641 const FRAME *z; |
|
642 printf("TEST DSP\r\n"); |
|
643 dsp->cls(); |
|
644 printf("TEST DSP #2\r\n"); |
|
645 show(0x00, "8g8g8g8g8g8g8", 13); // main dsp |
|
646 show(0x0C, "888", 3); // channel dsp |
|
647 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags |
|
648 dsp->copy_to_lcd(); |
|
649 ThisThread::sleep_for(3); |
|
650 dsp->cls(); |
|
651 printf("TEST DSP #3\r\n"); |
|
652 |
|
653 for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++) |
|
654 { |
|
655 z = &zones[i]; |
|
656 dsp->fillrect(z->x0, z->y0, z->x1, z->y1, 4+i); |
|
657 dsp->locate(z->x0+1, z->y0+1); |
|
658 dsp->printf("%d", i); |
|
659 } |
|
660 |
|
661 /* |
|
662 for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++) |
|
663 { |
|
664 z = &zones[i]; |
|
665 printf("Zone %d [%x]: %d, %d, %d, %d\n", i, z->flag, |
|
666 z->x0, z->y0, z->x1, z->y1); |
|
667 must_refresh = z->flag; |
|
668 wait(1); |
|
669 } |
|
670 printf("Done\n"); |
|
671 wait(2); |
|
672 printf("Copy ALL\n"); |
|
673 dsp->copy_to_lcd(); |
|
674 */ |
|
675 ThisThread::sleep_for(2); |
|
676 dsp->cls(); |
|
677 printf("TEST DSP DONE\r\n"); |
|
678 } |
|
679 |
|
680 |
311 |
681 void loop() |
312 void loop() |
682 { // run over and over |
313 { // run over and over |
683 keycode_t key; |
314 keycode_t key = {0, 0, KEY_NONE}; |
684 |
315 |
685 unsigned int err[8]; |
316 unsigned int err[8]; |
686 for (uint8_t i=0; i<8; i++) |
317 for (uint8_t i=0; i<8; i++) |
687 err[i] = 0; |
318 err[i] = 0; |
688 int p, pp; // rot encoder pulse counters |
319 int p, pp; // rot encoder pulse counters |