src/main.cpp

Fri, 23 Sep 2016 21:12:43 +0200

author
David Douard <david.douard@logilab.fr>
date
Fri, 23 Sep 2016 21:12:43 +0200
changeset 7
5cf4034ba4e0
parent 5
f1c85c2500f2
child 8
55021f3f1929
permissions
-rw-r--r--

attempt to update display by bloc

#include "stdio.h"

#include "mbed.h"
#include "rtos.h"
#include "string"

#include "Terminal6x8.h"
#include "Mono19x27.h"
#include "Mono15x22.h"
#include "Arial12x12.h"

#include "SSD1322.h"
#include "hp34comm.h"

Serial pc(USBTX, USBRX);

#define DEBUG

SSD1322 dsp(SPI_8, 20000000, PB_15, PB_14, PB_13, PB_12, D11, D12, "SSD1322", 256, 64);


uint8_t curchar;
uint8_t cmd;
uint8_t nchars;
char buffer[MAX_BUFF+1];

typedef struct _DSP
{
  uint8_t cmd;
  uint8_t color;
  uint8_t bgcolor;
  uint8_t x0;
  uint8_t y0;
  uint8_t fmt; // 0x01=>ascii, 0x02=>hex, 0x04=>bits, 0x08=>flags, 0x80=>ignore
  uint8_t maxsize;
  uint8_t width;
  const unsigned char* font;
  char buffer[MAX_BUFF+1];
} DSP;

static DSP table[] =
{
  { 0x00, 0xF,   0x0,  0,  0, 0x01, MAX_BUFF, 245, Mono19x27}, // main display
  { 0x0C, 0xF,   0x0,204, 38, 0x01, 3,        45,  Mono15x22}, // channels display
  //  { 0x01, 0xF,   0x0,  0,  0, 0x80, MAX_BUFF, 0, Terminal6x8},
  //  { 0x02, 0xF,   0x0,  0,  0, 0x80, MAX_BUFF, 0, Terminal6x8},
  { 0x0A, 0xF,   0x0,  0, 57, 0x0C, 4,        0, Terminal6x8}, // flags + bits
  //  { 0xFF, 0xF,   0x0,  0,  0, 0x80, MAX_BUFF, 0, Terminal6x8},
};

// 9x10
const unsigned char icon_alarm[] __attribute__((aligned (2))) =
{
  0x1c, 0x0,
  0x3e, 0x0,
  0x7f, 0x0,
  0x7f, 0x0,
  0x7f, 0x0,
  0x7f, 0x0,
  0x7f, 0x0,
  0x7f, 0x0,
  0xff, 0x80,
  0x10, 0x0
};

const unsigned char icon_curve[] __attribute__((aligned (2))) =
{
  0x80, 0x0,
  0x80, 0x0,
  0x80, 0x80,
  0x81, 0x0,
  0x9e, 0x0,
  0xa0, 0x0,
  0xc0, 0x0,
  0x80, 0x0,
  0x80, 0x0,
  0xff, 0x80
 };

typedef struct _FLAG
{
  uint8_t flag;
  uint8_t zone;
  uint8_t x;
  uint8_t y;
  const char* msg;
  const unsigned char* icon;
} FLAG;

typedef struct _FRAME
{
  uint8_t flag;
  uint8_t x0;
  uint8_t y0;
  uint8_t x1;
  uint8_t y1;
} FRAME;

static const FLAG flags[] =
  {
    // flag, zone, x0, y0, msg, icon
    // right-side icons area
    { 0x00, 0x02, 0, 0,  NULL, icon_alarm}, // F1.1
    { 0x01, 0x02, 0, 11, NULL, icon_curve}, // F1.2
    { 0x14, 0x02, 0, 22,  "4W"},    // F2.5

    { 0x03, 0x04, 1, 2, "Channel"}, // F1.4

    // col 1
    { 0x34, 0x10, 0,  0,  "MON"},     // F4.5
    { 0x33, 0x10, 0,  8,  "VIEW"},    // F4.4
    { 0x35, 0x10, 0,  16,  "SCAN"},   // F4.6

    //col 2
    { 0x32, 0x20, 0, 0,  "*"},      // F4.3
    { 0x36, 0x20, 0, 8,  "CFG"},    // F4.7
    { 0xFF, 0x20, 0, 16,  "ERROR"},

    /*
    { 0xFF, 0, 0,  "ADRS"},
    { 0xFF, 0, 0,  "RMT"},
    { 0xFF, 0, 0,  "EXT"},

    { 0xFF, 0, 0,  "ONCE"},
    { 0xFF, 0, 0,  "AUTO"},
    { 0xFF, 0, 0,  "MEM"},

    { 0xFF, 0, 0,  "LAST"},
    { 0xFF, 0, 0,  "MIN"},
    { 0xFF, 0, 0,  "MAX"},

    { 0xFF, 0, 0,  "AVG"},
    { 0xFF, 0, 0,  "OC"},
    */

    { 0x05, 0x08, 0,   0,  "Alarm"}, // F1.6
    { 0x06, 0x08, 0,  10,  "H"}, // F1.7
    { 0x13, 0x08, 6,  10,  "1"}, // F2.4
    { 0x10, 0x08, 12, 10,  "2"}, // F2.1
    { 0x12, 0x08, 18, 10,  "3"}, // F2.3
    { 0x11, 0x08, 24, 10,  "4"}, // F2.2
    { 0x04, 0x08, 30, 10,  "L"}, // F1.5

  };

