Many improvements draft

Sun, 01 Nov 2020 22:21:19 +0100

author
David Douard <david.douard@sdf3.org>
date
Sun, 01 Nov 2020 22:21:19 +0100
changeset 44
b3c3d54d2c7c
parent 43
c850674a3101
child 45
2da50a3d4e9f

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

src/def_f446re.h file | annotate | diff | comparison | revisions
src/def_hp34970_fp.h file | annotate | diff | comparison | revisions
src/display.cpp file | annotate | diff | comparison | revisions
src/display.h file | annotate | diff | comparison | revisions
src/hp34comm.cpp file | annotate | diff | comparison | revisions
src/hp34comm.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
--- a/src/def_f446re.h	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/def_f446re.h	Sun Nov 01 22:21:19 2020 +0100
@@ -45,7 +45,7 @@
 #define DBGPIN PC_6
 
 #ifdef HAVE_PC
-BufferedSerial pc(USBTX, USBRX);
+BufferedSerial pc(USBTX, USBRX, 115200);
 #endif
 DigitalOut led(LED1);
 #define HAS_LED
--- a/src/def_hp34970_fp.h	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/def_hp34970_fp.h	Sun Nov 01 22:21:19 2020 +0100
@@ -33,11 +33,12 @@
 #define KP_C2 PC_0
 #define KP_C3 PB_4
 #define KP_C4 PB_0
-/*
+
 #if defined(HAVE_PC)
-#include <USBSerial.h>
-USBSerial pc;
+//#include <USBSerial.h>
+//USBSerial pc;
+BufferedSerial pc(PC_10_ALT0, PC_11_ALT0, 115200); // UART_4
+//BufferedSerial pc(PC_10, PC_11, 115200); // UART_4
 #endif
-*/
 
 #endif
--- a/src/display.cpp	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/display.cpp	Sun Nov 01 22:21:19 2020 +0100
@@ -23,26 +23,64 @@
 	set_font((unsigned char*)Terminal6x8);
 	locate(90, 40);
 	this->printf("David Douard");
-	locate(0, 52);
-	this->printf("Clock = %ld ", SystemCoreClock);
+	copy_to_lcd();
+}
 
-	RCC_OscInitTypeDef cfg;
-	HAL_RCC_GetOscConfig(&cfg);
-	if (cfg.HSEState == RCC_HSE_BYPASS)
-		this->printf("HSE:EXT ");
-	else if (cfg.HSEState == RCC_HSE_ON)
-		this->printf("HSE:XTAL ");
-	else
-		this->printf("HSE:OFF ");
-
-	if (cfg.HSIState == RCC_HSI_ON)
-		this->printf("HSI:ON ");
-	else
-		this->printf("HSI:OFF ");
-
+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)
 {
@@ -52,21 +90,24 @@
 	char *oldv;
 	// char *txt;
 	char *txtp;
-	static char txt[256];
+	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
 	{
-		//txt = (char *)malloc(strlen(intxt)+1);
-		strcpy(txt, intxt);
-		txtp = txt;
-
 		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);
@@ -76,45 +117,48 @@
 
 				locate(table[i].x0, table[i].y0);
 
-				if (table[i].fmt & 0x01)  // ASCII text
+				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],
-														bgcolor);
+									 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;
 							}
 						}
-						if (cmd == 0x00) // main area
-							must_refresh |= 0x01;
-						if (cmd == 0x0C) // channels area
-							must_refresh |= 0x04;
+						must_refresh = 1;
 					}
 				}
 				/*
-					if (table[i].fmt & 0x02 ) {
+					if (table[i].fmt & FMT_HEX ) {
 					// hex
 					for (uint8_t j=0;; j++) {
 					if (txt[j] == 0x00)
@@ -125,52 +169,42 @@
 					this->printf(" ");
 					}
 				*/
