Stuff... draft

Wed, 18 Jan 2017 23:19:13 +0100

author
David Douard <david.douard@logilab.fr>
date
Wed, 18 Jan 2017 23:19:13 +0100
changeset 19
a52d60613cf7
parent 18
4fd621551d55
child 20
b4658776abb6

Stuff...

platformio.ini 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/platformio.ini	Sat Oct 29 23:44:31 2016 +0200
+++ b/platformio.ini	Wed Jan 18 23:19:13 2017 +0100
@@ -22,21 +22,16 @@
 framework = mbed
 board = nucleo_f446re
 upload_port = /media/sdb
+build_flags = -DHAVE_PC
 lib_compat_mode = 0
 
-[env:f303k8]
-platform = ststm32
-framework = mbed
-board = nucleo_f303k8
-upload_port = /media/sdb
-
 [env:l432kc]
 platform = ststm32
 framework = mbed
 board = nucleo_l432kc
 upload_port = /media/sdb
 lib_compat_mode = 0
-build_flags = -DDEBUG -DDEBUG2 -DHAVE_PC
+build_flags = -DHAVE_PC
 
 # [env:nucleo_f031k6]
 # platform = ststm31
--- a/src/hp34comm.cpp	Sat Oct 29 23:44:31 2016 +0200
+++ b/src/hp34comm.cpp	Wed Jan 18 23:19:13 2017 +0100
@@ -7,38 +7,111 @@
 #ifdef DEBUG2
 
 DigitalOut inrx(D9);
-DigitalOut intx(D5);
-DigitalOut ack(D6);
-DigitalOut staterx(A0);
-DigitalOut statetx(D10);
 
 #endif
 
 DigitalOut lled(LED1);
 
+#define RXTIMEOUT 0.05
+#define STARTUPRETRY 0.5
+const uint8_t startup_seq[] = {
+  0x33,
+  0x01,
+  0x01,
+  0x40,
+  //  0x02,
+};
 
+const uint8_t startup_seq2[] = {
+  0x33,
+  0x02,
+  0x00,
+  0x00,
+  //  0x02,
+};
+
+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::HPSerial(PinName tx, PinName rx):
-  serial(tx, rx)
+  serial(tx, rx),
+  cur_gstate(GSTATE_IDLE),
+  ncmd(0)
 {
-  cur_state = do_state_initial(&rx_data, 0x00);
-  serial.baud(187500);
-  serial.attach(this, &HPSerial::rxIrq, Serial::RxIrq);
+  serial.baud(187500); 
+  cur_state = STATE_IDLE;
+  serial.attach(callback(this, &HPSerial::rxIrq), Serial::RxIrq);
+}
+
+void HPSerial::startup(void) {
+  if (cur_gstate != GSTATE_STARTING) {
+    //_startup();
+    cur_gstate = GSTATE_STARTING;
+  }
+  set_timer(0.002); // launch the startup in 10ms
+}
+
+void HPSerial::_startup(void)
+{
+  cur_gstate = GSTATE_STARTING;
+  tr_data.size = sizeof(startup_seq);
+  tr_data.cmd = 0xFF;
+  tr_data.pos = 0;
+  for(uint8_t i=0; i<tr_data.size; i++)
+    tr_data.payload[i] = startup_seq[i];
+  cur_state = do_state_sending();
 }
 
-bool HPSerial::cmd_available(void) {
+void HPSerial::_startup2(void)
+{
+  cur_gstate = GSTATE_STARTING2;
+  tr_data.size = sizeof(startup_seq2);
+  tr_data.cmd = 0xFF;
+  tr_data.pos = 0;
+  for(uint8_t i=0; i<tr_data.size; i++)
+    tr_data.payload[i] = startup_seq2[i];
+  cur_state = do_state_sending();
+}
+
+void HPSerial::send(const uint8_t *buf, uint8_t size)
+{
+  //  tx_data->
+  //send(startup, sizeof(startup)/sizeof(startup[0]));
+}
+
+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();
+}
+
+bool HPSerial::cmd_available(void)
+{
   return !cmdbuf.empty();
 }
 