static const FRAME zones[] =
  {
    { 0x01, 0,   0, 245, 27}, // main display area
    { 0x02, 246, 0, 255, 27}, // right notif area
    { 0x04, 203, 28, 255, 54}, // channels display area
    { 0x08, 160, 28, 202, 54}, // alarms area
    { 0x10, 0,  28, 32,  54}, // flags col1
    { 0x20, 33, 28, 70,  54}, // flags col2
    { 0x40, 71, 28, 159, 54}, // flags col3

    { 0x80, 0, 55, 255, 63}, // flags bits display area
  };

static const FRAME frames[] =
  {
    { 0x02, 203, 35, 248, 55}, // F1.3
  };


#ifdef DEBUG
#define DBGPIN PC_0

DigitalOut dbgpin(DBGPIN);
inline void pulse(uint8_t count=1, bool stayup=false)
{
  dbgpin = 0;
  wait_us(2);
  while (count--)
  {
    dbgpin = 1;
    wait_us(2);
    dbgpin = 0;
    wait_us(2);
 }
  if (stayup)
    dbgpin = 1;

}
#else
inline void pulse(uint8_t count=1, bool stayup=false)
{}
#endif


HPSerial hp;
volatile uint8_t must_refresh;
Thread tdsp, tloop;

void copy_to_lcd(void);
void test_dsp();

void setup() {
    // init the LCD

    //dsp.set_orientation(3);
    pc.baud (115200);
    pc.printf("\n\nSystem Core Clock = %.3f MHZ\r\n",
          (float)SystemCoreClock/1000000);

    // 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);

    dsp.locate(30, 10);
    dsp.set_font(Mono19x27);
    dsp.printf("HP34970A");
    dsp.set_font(Terminal6x8);
    dsp.locate(90, 40);
    dsp.printf("David Douard");
    dsp.copy_to_lcd();
    wait(2);
    dsp.cls();
}

void copy_to_lcd(void) {
  uint8_t mask=1;

  while(1) {
    pulse(0, true);
    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);
    Thread::wait(10);
  }
}