-				if (table[i].fmt & 0x08 )  // flag indicators
+				if (table[i].fmt & FMT_FLAGS )  // flag indicators
 				{
+					uint8_t nbyte;
+					uint8_t nbit;
 					// flags
-					for (uint8_t j=0; j<max(nchar, table[i].maxsize) ; j++)
+					for (uint8_t l=0; l<(sizeof(flags)/sizeof(flags[0])); ++l)
 					{
-						for (uint8_t k=0; k<8; k++)
-						{
-							if (1)
-							{ //(txt[j] & (1 << k) ) != (oldv[j] & (1 << k))) {
-								for (uint8_t l=0;
-										 l<(sizeof(flags)/sizeof(flags[0])); ++l)
-								{
-									if (flags[l].flag == ((j<<4) + k)) {
-										if (txtp[j] & (1 << k))
-										{
-											foreground(flags[l].reverse ? bgcolor : fgcolor);
-											background(flags[l].reverse ? fgcolor : bgcolor);
-										}
-										else
-										{
-											foreground(bgcolor);
-											background(bgcolor);
-										}
-										if (flags[l].msg != NULL)
-										{ // a string
-											locate(flags[l].x, flags[l].y);
-											this->printf(flags[l].msg);}
-										else
-										{ // an icon
-											Bitmap_s pic = {9, 10, 2, (char*) flags[l].icon};
-											Bitmap_BW(pic, flags[l].x, flags[l].y);
-										}
-										must_refresh = 1; //|= zones[m].flag;
-										break;
-									}
-								}
-							}
+						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)
+					for (uint8_t l=0; l<(sizeof(frames)/sizeof(frames[0])); ++l)
 					{
 						uint16_t color;
-						if (frames[l].flag & txt[0]) // frame flags are on the 1st byte only
+						if (intxt[0] & (1 << frames[l].flag)) // frame flags are on the 1st byte only
 							color = fgcolor/6;
 						else
 							color = bgcolor;
@@ -181,6 +215,7 @@
 						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++)
@@ -194,6 +229,61 @@
 }
 
 
+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;
--- a/src/display.h	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/display.h	Sun Nov 01 22:21:19 2020 +0100
@@ -8,6 +8,15 @@
 #include "SSD1322.h"
 #include "hp34comm.h"
 
+//typedef enum {
+#define FMT_ASCII  0x01
+#define FMT_HEX    0x02
+#define FMT_BITS   0x04
+#define FMT_FLAGS  0x08
+#define FMT_IGNORE 0x80
+	//} dsp_format_t;
+
+
 typedef struct _DSP
 {
 	uint8_t cmd;
@@ -22,11 +31,13 @@
 	char buffer[MAX_BUFF+1];
 } DSP;
 
+
+
 static DSP table[] =
-{
-		{ 0x00, 0xF, 0x0,  0,  0, 0x01, MAX_BUFF, 245, Mono19x27}, // main display
-		{ 0x0C, 0xF, 0x0,196, 34, 0x01, 3,        45,  Mono15x22}, // channels display
-		{ 0x0A, 0xF, 0x0,  0, 57, 0x08, 4,        0, Terminal6x8}, // flags + bits
+{       // cmd,  fg, bg,  x0, y0,       fmt,  maxsize, width, font
+		{ 0x00, 0xF, 0x0,  0,  0, FMT_ASCII, MAX_BUFF, 245, Mono19x27}, // main display
+		{ 0x0C, 0xF, 0x0,196, 34, FMT_ASCII, 3,        45,  Mono15x22}, // channels display
+		{ 0x0A, 0xF, 0x0,  0, 57, FMT_FLAGS, 4,        0, Terminal6x8}, // flags + bits
 };
 
 // 9x10
@@ -79,47 +90,47 @@
 
 static const FLAG flags[] =
 {
-    // flag, zone, x0, y0, reverse, msg, icon
+    // flag, x0, y0, reverse, msg, icon
     // right-side icons area
-		{ 0x00, 246, 0,  false, NULL, icon_alarm}, // F1.0
-    { 0x01, 246, 11, false, NULL, icon_curve}, // F1.1
-
-    // F1.2 == Channel frame
-    { 0x03, 197, 27, false, "Channel"},  // F1.3
-    // F1.7 == Alarm frame
+	// flag is the bit index in the 4 bytes viewed as a 32bits value
+    { 0x00, 246, 0,  false, NULL, icon_alarm}, // F1.0  01 00 00 00
+    { 0x01, 246, 11, false, NULL, icon_curve}, // F1.1  02 00 00 00
+                                               // F1.2  04 00 00 00 - Channel frame
+    { 0x03, 197, 27, false, "CHANNEL"},        // F1.3  08 00 00 00
+                                               // F1.7  80 00 00 00 - Alarm frame
+    { 0x1c, 0,  28+8,  false, "MON"},          // F4.4  00 00 00 10
+    { 0x1b, 0,  28+16, false, "VIEW"},         // F4.3  00 00 00 08
+    { 0x1d, 0,  28,    true, "SCAN"},          // F4.5  00 00 00 20
+    { 0x1e, 0,  28+25, true, "CONFIG"},        // F4.6  00 00 00 40
 
-    { 0x34, 0,  28+8,  false, "MON"},    // F4.4
-    { 0x33, 0,  28+16, false, "VIEW"},   // F4.3
-    { 0x35, 0,  28,    true, "SCAN"},   // F4.5
-    { 0x36, 0,  28+25, true, "CONFIG"},    // F4.6
+    { 0x1a, 40, 52,    false, "*"},            // F4.2  00 00 00 04
+    { 0x19, 50, 52,    false, "ADRS"},         // F4.1  00 00 00 02
+    { 0x18, 80, 52,    false, "RMT"},          // F4.0  00 00 00 01
+    { 0x17, 104, 52,   true, "ERROR"},         // F3.7  00 00 80 00
 
-    { 0x32, 40, 52,    false, "*"},      // F4.2
-    { 0x31, 50, 52,    false, "ADRS"},   // F4.1
-    { 0x30, 80, 52,    false, "RMT"},    // F4.0
-    { 0x27, 104, 52,   true, "ERROR"},    // F3.7
+    { 0x16, 140, 52,   false, "EXT"},          // F3.6  00 00 40 00
+    { 0x15, 164, 52,   false, "ONCE"},         // F3.5  00 00 20 00
 
-    { 0x26, 140, 52,   false, "EXT"},    // F3.6
-    { 0x25, 164, 52,   false, "ONCE"},   // F3.5
-
-    { 0x23, 104, 28+16, false, "MEM"},    // F3.3
+    { 0x13, 104, 28+16, false, "MEM"},         // F3.3  00 00 08 00
 
 
     // col 5
-    { 0x14, 244, 22,  false, "4W"},     // F2.4
-    { 0x15, 244, 30,  false, "OC"},     // F2.5
-    { 0x22, 129, 28+16, false, "LAST"},   // F3.2
-    { 0x21, 129, 28+16, false, "MIN"},    // F3.1
-    { 0x20, 129, 28+16, false, "MAX"},    // F3.0
-    { 0x17, 129, 28+16, false, "AVG"},    // F2.7
+    { 0x0c, 244, 22,  false, "4W"},            // F2.4  00 10 00 00
+    { 0x0d, 244, 30,  false, "OC"},            // F2.5  00 20 00 00
+    { 0x12, 129, 28+16, false, "LAST"},        // F3.2  00 00 04 00
+    { 0x11, 129, 28+16, false, "MIN"},         // F3.1  00 00 02 00
+    { 0x10, 129, 28+16, false, "MAX"},         // F3.0  00 00 01 00
+    { 0x0f, 129, 28+16, false, "AVG"},         // F2.7  00 80 00 00
 
-    { 0x05, 154+0,  17+10, false, "Alarm"},  // F1.5
-    { 0x06, 154+0,  17+20, false, "H"},      // F1.6
-    { 0x13, 154+6,  17+20, false, "1"},      // F2.3
-    { 0x10, 154+12, 17+20, false, "2"},      // F2.0
-    { 0x12, 154+18, 17+20, false, "3"},      // F2.2
-    { 0x11, 154+24, 17+20, false, "4"},      // F2.1
-    { 0x04, 154+30, 17+20, false, "L"},      // F1.4
+    { 0x05, 154+0,  17+10, false, "Alarm"},    // F1.5  20 00 00 00
+    { 0x06, 154+0,  17+20, false, "H"},        // F1.6  40 00 00 00
+    { 0x0b, 154+6,  17+20, false, "1"},        // F2.3  00 08 00 00
+    { 0x08, 154+12, 17+20, false, "2"},        // F2.0  00 01 00 00
+    { 0x0a, 154+18, 17+20, false, "3"},        // F2.2  00 04 00 00
+    { 0x09, 154+24, 17+20, false, "4"},        // F2.1  00 02 00 00
+    { 0x04, 154+30, 17+20, false, "L"},        // F1.4  00 10 00 00
 
+	{ 0x80, 224, 54, true, "SHIFT"},   // not an actual command, managed by the front panel
 };
 
 static const FRAME zones[] =
@@ -154,7 +165,15 @@
 
 	void test_dsp();
 	void show(uint8_t, const char*, uint8_t);
+	void dimm_char(uint8_t);
 	void show_splashscreen();
+	void show_byescreen();
+	void set_flag(uint8_t flag, bool show);
+	void show_flag(uint8_t flag) {set_flag(flag, true);};
+	void hide_flag(uint8_t flag) {set_flag(flag, false);};
+	void shift_on() {set_flag(0x80, true);};
+	void shift_off() {set_flag(0x80, false);};
+
 
 private:
 	uint8_t must_refresh;
--- a/src/hp34comm.cpp	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/hp34comm.cpp	Sun Nov 01 22:21:19 2020 +0100
@@ -5,31 +5,22 @@
 
 /***** HP 34970A communication class ***/
 
-#ifdef DEBUG2
-
-DigitalOut inrx(D9);
-
-#endif
-
-DigitalOut lled(LED3);
-
 #define RXTIMEOUT 50ms
 #define STARTUPRETRY 0.5
 
 uint8_t startup_seq[] = {
   0x33,
-  0x02,
+  0x02,  // 0x02?
   0x00,
-  0x00,  // to be replaced by the actual keycode, if any
+  0x00,
 };
 
 HPSerial::statemethod HPSerial::state_table[NUM_STATES] = {
-  &HPSerial::do_state_initial,
-  &HPSerial::do_state_command,
-  &HPSerial::do_state_payload_size,
-  &HPSerial::do_state_payload,
-  &HPSerial::do_state_sending,
-  &HPSerial::do_state_eot,
+  &HPSerial::do_state_initial,      // STATE_IDLE
+  &HPSerial::do_state_command,      // STATE_COMMAND
+  &HPSerial::do_state_payload_size, // STATE_PAYLOAD_SIZE
+  &HPSerial::do_state_payload,      // STATE_PAYLOAD
+  &HPSerial::do_state_sending,      // STATE_SENDING
 };
 
 
@@ -39,17 +30,21 @@
   cur_gstate(GSTATE_IDLE)
 {
   serial.baud(187500);
+  serial.format(8, BufferedSerial::Even, 1);
   cur_state = STATE_IDLE;
-  serial.attach(callback(this, &HPSerial::rxIrq), SerialBase::RxIrq);
+  serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq);
 }
 
 void HPSerial::startup(uint8_t keycode) {
+  cur_gstate = GSTATE_STARTING;
+
   if (keycode != 0xFF) {
-      startup_sed[2] = 0xFF;
-      startup_sed[3] = keycode;
+	  printf("Set startup keycode to %X\n", keycode);
+      startup_seq[2] = 0xFF;
+      startup_seq[3] = keycode;
   }
-
-  cur_gstate = GSTATE_STARTING;
+  else
+      startup_seq[2] = 0x00;
   set_timer(10ms); // launch the startup in 10ms
 }
 
@@ -65,18 +60,28 @@
       tr_data.size = 3; // sizeof(startup_seq);
   for(uint8_t i=0; i<tr_data.size; i++)
     tr_data.payload[i] = startup_seq[i];
-
   cur_state = do_state_sending();
 }
 
 void HPSerial::sendkey(uint8_t keycode)
 {
-  tr_data.size = 2;
-  tr_data.cmd = 0xFF;
-  tr_data.pos = 0;
-  tr_data.payload[0] = 0x66;
-  tr_data.payload[1] = keycode;
-  cur_state = do_state_sending();
+  if (!sendbuf.full())
+    sendbuf.push(keycode);
+}
+
+void HPSerial::send_key_when_idle() {
+  if (!sendbuf.empty() && cur_gstate == GSTATE_IDLE)
+  {
+    uint8_t keycode;
+	cur_gstate = GSTATE_TX;
+	sendbuf.pop(keycode);
+	tr_data.size = 2;
+	tr_data.cmd = 0xFF;
+	tr_data.pos = 0;
+	tr_data.payload[0] = 0x66;
+	tr_data.payload[1] = keycode;
+	cur_state = do_state_sending();
+  }
 }
 
 bool HPSerial::cmd_available(void)