-bool HPSerial::pop(CMD& cmd) {
+bool HPSerial::pop(CMD& cmd)
+{
   return cmdbuf.pop(cmd);
 }
 
-bool HPSerial::cmd_buf_full(void) {
+bool HPSerial::cmd_buf_full(void)
+{
   return cmdbuf.full();
 }
 
-unsigned int HPSerial::nerrors(uint8_t errorno) {
+unsigned int HPSerial::nerrors(uint8_t errorno)
+{ 
   return errs[errorno];
 }
 
@@ -55,79 +128,108 @@
 }
 
 void HPSerial::send_ack(uint8_t c) {
-  timeouter.attach(this, &HPSerial::timeout, 0.001); // if nothing else happen in the next ms, reset
   serial.putc(c);
+  set_timer(RXTIMEOUT); // if nothing else happen in the next ms, reset
 }
 
-HPSerial::state_t HPSerial::do_state_initial(HPSerial::instance_data_t *data,
-				   uint8_t c)
-{
-  // go back to initial state
-  data->cmd = 0xFF;
-  data->size = 0;
-  data->received = 0;
-  timeouter.detach();
-  return HPSerial::STATE_IDLE;
-}
-
-HPSerial::state_t HPSerial::do_state_handcheck(HPSerial::instance_data_t *data,
-				     uint8_t c)
+HPSerial::state_t HPSerial::do_state_initial(uint8_t c)
 {
   // we are idle, incoming char is a handcheck
   // knwon handcheck values are 0x66 and 0x33
+  set_timer(RXTIMEOUT); // reset the watchdog
   switch (c) {
   case 0x33:
     send_ack(0xCC);
     return HPSerial::STATE_PAYLOAD_SIZE;
     break;
+  case 0x55: // EoT
+    return HPSerial::STATE_IDLE;
+    break;
   case 0x66:
     send_ack(0x99);
     return HPSerial::STATE_COMMAND;
     break;
-  default:
-    return do_state_initial(data, 0x00);
+  case 0xFF:
+    return HPSerial::STATE_IDLE;
+  default: // unknown value
+    send_ack(0xFF);
+    return HPSerial::STATE_IDLE;
   }
 }
 
-HPSerial::state_t HPSerial::do_state_command(HPSerial::instance_data_t *data,
-					     uint8_t c)
+HPSerial::state_t HPSerial::do_state_command(uint8_t c)
 {
   if (c == 0x55) { // EoT
-    return do_state_initial(data, 0x00);
+    return STATE_IDLE;
   }
 
-  data->cmd = c;
-  data->size = 0;
+  tr_data.cmd = c;
+  tr_data.size = 0;
+  tr_data.pos = 0;
   send_ack(0x00);
-  return HPSerial::STATE_PAYLOAD_SIZE;
+
+  if (c == 0x86) { // shutdown
+    pushCmd(tr_data.cmd, tr_data.size, tr_data.payload);
+    return HPSerial::STATE_IDLE;
+  } 
+  return STATE_PAYLOAD_SIZE;
 }
 
-HPSerial::state_t HPSerial::do_state_payload_size(HPSerial::instance_data_t *data,
-						  uint8_t c)
+HPSerial::state_t HPSerial::do_state_payload_size(uint8_t c)
 {
-  data->size = c;
-  data->received = 0;
+  tr_data.size = c;
+  tr_data.pos = 0;
   send_ack(0x00);
-  return HPSerial::STATE_PAYLOAD;
+  return STATE_PAYLOAD;
 }
 
-HPSerial::state_t HPSerial::do_state_payload(HPSerial::instance_data_t *data,
-					uint8_t c)
+HPSerial::state_t HPSerial::do_state_payload(uint8_t c)
 {
-  data->payload[data->received++] = c;
+  tr_data.payload[tr_data.pos++] = c;
   send_ack(0x00);
-  if (data->received >= data->size) {
-    pushCmd(data->cmd, data->size, data->payload);
-    return HPSerial::STATE_COMMAND;
+  if (tr_data.pos >= tr_data.size) {
+    pushCmd(tr_data.cmd, tr_data.size, tr_data.payload);
+    return HPSerial::STATE_IDLE;
   }
   return HPSerial::STATE_PAYLOAD;
 }
 
+HPSerial::state_t HPSerial::do_state_sending(uint8_t c)
+{
+  // ghee
+  if (c == 0xFF)
+    {
+      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();
+    }
+  serial.putc(tr_data.payload[tr_data.pos++]);
+  set_timer(RXTIMEOUT);
+  return HPSerial::STATE_SENDING;
+}
+
+HPSerial::state_t HPSerial::do_state_eot(uint8_t c)
+{
+  serial.putc(0x55); // EoT 
+  if (cur_gstate == GSTATE_STARTING) {
+    cur_gstate = GSTATE_STARTING2;
+    set_timer(0.002); // launch startup2 in 10ms
+  }
+  else {
+    cur_gstate = GSTATE_IDLE;
+    set_timer(); // We are IDLE, detach the timeouter
+  }
+  return STATE_IDLE;
+}
+
 HPSerial::state_t HPSerial::run_state(HPSerial::state_t cur_state,
-				      HPSerial::instance_data_t *data,
 				      uint8_t c)
 {
-  return (this->*(HPSerial::state_table[cur_state]))(data, c);
+  return (this->*(HPSerial::state_table[cur_state]))(c);
 };
 
 void HPSerial::rxIrq(void) {
@@ -139,7 +241,7 @@
 #endif
     lled = 1;
     val = serial.getc();
-    cur_state = run_state(cur_state, &rx_data, val);
+    cur_state = run_state(cur_state, val);
     lled = 0;
 #ifdef DEBUG2
     inrx=0;
@@ -149,5 +251,16 @@
 
 
 void HPSerial::timeout(void) {
-  cur_state = do_state_initial(&rx_data, 0x00);
+  set_timer(); // detach the timeouter
+  if (cur_gstate == GSTATE_STARTING)
+    _startup();
+  else if (cur_gstate == GSTATE_STARTING2)
+    _startup2();
+  else // reset
+    {
+    cur_gstate = GSTATE_IDLE;
+    cur_state = STATE_IDLE;
+    }
 }
+
+
--- a/src/hp34comm.h	Sat Oct 29 23:44:31 2016 +0200
+++ b/src/hp34comm.h	Wed Jan 18 23:19:13 2017 +0100
@@ -22,21 +22,27 @@
     char value[MAX_BUFF+1];
     unsigned long id;
   } CMD;
-
-
   
   HPSerial(PinName tx, PinName rx);
-  
+
   bool cmd_available(void);
   bool pop(CMD& cmd);
   bool cmd_buf_full(void);
   unsigned int nerrors(uint8_t errorno);
-		     
+  
+  void startup(void);
+  void send(const uint8_t *buf, uint8_t size);
+  void sendkey(uint8_t keycode);
   
 private:
   void pushCmd(uint8_t cmd, uint8_t size, char *payload);
   void rxIrq(void);
   void timeout(void);
+  void set_timer(float v=0.0) {
+    timeouter.detach();
+    if (v > 0.0)
+      timeouter.attach(callback(this, &HPSerial::timeout), v);
+  }
 
  private:
   RawSerial serial;
@@ -47,44 +53,69 @@
   unsigned int errs[MAX_ERRS];
   Ticker timeouter;
 
-  // state machine stuff
-  typedef enum {STATE_IDLE,
-		STATE_HANDCHEKED,
-		STATE_COMMAND,
-		STATE_PAYLOAD_SIZE,
-		STATE_PAYLOAD,
-		NUM_STATES} state_t;
-
+ public:
+  // global state machine
+  typedef enum {
+    GSTATE_STARTING,
+    GSTATE_STARTING2,
+    GSTATE_IDLE,
+    GSTATE_TX,
+    GSTATE_RX,
+    NUM_GSTATES} gstate_t;
+  gstate_t gstate() {return cur_gstate;};
+  /* gstate_t do_start(); */
+  /* gstate_t do_send(); */
+  /* gstate_t do_receive(); */
   
-  typedef struct instance_data {
+  /* typedef gstate_t(HPSerial::*gstatemethod)(); */
+  /* statemethod const gstate_table[NUM_GSTATES] = { */
+  /*     &HPSerial::do_start, */
+  /*     &HPSerial::do_send, */
+  /*     &HPSerial::do_receive, */
+  /* }; */
+  
+  /* gstate_t run_gstate(gstate_t cur_state); */
+ private:
+  gstate_t cur_gstate;
+  
+ public:
+  // transmission state machine
+  typedef enum {
+    STATE_IDLE,
+    STATE_COMMAND,
+    STATE_PAYLOAD_SIZE,
+    STATE_PAYLOAD,
+    STATE_SENDING,
+    STATE_EOT,
+    NUM_STATES} state_t;
+  state_t state() {return cur_state;};
+  
+ private:
+  typedef struct state_data {
     uint8_t cmd;
     uint8_t size;
-    uint8_t received;
+    uint8_t pos;
     char payload[MAX_BUFF];
-  } instance_data_t;
+  } state_data_t;
 
-  state_t do_state_initial(instance_data_t *data, uint8_t c);
-  state_t do_state_handcheck(instance_data_t *data, uint8_t c);
-  state_t do_state_command(instance_data_t *data, uint8_t c);
-  state_t do_state_payload_size(instance_data_t *data, uint8_t c);
-  state_t do_state_payload(instance_data_t *data, uint8_t c);
+  void _startup(void);
+  void _startup2(void);
+  state_t do_state_initial(uint8_t c=0x00);
+  state_t do_state_command(uint8_t c);
+  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=0x00);
 
   void send_ack(uint8_t c);
   
-  // pointer to "state method" (ie. one of the just above)
-  typedef state_t(HPSerial::*statemethod)(instance_data_t *data, uint8_t c);
-  statemethod const state_table[NUM_STATES] = {
-      &HPSerial::do_state_initial,
-      &HPSerial::do_state_handcheck,
-      &HPSerial::do_state_command,
-      &HPSerial::do_state_payload_size,
-      &HPSerial::do_state_payload,
-  };
-  
-  state_t run_state(state_t cur_state, instance_data_t *data, uint8_t c);
+  typedef state_t(HPSerial::*statemethod)(uint8_t c);
+  static  statemethod state_table[NUM_STATES];  
+  state_t run_state(state_t cur_state, uint8_t c);
 
   state_t cur_state;
-  instance_data rx_data;
+  state_data_t tr_data;
 };
 
+
 #endif
--- a/src/main.cpp	Sat Oct 29 23:44:31 2016 +0200
+++ b/src/main.cpp	Wed Jan 18 23:19:13 2017 +0100
@@ -12,50 +12,88 @@
 #include "SSD1322.h"
 #include "hp34comm.h"
 
+#include "QEI.h"
 #include "Keypad.h"
 
+/******************************************************/
+/*                 L432KC                             */
+/******************************************************/
 #if (defined STM32L432xx)
 // display
 #define DSP_MOSI PA_7 //A6
-#define DSP_MISO PA_6 //A5 
+#define DSP_MISO PA_6 //A5
 #define DSP_SCLK PA_5 //A4
 #define DSP_CS   PB_0 //D3
 #define DSP_RST  PB_5 //D11
 #define DSP_DC   PB_4 //D12
+
 // UART for RX (CPU->DP) and TX (DP->CPU) combined
 #define HP_TX PA_9 // serial1 TX
 #define HP_RX PA_10 // serial1 RX
+
+// RST pin (handle this by hand)
+#define HP_RST PA_0
+
 // misc
-#define DBGPIN PA_12
+#define DBGPIN NC
+
+// encoder
+#define KP_ENC1 PA_8
+#define KP_ENC2 PA_11
 
-#elif (defined STM32F303x8)
-// display
-#define DSP_MOSI PA_7 //A6
-#define DSP_MISO PA_6 //A5 
-#define DSP_SCLK PA_5 //A4
-#define DSP_CS   PA_4
-#define DSP_RST  PB_5 //D11
-#define DSP_DC   PB_4 //D12
-// UART for RX (CPU->DP) and TX (DP->CPU) combined
-#define HP_RX PA_10 // serial1 RX
-// misc
-#define DBGPIN PA_12
+// keypad
+#define KP_R0 PA_1
+#define KP_R1 PA_3
+#define KP_R2 PA_4
+#define KP_R3 PA_12
 
+#define KP_C0 D4
+#define KP_C1 D5
+#define KP_C2 D6
+#define KP_C3 D7
+#define KP_C4 D8
+
+/******************************************************/
+/*                 F446RE                             */
+/******************************************************/
 #elif defined STM32F446xx
+// UART
+// USBTX PA_2
+// USBRX PA_3
 // display
 #define DSP_MOSI PB_15
-#define DSP_MISO PB_14
+#define DSP_MISO NC
 #define DSP_SCLK PB_13
 #define DSP_CS   PB_12
-#define DSP_RST  D11
-#define DSP_DC   D12
+#define DSP_RST  PB_5
+#define DSP_DC   PB_4
+
 // UART for RX (CPU->DP)
-#define HP_RX PA_1 // serial4 RX
-// UART for TX (DP->CPU)
-#define HP_TX PC_7 // serial6 RX
+#define HP_RX PC_11 // serial3 RX
+#define HP_TX PC_10 // serial3 TX
+
+// RST pin (handle this by hand)
+#define HP_RST PC_12
+
+// encoder
+#define KP_ENC1 PC_4
+#define KP_ENC2 PC_5
+
+// keypad
+#define KP_R0 PC_0   //  I-6
+#define KP_R1 PC_1   // II-5
+#define KP_R2 PC_2   //  I-5
+#define KP_R3 PC_3   // II-4
+
+
+#define KP_C0 PB_0   //  I-4
+#define KP_C1 PA_6   //  I-2
+#define KP_C2 PA_7   //  I-3
+#define KP_C3 PA_5   //  I-1
+#define KP_C4 PD_2   // II-1
 
 // misc
-#define DBGPIN PC_0
+#define DBGPIN PC_6
 
 #endif
 
@@ -63,16 +101,68 @@
 Serial pc(USBTX, USBRX);
 #endif
 
-SSD1322 *dsp;//(10000000, DSP_MOSI, DSP_MISO, DSP_SCLK, DSP_CS, DSP_RST, DSP_DC, "SSD1322");
-HPSerial *hp; //(HP_RX, HP_TX);
+SSD1322 *dsp;
+HPSerial *hp;
 volatile uint8_t must_refresh;
 Thread tdsp, tloop;
-Timeout blinker;
+Ticker blinker;
+Timeout rst_delay;
+Timeout splashscreen_timer;
 DigitalOut led(LED1);
+InterruptIn rst(HP_RST);
+
+QEI qenc(KP_ENC1, KP_ENC2, NC, 16);
+volatile uint8_t knob;
+volatile bool splashscreen;
+
+
+typedef enum {
+  KEY_NONE=0,
+  KEY_PRESSED,
+  KEY_RELEASED
+} key_event_t;
+
+typedef struct keycode {
+  uint8_t row;
+  uint8_t col;
+  key_event_t keyevent;
+} keycode_t;
+
+volatile keycode_t cur_keycode;
 
-Keypad kpad(std::vector<int>({(int)PA_0, (int)PA_1}),
-	    std::vector<int>({(int)PA_8, (int)PA_11}));
+PinName kp_rows[] = {
+  KP_R0,
+  KP_R1,
+  KP_R2,
+  KP_R3
+};
+
+PinName kp_colums[] = {
+  KP_C0, KP_C1,
+  KP_C2, KP_C3,
+  KP_C4
+};
 
+DigitalIn kp_in[] = {
+  KP_R0,
+  KP_R1,
+  KP_R2,
+  KP_R3
+};
+
+DigitalOut kp_out[] = {
+  KP_C0, KP_C1,
+  KP_C2, KP_C3,
+  KP_C4
+};
+
+uint8_t kp_nrows = sizeof(kp_in)/sizeof(kp_in[0]);
+uint8_t kp_ncols = sizeof(kp_out)/sizeof(kp_out[0]);
+
+void kp_cb(uint8_t row, uint8_t col);
+void kr_cb(uint8_t row, uint8_t col);
+
+Keypad *kpad;
 uint8_t curchar;
 uint8_t cmd;
 uint8_t nchars;
@@ -80,7 +170,6 @@
 
 void timeout_h() {
   led = !led;
-  blinker.attach(&timeout_h, 0.5f);  
 }
 
 typedef struct _DSP
@@ -161,7 +250,7 @@
     // right-side icons area
     { 0x00, 0x02, 0, 0,  NULL, icon_alarm}, // F1.1
     { 0x01, 0x02, 0, 11, NULL, icon_curve}, // F1.2
-    
+
 
     { 0x03, 0x04, 1, 2, "Channel"}, // F1.4
 
@@ -182,10 +271,10 @@
     // col 4
     { 0x26, 0x080, 0, 0,  "EXT"},  // F3.7
     { 0x25, 0x080, 0, 8,  "ONCE"}, // F3.6
-    
+
     { 0xFF, 0x080, 0, 16,  "MEM"},
 
-    
+
     // col 5
     { 0x14, 0x100, 0, 0,  "4W"},    // F2.5
     { 0x15, 0x100, 0, 8,  "OC"},    // F2.6
@@ -242,44 +331,90 @@
  }
   if (stayup)
     dbgpin = 1;
