Make sure to send pending keys

even if the FP is flood by the CPU: hijack the started transmission
(just after receiving a SoT (0x66) datagram).
2 files changed, 42 insertions(+), 27 deletions(-)

M src/hp34comm.cpp
M src/hp34comm.h
M src/hp34comm.cpp +40 -26
@@ 64,34 64,40 @@ bool HPSerial::wait_for(uint8_t value)
 
 
 void HPSerial::send_pending_key() {
-  uint8_t c;
-
+  // body of the send_trhead: dedicated to sending pending keys
+  // Note that a key can also be sent after receiving a SoT packet
   while(true)
   {
 	  if (!sendbuf.empty())
+		do_send_key();
+	  else // prevent from flooding the main unit
+	    ThisThread::sleep_for(1ms);
+  }
+}
+
+void HPSerial::do_send_key() {
+  uint8_t c;
+  if (!sendbuf.empty())
+  {
+	  if (cur_gstate == GSTATE_IDLE)
 	  {
-		  if (cur_gstate == GSTATE_IDLE)
-		  {
-			  serial.attach(0, SerialBase::RxIrq);
-			  cur_gstate = GSTATE_TX;
-
-			  c = 0x66;
-			  serial.write(&c, 1);
-			  if (!wait_for(0x99)) {}
-			  // break; // XXX what to do?
+		  serial.attach(0, SerialBase::RxIrq);
+		  cur_gstate = GSTATE_TX;
 
-			  sendbuf.pop(c);
-			  serial.write(&c, 1);
-			  if (!wait_for(0x00)) {}
+		  c = 0x66;
+		  serial.write(&c, 1);
+		  if (!wait_for(0x99)) {}
+		  // break; // XXX what to do?
 
-			  c = 0x55;
-			  serial.write(&c, 1);
-			  cur_gstate = GSTATE_IDLE;
-			  serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq);
-		  }
+		  sendbuf.pop(c);
+		  serial.write(&c, 1);
+		  if (!wait_for(0x00)) {}
+
+		  c = 0x55;
+		  serial.write(&c, 1);
+		  cur_gstate = GSTATE_IDLE;
+		  serial.attach(callback(this, &HPSerial::rx_irq), SerialBase::RxIrq);
 	  }
-	  //else // prevent from flooding the main unit
-	  ThisThread::sleep_for(1ms);
   }
 }
 

          
@@ 187,7 193,7 @@ unsigned int HPSerial::nerrors(uint8_t e
 }
 
 
-void HPSerial::pushCmd(uint8_t cmd, uint8_t size, char *payload) {
+void HPSerial::push_cmd(uint8_t cmd, uint8_t size, char *payload) {
   CMD val;
   uint8_t i;
   val.id = ncmd++;

          
@@ 220,8 226,16 @@ HPSerial::state_t HPSerial::do_state_ini
     return HPSerial::STATE_IDLE;
     break;
   case 0x66:
-    send_ack(0x99);
-    return HPSerial::STATE_COMMAND;
+	  if (!sendbuf.empty()) {
+		  // hijack the transmission to send a keycode
+		  do_send_key();
+		  return HPSerial::STATE_IDLE;
+	  }
+	  else
+	  {
+		  send_ack(0x99);
+		  return HPSerial::STATE_COMMAND;
+	  }
     break;
   case 0xFF:
     return HPSerial::STATE_IDLE;

          
@@ 244,7 258,7 @@ HPSerial::state_t HPSerial::do_state_com
   send_ack(0x00);
 
   if (c == 0x86) { // shutdown
-    pushCmd(tr_data.cmd, tr_data.size, tr_data.payload);
+    push_cmd(tr_data.cmd, tr_data.size, tr_data.payload);
     return HPSerial::STATE_IDLE;
   }
   return STATE_PAYLOAD_SIZE;

          
@@ 265,7 279,7 @@ HPSerial::state_t HPSerial::do_state_pay
   tr_data.payload[tr_data.pos++] = c;
   send_ack(0x00);
   if (tr_data.pos >= tr_data.size) {
-    pushCmd(tr_data.cmd, tr_data.size, tr_data.payload);
+    push_cmd(tr_data.cmd, tr_data.size, tr_data.payload);
     return STATE_IDLE;
   }
   return STATE_PAYLOAD;

          
M src/hp34comm.h +2 -1
@@ 36,7 36,7 @@ public:
   void send_startup_seq(uint8_t keycode);
 
 private:
-  void pushCmd(uint8_t cmd, uint8_t size, char *payload);
+  void push_cmd(uint8_t cmd, uint8_t size, char *payload);
   void rx_irq(void);
   void timeout(void);
   void set_timer(Kernel::Clock::duration_u32 v=0ms) {

          
@@ 57,6 57,7 @@ private:
 
   Thread send_thread;
   void send_pending_key();
+  void do_send_key();
   bool wait_for(uint8_t);