@@ -112,8 +117,8 @@
 }
 
 void HPSerial::send_ack(uint8_t c) {
-	serial.write(&c, 1);
-  set_timer(RXTIMEOUT); // if nothing else happen in the next ms, reset
+  serial.write(&c, 1);
+  set_timer(RXTIMEOUT); // if nothing else happen in the next RXTIMEOUT ms, reset
 }
 
 HPSerial::state_t HPSerial::do_state_initial(uint8_t c)
@@ -122,7 +127,7 @@
   // knwon handcheck values are 0x66 and 0x33
   set_timer(RXTIMEOUT); // reset the watchdog
   switch (c) {
-  case 0x33:
+  case 0x33:  // XXX? when are we expecting a 0x33 here?
     send_ack(0xCC);
     return HPSerial::STATE_PAYLOAD_SIZE;
     break;
@@ -173,9 +178,9 @@
   send_ack(0x00);
   if (tr_data.pos >= tr_data.size) {
     pushCmd(tr_data.cmd, tr_data.size, tr_data.payload);
-    return HPSerial::STATE_IDLE;
+    return STATE_IDLE;
   }
-  return HPSerial::STATE_PAYLOAD;
+  return STATE_PAYLOAD;
 }
 
 HPSerial::state_t HPSerial::do_state_sending(uint8_t c)