-
 }
 #else
 inline void pulse(uint8_t count=1, bool stayup=false)
 {}
 #endif
 
+// callbacks & thread functions
+void loop();
+void copy_to_lcd(void);
+void test_dsp();
+void reset(void);
+void reset_irq(void);
+void qei_cb(int dir);
+void end_splashscreen(void);
 
 
-void copy_to_lcd(void);
-void test_dsp();
 
 void setup() {
-  blinker.attach(&timeout_h, 0.5f);
-
-  // init the LCD
-  dsp = new SSD1322(20000000, DSP_MOSI, DSP_MISO, DSP_SCLK, DSP_CS, DSP_RST, DSP_DC, "SSD1322");
-  //dsp.set_orientation(3);
 #ifdef HAVE_PC
   pc.baud (115200);
 #endif
-  printf("\n\nSystem Core Clock = %.3f MHZ\r\n",
+  
+  printf("\n\nSETUP\n");
+  printf("  System Core Clock = %.3f MHZ\r\n",
   	 (float)SystemCoreClock/1000000);
   
+  //printf("Attaching Led 1: %d\n", LED1);
+  //blinker.attach(callback(timeout_h), 0.5f);
+  
+  hp = NULL;
+  printf("Setup HP communication pins\n");
+  printf("     HP_RX=%d\n", HP_RX);
+  DigitalIn(HP_RX).mode(PullDown);
+  printf("     HP_TX=%d\n", HP_TX);
+  DigitalOut(HP_TX).write(1);
+  printf("     HP_RST=%d\n", HP_RST);
+  DigitalIn(HP_RST).mode(PullDown);
+  
+  printf("  setup QEI pins\n");
+  printf("     ENC1=%d\n", KP_ENC1);
+  DigitalIn(KP_ENC1).mode(PullUp);
+  printf("     ENC2=%d\n", KP_ENC2);
+  DigitalIn(KP_ENC2).mode(PullUp);
+  qenc.attach(&qei_cb);
+
+  printf("  setup Keypad\n");
+  cur_keycode.keyevent = KEY_NONE;
+  uint8_t nrows = sizeof(kp_rows)/sizeof(kp_rows[0]);
+  uint8_t ncols = sizeof(kp_colums)/sizeof(kp_colums[0]);
+
+  kpad = new Keypad(nrows, kp_in, ncols, kp_out);
+  printf("  attach Keypad callbacks\n");
+  kpad->attach(&kp_cb, &kr_cb);
+  printf("  start Keypad\n");
+  kpad->start();  
+  
+  printf("Setup OLED display\n");
+  splashscreen = true;
+  // init the LCD
+  printf("     DSP_MOSI=%d\n", DSP_MOSI);
+  printf("     DSP_MISO=%d\n", DSP_MISO);
+  printf("     DSP_SCLK=%d\n", DSP_SCLK);
+  printf("     DSP_CS=%d\n", DSP_CS);
+  printf("     DSP_RST=%d\n", DSP_RST);
+  printf("     DSP_DC=%d\n", DSP_DC);
+  dsp = new SSD1322(20000000, DSP_MOSI, DSP_MISO, DSP_SCLK, DSP_CS,
+		    DSP_RST, DSP_DC, "SSD1322");
+  //dsp.set_orientation(3);
+  printf("  configure DSP\n");
   // myLCD.set_font((unsigned char*) Terminal6x8);
   // myLCD.claim(stdout);      // send stdout to the LCD display
   // myLCD.claim(stderr);      // send stderr to the LCD display
   dsp->background(Black);    // set background to black
   dsp->foreground(0xF);
   dsp->cls();
-  
+
   cmd = 0xFF;
   curchar = 0;
   nchars = 0;
 
   for (uint8_t i=0; i<sizeof(table)/sizeof(table[0]); ++i)
     memset(table[i].buffer, 0, MAX_BUFF+1);
-  
+
+  printf("  display splash screen\n");
   dsp->locate(30, 10);
   dsp->set_font((unsigned char*)Mono19x27);
   dsp->printf("HP34970A");
@@ -287,21 +422,54 @@
   dsp->locate(90, 40);
   dsp->printf("David Douard");
   dsp->copy_to_lcd();
-  wait(2);
-  dsp->cls();
+
+  printf("Starting LCD thread\n");
+  tdsp.start(&copy_to_lcd);
+
+  printf("Starting Event thread\n");
+  tloop.start(&loop);
+  
+  printf("Attaching timers\n");
+  splashscreen_timer.attach(callback(&end_splashscreen), 2);
+  rst.fall(&reset_irq);
+  
+  printf("SETUP DONE\n");
+}
 
-  hp = new HPSerial(HP_TX, HP_RX);
-  //hp = NULL;
+void end_splashscreen(void)
+{
+  printf("End of splash screen\n");
+  splashscreen = false;
+}
+
+void reset_irq(void)
+{
+  rst_delay.attach(callback(&reset), 0.1);  
+}
+
+void reset(void)
+{
+  if (DigitalIn(HP_RST).read() == 0) {
+    if (hp == NULL) {
+      printf("setup HP communication handler\n");
+      hp = new HPSerial(HP_TX, HP_RX);
+    }
+  
+    printf("!! RST !! (gstate=%d, state=%d)\n",
+	   hp->gstate(), hp->state());
+    //printf("Value is ... %X\n", hp->search());
+    hp->startup();
+  }
 }
 
 void copy_to_lcd(void) {
-  uint8_t mask=1;
+  //uint8_t mask=1;
 
   while(1) {
     pulse(0, true);
-    if (must_refresh) {
+    if ((splashscreen == false) && (must_refresh)) {
       must_refresh = 0;
-      //Thread::wait(20); // give a bit of time for some more cmds  
+      //Thread::wait(20); // give a bit of time for some more cmds
       dsp->copy_to_lcd();
     }
 
@@ -325,11 +493,15 @@
   }
 }
 
-void show(uint8_t cmd, char *txt, uint8_t nchar=0) {
+void show(uint8_t cmd, const char *intxt, uint8_t nchar=0) {
   uint8_t i, len;
   uint16_t bgcolor, fgcolor;
   char *oldv;
+  char *txt;
 
+  
+  txt = (char *)malloc(strlen(intxt)+1);
+  strcpy(txt, intxt);
   pulse(1, true);
 
   len = MAX_BUFF;
@@ -359,7 +531,7 @@
 	    if (txt[k] == 0x09) { // \t is a special char for 'unselected' display value
 	      txt[k] = 0x00;
 	      dsp->printf(txt);
-	      
+
 	      if (fgcolor == table[i].color)
 		fgcolor /= 2;
 	      else
@@ -467,7 +639,7 @@
       break;
     }
   }
-
+  free(txt);
   //dsp->copy_to_lcd();
   pulse(1, false);
 }
@@ -510,49 +682,76 @@
 }
 
 
-void loop() { // run over and over
+void loop()
+{ // run over and over
   unsigned int err[8];
   for (uint8_t i=0; i<8; i++)
     err[i] = 0;
+  int p, pp;
+  p=0;
+  pp=0;
   while(1) {
-      if (hp->cmd_available())
-	{
-	  led = 1;
-	  HPSerial::CMD cmd;
-	  if (hp->pop(cmd))
-	    {
-	      for (uint8_t i=0; i<7; i++)
-		if (hp->nerrors(i) > err[i]) {
-		  printf("ERR: %d/%d/%d/%d/%d/%d/%d\n",
-			 hp->nerrors(0),
-			 hp->nerrors(1),
-			 hp->nerrors(2),
-			 hp->nerrors(3),
-			 hp->nerrors(4),
-			 hp->nerrors(5),
-			 hp->nerrors(6)
-			 );
-		  break;
-		}
-	      for (uint8_t i=0; i<7; i++)
-		err[i] = hp->nerrors(i);
-	      printf("CMD[%d] %02X", cmd.id, cmd.cmd);
-	      
-	      if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C))
-		printf(": '%s'\n", cmd.value);
-	      else {
-		printf(":");
-		for (uint8_t i=0; i<cmd.size; i++)
-		  printf("%02x ", cmd.value[i]);
-		printf("\n");	      
-	      }
-	      show(cmd.cmd, cmd.value, cmd.size);
-	    }
+    if (knob != 0)
+      {
+	if (hp != NULL) {
+	  printf("Sending keycode %X\n", knob);
+	  hp->sendkey(knob);
+	  printf("   DONE\n");
+	}
+	knob = 0;
+      }
+
+    if (cur_keycode.keyevent != KEY_NONE)
+      {
+	printf("Keycode %dx%d: %s\n",
+	       cur_keycode.row, cur_keycode.col,
+	       cur_keycode.keyevent==KEY_PRESSED?"pressed":"released");
+	cur_keycode.keyevent = KEY_NONE;
+      }
+
+    p = qenc.getPulses();
+    if (p != pp) {
+      printf("Pulses = %d\n", p);
+      pp = p;
+    }
+    if ((hp != NULL) && (hp->cmd_available()))
+      {
+        led = 1;
+	HPSerial::CMD cmd;
+	if (hp->pop(cmd))
+	  {
+            for (uint8_t i=0; i<7; i++)
+	      if (hp->nerrors(i) > err[i]) {
+    printf("ERR: %d/%d/%d/%d/%d/%d/%d\n",
+      hp->nerrors(0),
+      hp->nerrors(1),
+      hp->nerrors(2),
+      hp->nerrors(3),
+      hp->nerrors(4),
+      hp->nerrors(5),
+      hp->nerrors(6)
+      );
+    break;
+  }
+	    for (uint8_t i=0; i<7; i++)
+	      err[i] = hp->nerrors(i);
+	    printf("CMD[%d] %02X", (int)cmd.id, cmd.cmd);
+
+	    if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C))
+	      printf(": '%s'\n", cmd.value);
+	    else {
+              printf(":");
+	      for (uint8_t i=0; i<cmd.size; i++)
+		printf("%02x ", cmd.value[i]);
+	      printf("\n");
+            }
+	    show(cmd.cmd, cmd.value, cmd.size);
+           }
 	  else
 	    printf("\n");
-	  
+
 	  show(cmd.cmd, cmd.value, cmd.size);
-	    
+
 	  led = 0;
 	}
       else
@@ -560,15 +759,32 @@
   }
 }
 
+void qei_cb(int dir)
+{
+  if(dir == 1) // turn right
+    knob = 0x80;
+  else         // turn left
+    knob = 0x83;
+}
+
+void kp_cb(uint8_t row, uint8_t col)
+{
+    cur_keycode.row = row;
+    cur_keycode.col = col;
+    cur_keycode.keyevent = KEY_PRESSED;
+}
+
+void kr_cb(uint8_t row, uint8_t col)
+{
+    cur_keycode.row = row;
+    cur_keycode.col = col;
+    cur_keycode.keyevent = KEY_RELEASED;
+}
+
 int main()
 {
   setup();
-
-  tdsp.start(copy_to_lcd);
-
-  test_dsp();
-
-  tloop.start(loop);
-  while(1);
-  //loop();
+  printf("Main loop (noop)\n");
+  while(1)
+    wait(.1);
 }

mercurial