Sun, 01 Nov 2020 22:21:19 +0100
Many improvements
- add support for dimm-based selection,
- add support for poweroff (at least power thr display off),
- add support for the initial key pressed during initialization sequence,
- fix a race condition (sending a keycode while receiving a message)
- add support for the shift button
- many code cleanups and improvements
#include "stdio.h" #include <mbed.h> #include <rtos.h> #include "display.h" Display::Display(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, const char* name) : SSD1322(Hz, mosi, miso, sclk, CS, reset, DC, name) { must_refresh = 0; } Display::~Display() { } void Display::show_splashscreen() { locate(30, 10); set_font((unsigned char*)Mono19x27); this->printf("HP34970A"); set_font((unsigned char*)Terminal6x8); locate(90, 40); this->printf("David Douard"); copy_to_lcd(); } void Display::show_byescreen() { cls(); background(0x00); foreground(0xFF); locate(30, 10); set_font((unsigned char*)Mono19x27); this->printf("Bye..."); copy_to_lcd(); } void Display::dimm_char(uint8_t n) { // dimm the char number of the currently displayed string of the main area; // do this by printing a modifed version of the last displayed string // but only alphanumeric chars should be counted (not the punctuation) static char txt[64]; char c; uint8_t len, i, j; // for which we need to look for the entry in the table for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) { if (table[i].cmd == 0x00) { ::printf("DIMM CHAR %d\n", n); ::printf("repl '%s'\n", table[i].buffer); len = strlen(table[i].buffer); if (n >= len) break; // nothing to do strncpy(txt, table[i].buffer, table[i].maxsize); // look for the actual position of the char in the string (only alphanum) // XXX very poor implementation... for (j=0; (j<len)&&(j<=n); j++) { c = txt[j]; if ((c == ',') || (c == '.') || (c == ';') || (c == ':') || (c == ' ')) n++; } // now move the end of the string for char n to steps on the right // so we can insert our 2 '\t' characters before and after the // character to dimm for (j=len; j>n; j--) { txt[j+2] = txt[j]; } txt[n+2] = '\t'; txt[n+1] = txt[n]; txt[n] = '\t'; txt[len+2] = 0x00; // make sure the string will be terminated ::printf("with '%s'\n", txt); // now display this string show(0x00, txt, 0); break; } } } void Display::show(uint8_t cmd, const char *intxt, uint8_t nchar=0) { uint8_t i; // uint8_t len; uint16_t bgcolor, fgcolor; char *oldv; // char *txt; char *txtp; static char txt[64]; if (cmd == 0xFF) // cls { clrbuff(); } else if (cmd == 0x0D) { // dimm a character of the main area dimm_char(intxt[0]); } else { for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) { if (table[i].cmd == cmd) { strcpy(txt, intxt); txtp = txt; bgcolor = table[i].bgcolor; fgcolor = table[i].color; background(bgcolor); foreground(fgcolor); set_font((unsigned char*) table[i].font); oldv = table[i].buffer; locate(table[i].x0, table[i].y0); if (table[i].fmt & FMT_ASCII) // ASCII text { // check if the string has changed since last time if (strncmp(oldv, txt, table[i].maxsize) != 0) { // clear the text area if (table[i].width > 0) fillrect(table[i].x0, table[i].y0, table[i].x0 + table[i].width, table[i].y0 + table[i].font[2] - 1, bgcolor); // draw chars by portions of string separated by \t (highlight) for (uint8_t k=0; ;k++) { if (txtp[k] == 0x00) { // end of string, display it this->printf(txtp); break; } if (txtp[k] == 0x09) { // \t is a special char for 'unselected' display value // first disply the beginning of the string txtp[k] = 0x00; this->printf(txtp); // swap the fg color (dimm/bright) if (fgcolor == table[i].color) fgcolor /= 2; else fgcolor = table[i].color; foreground(fgcolor); // continue on the next with part of the string txtp = &(txtp[k+1]); k = 0; } } must_refresh = 1; } } /* if (table[i].fmt & FMT_HEX ) { // hex for (uint8_t j=0;; j++) { if (txt[j] == 0x00) break; this->printf("%02X ", txt[j]); } for (uint8_t j=3*strlen(txt); j<table[i].maxsize; j++) this->printf(" "); } */ if (table[i].fmt & FMT_FLAGS ) // flag indicators { uint8_t nbyte; uint8_t nbit; // flags for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l) { nbyte = flags[l].flag / 8; nbit = flags[l].flag % 8; if (intxt[nbyte] & (1 << nbit)) { // draw the flag, possibly reversed fg/bg foreground(flags[l].reverse ? bgcolor : fgcolor); background(flags[l].reverse ? fgcolor : bgcolor); } else { // erase the flag foreground(bgcolor); background(bgcolor); } if (flags[l].msg != NULL) { // flag is a string locate(flags[l].x, flags[l].y); this->printf(flags[l].msg);} else { // flag is an icon Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon}; Bitmap_BW(pic, flags[l].x, flags[l].y); } } // draw frames (Alarm and Channel) for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l) { uint16_t color; if (intxt[0] & (1 << frames[l].flag)) // frame flags are on the 1st byte only color = fgcolor/6; else color = bgcolor; hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color); hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color); hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color); vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color); vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color); } must_refresh = 1; //|= zones[m].flag; } for(uint8_t j=0; j<table[i].maxsize; j++) oldv[j] = txt[j]; break; } } //free(txt); //this->copy_to_lcd(); } } void Display::set_flag(uint8_t flag, bool show=true) { uint8_t i; uint8_t bgcolor = 0x00, fgcolor = 0xFF; for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l) { if (flag == flags[l].flag) { if (show) { foreground(flags[l].reverse ? bgcolor : fgcolor); background(flags[l].reverse ? fgcolor : bgcolor); } else { foreground(bgcolor); background(bgcolor); } if (flags[l].msg != NULL) { // flag is a string locate(flags[l].x, flags[l].y); set_font((unsigned char*)Terminal6x8); this->printf(flags[l].msg);} else { // flag is an icon Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon}; Bitmap_BW(pic, flags[l].x, flags[l].y); } } } // draw frames (Alarm and Channel) for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l) { if (flag == frames[l].flag) { uint16_t color; if (show) color = fgcolor/6; else color = bgcolor; hline(frames[l].x0+1, frames[l].x0+3, frames[l].y0, color); hline(frames[l].x1-3, frames[l].x1-1, frames[l].y0, color); hline(frames[l].x0+1, frames[l].x1-1, frames[l].y1, color); vline(frames[l].x0, frames[l].y0+1, frames[l].y1-1, color); vline(frames[l].x1, frames[l].y0+1, frames[l].y1-1, color); } } must_refresh = 1; } void Display::test_dsp() { const FRAME *z; printf("TEST DSP\r\n"); cls(); printf("TEST DSP #2\r\n"); show(0x00, "8g8g8g8g8g8g8", 13); // main dsp show(0x0C, "888", 3); // channel dsp show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags copy_to_lcd(); ThisThread::sleep_for(3ms); cls(); printf("TEST DSP #3\r\n"); for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++) { z = &zones[i]; fillrect(z->x0, z->y0, z->x1, z->y1, 4+i); locate(z->x0+1, z->y0+1); this->printf("%d", i); } /* for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++) { z = &zones[i]; printf("Zone %d [%x]: %d, %d, %d, %d\n", i, z->flag, z->x0, z->y0, z->x1, z->y1); must_refresh = z->flag; wait(1); } printf("Done\n"); wait(2); printf("Copy ALL\n"); copy_to_lcd(); */ ThisThread::sleep_for(2ms); cls(); printf("TEST DSP DONE\r\n"); }