@@ -184,48 +189,41 @@
   if (c == 0xFF)
   { // resend current char
     tr_data.pos--;
-	tr_data.payload[tr_data.pos] += 1;
   }
   // TODO: check ACK values (c is the received ack)
   if (tr_data.pos >= tr_data.size)
   {
-    return do_state_eot();
+	  c = 0x55;
+	  serial.write(&c, 1); // EoT
+	  cur_gstate = GSTATE_IDLE;
+	  set_timer(); // We are IDLE, detach the timeouter
+	  return STATE_IDLE;
   }
-  serial.write(&tr_data.payload[tr_data.pos++], 1);
-  set_timer(RXTIMEOUT);
-  return HPSerial::STATE_SENDING;
-}
-
-HPSerial::state_t HPSerial::do_state_eot(uint8_t c)
-{
-  serial.write(&c, 1); // EoT
-  cur_gstate = GSTATE_IDLE;
-  set_timer(); // We are IDLE, detach the timeouter
-  return STATE_IDLE;
+  else
+  {
+	  serial.write(&tr_data.payload[tr_data.pos++], 1);
+	  set_timer(RXTIMEOUT);
+	  return STATE_SENDING;
+  }
 }
 
 HPSerial::state_t HPSerial::run_state(HPSerial::state_t cur_state,
-				      uint8_t c)
+									  uint8_t c)
 {
   return (this->*(HPSerial::state_table[cur_state]))(c);
 };
 
