src/main.cpp

changeset 37
07e8ca2bdf6d
parent 36
a6c7292742a0
child 38
ffef9bbb345d
equal deleted inserted replaced
36:a6c7292742a0 37:07e8ca2bdf6d
2 2
3 #include <mbed.h> 3 #include <mbed.h>
4 #include <rtos.h> 4 #include <rtos.h>
5 #include <string> 5 #include <string>
6 6
7 #include "Terminal6x8.h"
8 #include "Mono19x27.h"
9 #include "Mono15x22.h"
10 #include "Arial12x12.h"
11
12 #include "SSD1322.h"
13 #include "hp34comm.h" 7 #include "hp34comm.h"
8 #include "display.h"
14 9
15 #include "QEI.h" 10 #include "QEI.h"
16 #include "Keypad.h" 11 #include "Keypad.h"
17 12
18 // Pins and device declarations 13 // Pins and device declarations
23 #endif 18 #endif
24 19
25 #include "platform/CircularBuffer.h" 20 #include "platform/CircularBuffer.h"
26 21
27 22
28 SSD1322 *dsp; 23 Display *dsp;
24 volatile bool splashscreen;
29 HPSerial *hp; 25 HPSerial *hp;
30 volatile uint8_t must_refresh;
31 Thread tdsp, tloop; 26 Thread tdsp, tloop;
32 Ticker blinker; 27 Ticker blinker;
33 Timeout rst_delay; 28 Timeout rst_delay;
34 Timeout splashscreen_timer; 29 Timeout splashscreen_timer;
35 InterruptIn rst(HP_RST); 30 InterruptIn rst(HP_RST);
36 31
37 QEI qenc(KP_ENC1, KP_ENC2, NC, 16); 32 QEI qenc(KP_ENC1, KP_ENC2, NC, 16);
38 volatile uint8_t knob; 33 volatile uint8_t knob;
39 bool shift; // true when kp is shifted, cleared by command 0x01 from Unit 34 bool shift; // true when kp is shifted, cleared by command 0x01 from Unit
40 volatile bool splashscreen;
41
42 35
43 typedef enum { 36 typedef enum {
44 KEY_NONE=0, 37 KEY_NONE=0,
45 KEY_PRESSED, 38 KEY_PRESSED,
46 KEY_RELEASED 39 KEY_RELEASED
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)
274 {} 133 {}
275 #endif 134 #endif
276 135
277 // callbacks & thread functions 136 // callbacks & thread functions
278 void loop(); 137 void loop();
279 void copy_to_lcd(void);
280 void test_dsp();
281 void reset(void); 138 void reset(void);
282 void reset_irq(void); 139 void reset_irq(void);
283 void qei_cb(int dir); 140 void qei_cb(int dir);
284 void end_splashscreen(void); 141 void end_splashscreen(void);
285 void show(uint8_t, const char*, uint8_t);
286 142
287 /* 143 /*
288 #if defined(HAVE_PC) 144 #if defined(HAVE_PC)
289 FileHandle *mbed::mbed_override_console(int fd) 145 FileHandle *mbed::mbed_override_console(int fd)
290 { 146 {
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(&copy_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
430 splashscreen = false; 258 splashscreen = false;
431 } 259 }
432 260
433 void reset_irq(void) 261 void reset_irq(void)
434 { 262 {
435 rst_delay.attach(callback(&reset), 0.1); 263 rst_delay.attach(callback(&reset), 1ms);
436 } 264 }
437 265
438 void reset(void) 266 void reset(void)
439 { 267 {
440 if (DigitalIn(HP_RST).read() == 0) { 268 if (DigitalIn(HP_RST).read() == 0) {
448 //printf("Value is ... %X\n", hp->search()); 276 //printf("Value is ... %X\n", hp->search());
449 hp->startup(); 277 hp->startup();
450 } 278 }
451 } 279 }
452 280
453 void copy_to_lcd(void) { 281 void refresh_display(void) {
454 //uint8_t mask=1; 282 //uint8_t mask=1;
455 283
456 while(1) { 284 while(1) {
457 pulse(0, true); 285 pulse(0, true);
458 if ((splashscreen == false) && (must_refresh)) { 286 if (splashscreen == false) {
459 must_refresh = 0;
460 //Thread::wait(20); // give a bit of time for some more cmds 287 //Thread::wait(20); // give a bit of time for some more cmds
461 dsp->copy_to_lcd(); 288 dsp->copy_to_lcd();
462 } 289 }
463 290
464 /* 291 /*
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
732 } 363 }
733 else 364 else
734 { 365 {
735 dsp->locate(140, 0); 366 dsp->locate(140, 0);
736 dsp->printf("KC: %dx%d[0x%s%X] %s", 367 dsp->printf("KC: %dx%d[0x%s%X] %s",
737 key.row, key.col, 368 key.row, key.col,
738 kp_mapping[key.row][key.col] <= 0x0F ? "0" : "", 369 kp_mapping[key.row][key.col] <= 0x0F ? "0" : "",
739 kp_mapping[key.row][key.col], 370 kp_mapping[key.row][key.col],
740 key.keyevent==KEY_PRESSED ? "PRE" : "REL"); 371 key.keyevent==KEY_PRESSED ? "PRE" : "REL");
741 dsp->copy_to_lcd(); 372 dsp->copy_to_lcd();
742 } 373 }
743 // cur_keycode.keyevent = KEY_NONE; 374 // cur_keycode.keyevent = KEY_NONE;
744 } 375 }
745 376
790 } else if (cmd.cmd == 0x86) { 421 } else if (cmd.cmd == 0x86) {
791 // shutdown 422 // shutdown
792 // TODO 423 // TODO
793 } else { 424 } else {
794 // display related commands 425 // display related commands
795 show(cmd.cmd, cmd.value, cmd.size); 426 dsp->show(cmd.cmd, cmd.value, cmd.size);
796 } 427 }
797 #if defined(HAS_LED) 428 #if defined(HAS_LED)
798 led = 0; 429 led = 0;
799 #endif 430 #endif
800 } 431 }
801 } 432 }
802 //else 433 //else
803 ThisThread::sleep_for(1); 434 ThisThread::sleep_for(1ms);
804 } 435 }
805 } 436 }
806 437
807 void qei_cb(int dir) 438 void qei_cb(int dir)
808 { 439 {
834 465
835 int main() 466 int main()
836 { 467 {
837 setup(); 468 setup();
838 printf("Main loop (noop)\r\n"); 469 printf("Main loop (noop)\r\n");
470 loop();
471 /*
839 while(1) 472 while(1)
840 { 473 {
841 timeout_h(); 474 timeout_h();
842 ThisThread::sleep_for(1); 475 ThisThread::sleep_for(1ms);
843 } 476 }
844 } 477 */
478 }

mercurial