void show(uint8_t cmd, char *txt, uint8_t nchar=0) {
  uint8_t i, len;
  uint16_t bgcolor, fgcolor;
  char *oldv;

  pulse(1, true);

  len = MAX_BUFF;

  for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
    if (table[i].cmd == cmd) {
      bgcolor = table[i].bgcolor;
      fgcolor = table[i].color;
      dsp.background(bgcolor);
      dsp.foreground(fgcolor);
      dsp.set_font((unsigned char*) table[i].font);
      oldv = table[i].buffer;

      dsp.locate(table[i].x0, table[i].y0);

      if (table[i].fmt & 0x01 ) {
	// ascii
	if (table[i].width > 0)
	  dsp.fillrect(table[i].x0, table[i].y0, table[i].x0 + table[i].width, table[i].y0 + table[i].font[2], bgcolor);
	for (uint8_t k=0; ;k++) {
	  if (txt[k] == 0x00)
	    {
	      dsp.printf(txt);
	      break;
	    }
	  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
	      fgcolor = table[i].color;
	    dsp.foreground(fgcolor);
	    txt = &(txt[k+1]);
	    k = 0;
	  }
	}
	if (cmd == 0x00) // main area
	  must_refresh |= 0x01;
	if (cmd == 0x0C) // channels area
	  must_refresh |= 0x04;
      }

      /*
      if (table[i].fmt & 0x02 ) {
      // hex
	for (uint8_t j=0;; j++) {
	  if (txt[j] == 0x00)
	    break;
	  dsp.printf("%02X ", txt[j]);
	}
	for (uint8_t j=3*strlen(txt); j<table[i].maxsize; j++)
	  dsp.printf(" ");
      }
      */
      if (table[i].fmt & 0x04 ) {
      // binary
	dsp.foreground(fgcolor);
	dsp.printf(" [");
	for (uint8_t j=0; j<max(nchar, table[i].maxsize) ; j++) {
	  if (j>0) {
	    dsp.foreground(fgcolor);
	    dsp.printf(" | ");
	  }
	  for (uint8_t k=0; k<8; k++) {
	    if (txt[j] & (1 << (7-k)))
	      dsp.foreground(fgcolor);
	    else
	      dsp.foreground(bgcolor);
	    dsp.printf("%d", (8-k));
	  }
	}
	dsp.foreground(fgcolor);
	dsp.printf("]");
	must_refresh |= 0x80;
      }

      if (table[i].fmt & 0x08 ) {
      // flags
	for (uint8_t j=0; j<max(nchar, table[i].maxsize) ; j++) {
	  for (uint8_t k=0; k<8; k++) {
	    if ((txt[j] & (1 << k) ) != (oldv[j] & (1 << k))) {

	      if (txt[j] & (1 << k))
		dsp.foreground(fgcolor);
	      else
		dsp.foreground(bgcolor);

	      /*
	      for (uint8_t l=0;
		   l<(sizeof(frames)/sizeof(frames[0])); ++l) {
		if (frames[l].flag & ((j<<4) + k))
		  dsp.fillrect(frames[l].x0, frames[l].y0,
			       frames[l].x1, frames[l].y1,
			       fgcolor/8);
		else
		  dsp.fillrect(frames[l].x0, frames[l].y0,
			       frames[l].x1, frames[l].y1,
			       bgcolor);

	      }
	      */

	      for (uint8_t l=0;
		   l<(sizeof(flags)/sizeof(flags[0])); ++l) {
		if (flags[l].flag == ((j<<4) + k)) {
		  for (uint8_t m=0; m<(sizeof(zones)/sizeof(zones[0])); m++) {
		    if (flags[l].zone == zones[m].flag) {
		      if (flags[l].msg != NULL) { // a string
			dsp.locate(flags[l].x + zones[m].x0,
				   flags[l].y + zones[m].y0);
			dsp.printf(flags[l].msg);}
		      else { // an icon
			Bitmap_s pic = {9, 10, 2, flags[l].icon};
			dsp.Bitmap_BW(pic,
				      flags[l].x + zones[m].x0,
				      flags[l].y + zones[m].y0);
		      }
		      must_refresh |= zones[m].flag;
		      break;
		    }
		  }
		  break;
		}
	      }
	    }
	  }
	}
      }

      for(uint8_t j=0; j<table[i].maxsize; j++)
	oldv[j] = txt[j];
      break;
    }
  }

  //dsp.copy_to_lcd();
  pulse(1, false);
}

void test_dsp()
{
  const FRAME *z;
  show(0x00, "8g8g8g8g8g8g8", 13); // main dsp
  show(0x0C, "888", 3); // channel dsp
  show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags
  dsp.copy_to_lcd();
  wait(3);
  dsp.cls();
  

  for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++)
    {
      z = &zones[i];
      dsp.fillrect(z->x0, z->y0, z->x1, z->y1, 4+i);
      dsp.locate(z->x0+1, z->y0+1);
      dsp.printf("%d", i);
    }
  for (uint8_t i=0; i<(sizeof(zones)/sizeof(zones[0])); i++)
    {
      z = &zones[i];
      pc.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);
    }
  pc.printf("Done\n");
  wait(2);
  pc.printf("Copy ALL\n");
  dsp.copy_to_lcd();
  wait(2);  
  dsp.cls();
}


void loop() { // run over and over
  while(1){
  if (hp.cmd_available())
    {
      HPSerial::CMD cmd;
      if (hp.pop(cmd))
	{/*
	  pc.printf("CMD[%s:%d %d/%d/%d/%d/%d/%d/%d] %X\n", (cmd.direction==HPSerial::Rx)?"Rx":"Tx", cmd.id,
		    hp.nerrors(0),
		    hp.nerrors(1),
		    hp.nerrors(2),
		    hp.nerrors(3),
		    hp.nerrors(4),
		    hp.nerrors(5),
		    hp.nerrors(6),
		    cmd.cmd);
	 */
	  if (cmd.direction == HPSerial::Rx) {
	    //  if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C))
	    //  pc.printf("  data=%s\n", cmd.value);
	    show(cmd.cmd, cmd.value, cmd.size);

	  }
	}
    }
  Thread::wait(0.01);
  }
}

int main()
{
  setup();

  tdsp.start(copy_to_lcd);

  test_dsp();
  wait(5);
  dsp.cls();

  tloop.start(loop);
  while(1);
  //loop();
}

mercurial