-void HPSerial::rxIrq(void) {
+void HPSerial::rx_irq(void) {
   uint8_t val;
   if(serial.readable())
   { // no reason why we would end here without
 	// this condition, but hey
-#ifdef DEBUG2
-    inrx=1;
-#endif
-    //lled = 1;
-    //val = serial.getc();
+	if (cur_gstate == GSTATE_IDLE)
+	  // occurs when the CPU starts a new transmission
+	  // at this point, cur_state should be STATE_IDLE also (TODO add a check?)
+	  cur_gstate = GSTATE_RX;
 	serial.read(&val, 1);
     cur_state = run_state(cur_state, val);
-    //lled = 0;
-#ifdef DEBUG2
-    inrx=0;
-#endif
   }
 }
 
@@ -234,7 +232,7 @@
   set_timer(); // detach the timeouter
   if (cur_gstate == GSTATE_STARTING)
     _startup();
-  else // reset
+  else // CPU took too long to reply, reset
     {
     cur_gstate = GSTATE_IDLE;
     cur_state = STATE_IDLE;
--- a/src/hp34comm.h	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/hp34comm.h	Sun Nov 01 22:21:19 2020 +0100
@@ -32,22 +32,24 @@
 
   void startup(uint8_t keycode=0xFF);
   void sendkey(uint8_t keycode);
+  void send_key_when_idle();
 
 private:
   void pushCmd(uint8_t cmd, uint8_t size, char *payload);
-  void rxIrq(void);
+  void rx_irq(void);
   void timeout(void);
   void set_timer(Kernel::Clock::duration_u32 v=0ms) {
     timeouter.detach();
     if (v > 0ms)
       timeouter.attach(callback(this, &HPSerial::timeout), v);
-  }
+  };
 
  private:
   UnbufferedSerial serial;
   uint8_t buf[BUF_SIZE];
   uint8_t head;
   CircularBuffer<CMD, 32> cmdbuf;
+  CircularBuffer<uint8_t, 32> sendbuf;
   unsigned long ncmd;
   unsigned int errs[MAX_ERRS];
   Ticker timeouter;
@@ -84,7 +86,6 @@
     STATE_PAYLOAD_SIZE,
     STATE_PAYLOAD,
     STATE_SENDING,
-    STATE_EOT,
     NUM_STATES} state_t;
   state_t state() {return cur_state;};
 
@@ -102,7 +103,6 @@
   state_t do_state_payload_size(uint8_t c);
   state_t do_state_payload(uint8_t c);
   state_t do_state_sending(uint8_t c=0x00);
-  state_t do_state_eot(uint8_t c=0x55);
 
   void send_ack(uint8_t c);
 
--- a/src/main.cpp	Sun Nov 01 22:16:33 2020 +0100
+++ b/src/main.cpp	Sun Nov 01 22:21:19 2020 +0100
@@ -23,15 +23,18 @@
 Display *dsp;
 volatile bool splashscreen;
 HPSerial *hp;
-Thread tdsp;
-Ticker blinker;
+Thread tdsp(osPriorityNormal, OS_STACK_SIZE, nullptr, "DSP");
+Ticker dsp_refresh;
 Timeout rst_delay;
 Timeout splashscreen_timer;
+Timeout byescreen_timer;
 InterruptIn rst(HP_RST);
 
 QEI qenc(KP_ENC1, KP_ENC2, NC, 16);
 volatile uint8_t knob;
 bool shift;  // true when kp is shifted, cleared by command 0x01 from Unit
+bool must_reset;
+bool must_shutdown;
 
 typedef enum {
     KEY_NONE=0,
@@ -45,7 +48,6 @@
   key_event_t keyevent;
 } keycode_t;
 
-//volatile keycode_t cur_keycode;
 
 #define KEY_BUF_SIZE 10
 CircularBuffer<keycode_t, KEY_BUF_SIZE> key_buf;
@@ -94,10 +96,14 @@
     {0x0A, 0x09, 0x08, 0x02, 0xFF}
 };
 
+#define KC_SHIFT 0x0C
+
 void kp_cb(uint8_t row, uint8_t col);
 void kr_cb(uint8_t row, uint8_t col);
 
 Keypad *kpad;
+keycode_t last_key = {0, 0, KEY_NONE};
+
 uint8_t curchar;
 //uint8_t curcmd;
 uint8_t nchars;
@@ -139,21 +145,17 @@
 void qei_cb(int dir);
 void end_splashscreen(void);
 
-/*
-  #if defined(HAVE_PC)
-  FileHandle *mbed::mbed_override_console(int fd)
-  {
-  return static_cast<FileHandle*> (&pc);
-  }
-  #endif
-*/
+
+#if defined(HAVE_PC)
+FileHandle *mbed::mbed_override_console(int fd)
+{
+	return static_cast<FileHandle*> (&pc);
+}
+#endif
+
 
 void setup() {
 #if defined(HAVE_PC)
-#if   defined(TARGET_NUCLEO_F446RE)
-  pc.set_baud(115200);
-#endif
-
 /*
   #if  defined(TARGET_HP34970_FP_F303RD)
   pc.init();
@@ -163,8 +165,7 @@
 #endif
 
   printf("\n\nSETUP\n");
-  printf("  System Core Clock = %.3f MHZ\r\n",
-         (float)SystemCoreClock/1000000);
+  printf("  System Core Clock = %ld MHZ\r\n", SystemCoreClock/1000000);
 
   /*
     #if defined(HAS_LED)
@@ -199,9 +200,10 @@
   qenc.attach(&qei_cb);
 
   printf("  setup Keypad\r\n");
-  //cur_keycode.keyevent = KEY_NONE;
 
   shift = false;
+  must_reset = false;
+  must_shutdown = false;
   kpad = new Keypad(KP_NROWS, kp_rows, KP_NCOLS, kp_columns);
   printf("  attach Keypad callbacks\r\n");
   kpad->attach(&kp_cb, &kr_cb);
@@ -230,15 +232,10 @@
   dsp->show_splashscreen();
 
   printf("Starting LCD thread\r\n");
+  // does not compile...
+  // dsp_refresh.attach(callback(dsp, &Display::copy_to_lcd), 50ms);
   tdsp.start(&refresh_display);
 
-  /*
-    dsp->clrbuff();
-    show(0x00, "HH:MM:\tSS\t:mmmm", 15); // main dsp
-    show(0x0C, "888", 3); // channel dsp
-    show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags
-  */
-
   printf("Attaching timers\r\n");
   splashscreen = true;
   splashscreen_timer.attach(callback(&end_splashscreen), 2ms);
@@ -254,85 +251,86 @@
   splashscreen = false;
 }
 
+void reset_irq_tmr(void)
+{
+	must_reset = true;
+}
+
 void reset_irq(void)
 {
-  rst_delay.attach(callback(&reset), 1ms);
+	rst_delay.attach(callback(&reset_irq_tmr), 50ms);
 }
 
 void reset(void)
 {
+  // this should be called as a result of the HP_RST pin going LO
+  printf("Reset connection to the main unit\n");
   if (DigitalIn(HP_RST).read() == 0) {
     if (hp == NULL) {
       printf("setup HP communication handler\r\n");
       hp = new HPSerial(HP_TX, HP_RX);
     }
+	else {
+		printf("Connection already initialized\n");
+	}
 
     printf("!! RST !! (gstate=%d, state=%d)\r\n",
            hp->gstate(), hp->state());
     //printf("Value is ... %X\n", hp->search());
-    hp->startup();
+	dsp->power_on();
+	dsp->cls();
+    printf("Initiate startup sequence\n");
+	if (last_key.keyevent == KEY_PRESSED)
+		hp->startup(kp_mapping[last_key.row][last_key.col]);
+	else
+		hp->startup();
+  }
+  else
+  {
+	  printf("HP_RST is not LOW, skipping\n");
   }
 }
 
 void refresh_display(void) {
-  //uint8_t mask=1;
-
-  while(1) {
-    pulse(0, true);
-    if (splashscreen == false) {
-      //Thread::wait(20); // give a bit of time for some more cmds
-      dsp->copy_to_lcd();
-    }
+	while(1) { //!must_shutdown) {
+		dsp->copy_to_lcd();
+		ThisThread::sleep_for(50ms);
+	}
+}
 
-    /*
-      if (must_refresh & mask) {
-      for(uint8_t i=0; i<sizeof(zones)/sizeof(zones[0]); i++)
-      if (zones[i].flag == mask) {
-      dsp->copy_to_lcd(zones[i].x0/4, (zones[i].x1+3)/4,
-      zones[i].y0,   zones[i].y1);
-      must_refresh &= ~mask;
-      break;
-      }
-      }
-      mask = mask << 1;
-      if (mask == 0) {
-      mask = 1;
-      }
-    */
-    pulse(0, false);
-
-    ThisThread::sleep_for(30ms);
-  }
+void shutdown(void)
+{
+  must_shutdown = true;
 }
 
 void mainloop()
 { // run over and over
   keycode_t key = {0, 0, KEY_NONE};
-
+  uint8_t keycode;  // actual sent value to the CPU
+  HPSerial::CMD cmd;
+  unsigned int nkeys = 0;
   unsigned int err[8];
   for (uint8_t i=0; i<8; i++)
     err[i] = 0;
-  int p, pp;  // rot encoder pulse counters
-  p = 0;
-  pp = 0;
 
   while(1) {
-    p = qenc.getPulses();
-    if (p != pp)
-    {
-      dsp->locate(0, 0);
-      dsp->printf("Pulses = %d  ", p);
-      dsp->copy_to_lcd();
-      pp = p;
-    }
+	if (must_reset) {
+	  must_reset = false;
+	  reset();
+	}
+	if (must_shutdown) {
+		//tdsp.join();
+		//dsp_refresh.detach();
+		must_shutdown = false;
+		dsp->power_off();
+	}
 
     if (knob != 0)
     {
       if (hp != NULL)
       {
-        printf("Sending keycode %X\r\n", knob);
+        printf("KEY[%d] %s%X\n", nkeys++, knob<0x0F ? "0" : "", knob);
         hp->sendkey(knob);
-        printf("   DONE\r\n");
       }
       else
       {
@@ -343,19 +341,28 @@
       knob = 0;
     }
 
-    if (!key_buf.empty()) //cur_keycode.keyevent != KEY_NONE)
+    if (!key_buf.empty())
     {
       key_buf.pop(key);
-      printf("Keycode %dx%d: %s\r\n",
-             key.row, key.col, key.keyevent==KEY_PRESSED?"pressed":"released");
+	  keycode = kp_mapping[key.row][key.col];
+
+	  if ((keycode == KC_SHIFT) && (key.keyevent == KEY_PRESSED))
+	  {
+		  shift = true;
+		  dsp->shift_on();
+	  }
+
       if (hp != NULL) {
-        uint8_t keycode = kp_mapping[key.row][key.col];
+        if ((shift) && (keycode != KC_SHIFT))
+		{
+          keycode |= 0x20;  // bit 5: key shifted
+		  shift = false;
+		  dsp->shift_off();
+		}
         if (key.keyevent == KEY_RELEASED)
           keycode |= 0x40;  // bit 6: key relased
-        if (shift)
-          keycode |= 0x20;  // bit 5: key shifted
-
-        hp->sendkey(kp_mapping[key.row][key.col]);
+        printf("KEY[%d] %s%X\n", nkeys++, keycode<0x0F ? "0" : "", keycode);
+        hp->sendkey(keycode);
       }
       else
       {
@@ -367,13 +374,14 @@
               key.keyevent==KEY_PRESSED ? "PRE" : "REL");
         dsp->copy_to_lcd();
       }
-      // cur_keycode.keyevent = KEY_NONE;
     }
 
+	// at each loop iteration, send buffered keycodes, if any
+	if (hp != NULL)
+	  hp->send_key_when_idle();
 
     if ((hp != NULL) && (hp->cmd_available()))
     {
-      HPSerial::CMD cmd;
       if (hp->pop(cmd))
       {
 #if defined(HAS_LED)
@@ -381,7 +389,7 @@
 #endif
         for (uint8_t i=0; i<7; i++)
           if (hp->nerrors(i) > err[i]) {
-            printf("ERR: %d/%d/%d/%d/%d/%d/%d\r\n",
+            printf("ERR: %X/%X/%X/%X/%X/%X/%X\n",
                    hp->nerrors(0),
                    hp->nerrors(1),
                    hp->nerrors(2),
@@ -395,17 +403,17 @@
         for (uint8_t i=0; i<7; i++)
           err[i] = hp->nerrors(i);
 
-        printf("CMD[%d] %02X", (int)cmd.id, cmd.cmd);
+        printf("CMD[%d] %s%X", (int)cmd.id, cmd.cmd<0x10 ? "0" : "", cmd.cmd);
 
         // 0x00: main display
         // 0x0C: channel display
         if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C))
-          printf(": '%s'\r\n", cmd.value);
+          printf(": '%s'\n", cmd.value);
         else {
-          printf(":");
+          printf(": ");
           for (uint8_t i=0; i<cmd.size; i++)
-            printf("%02x ", cmd.value[i]);
-          printf("\r\n");
+			  printf("%s%X ", cmd.value[i] < 0x10 ? "0" : "", cmd.value[i]);
+          printf("\n");
         }
 
         if (cmd.cmd == 0x01) {
@@ -413,11 +421,13 @@
           if (cmd.value[0] == 0x0E) {
             // clear the Shift flag
             shift = false;
+			dsp->shift_off();
           }
         } else if (cmd.cmd == 0x86) {
-          // shutdown
-          // TODO
-        } else {
+			// shutdown
+			dsp->show_byescreen();
+			byescreen_timer.attach(callback(&shutdown), 2s);
+         } else {
           // display related commands
           dsp->show(cmd.cmd, cmd.value, cmd.size);
         }
@@ -431,6 +441,7 @@
   }
 }
 
+
 void qei_cb(int dir)
 {
   if(dir == 1) // turn right
@@ -441,22 +452,20 @@
 
 void kp_cb(uint8_t row, uint8_t col)
 {
-  keycode_t key;
-  key.row = row;
-  key.col = col;
-  key.keyevent = KEY_PRESSED;
+  last_key.row = row;
+  last_key.col = col;
+  last_key.keyevent = KEY_PRESSED;
   if(!key_buf.full())
-    key_buf.push(key);
+    key_buf.push(last_key);
 }
 
 void kr_cb(uint8_t row, uint8_t col)
 {
-  keycode_t key;
-  key.row = row;
-  key.col = col;
-  key.keyevent = KEY_RELEASED;
+  last_key.row = row;
+  last_key.col = col;
+  last_key.keyevent = KEY_RELEASED;
   if(!key_buf.full())
-    key_buf.push(key);
+    key_buf.push(last_key);
 }
 
 int main()

mercurial