src/main.cpp

Wed, 21 Sep 2016 20:09:21 +0200

author
David Douard <david.douard@logilab.fr>
date
Wed, 21 Sep 2016 20:09:21 +0200
changeset 6
8cb67d7afd79
parent 5
f1c85c2500f2
child 7
5cf4034ba4e0
permissions
-rw-r--r--

[SSD1322] add a copy_to_lcd method that accepts an area

#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 x;
  uint8_t y;
  const char* msg;
  const unsigned char* icon;
} FLAG;

static const FLAG flags[] =
  {
    //{ 0x00, 160, 30, "Alarm"},  // for the 'alarm' box
    { 0x00, 246, 0,  NULL, icon_alarm}, // F1.1
    { 0x01, 246, 11, NULL, icon_curve}, // F1.2
    { 0x03, 204, 30, "Channel"}, // F1.4
    { 0x14, 68, 44,  "4W"},      // F2.5
    { 0x32, 40, 44,  "*"},       // F4.3
    { 0x33, 40, 44,  "VIEW"},    // F4.4
    { 0x34, 0,  30,  "MON"},     // F4.5
    { 0x35, 0,  44,  "SCAN"},    // F4.6
    { 0x36, 0,  44,  "CONFIG"},  // F4.7
    
    { 0xFF, 0, 0,  "ADRS"},
    { 0xFF, 0, 0,  "RMT"},
    { 0xFF, 0, 0,  "ERROR"},
    { 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"},

    { 0xFF, 0, 0,  "H"},
    { 0xFF, 0, 0,  "1"},
    { 0xFF, 0, 0,  "2"},
    { 0xFF, 0, 0,  "3"},
    { 0xFF, 0, 0,  "4"},
    { 0xFF, 0, 0,  "L"},
    
  };

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

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 bool 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();
    dsp.locate(0, 0);
    dsp.set_font(Mono19x27);
    
    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.printf("HP34970A");
    dsp.set_font(Terminal6x8);
    for(uint8_t i=0; i<4;  i++) {
      dsp.locate(160, i*8);
      dsp.printf("Lg %d", i+1);
      dsp.locate(208, (3-i)*8);
      dsp.printf("Lg %d", i+1);
    }
    dsp.copy_to_lcd();
    wait(2);
    dsp.cls();
    
    test_dsp();
    dsp.copy_to_lcd();
    wait(2);
    dsp.cls();
    
}

void copy_to_lcd(void) {
  while(1) {
    pulse(0, true);
    if (must_refresh) {
      must_refresh = false;
      dsp.copy_to_lcd();
    }
    pulse(0, false);
    Thread::wait(100);
  }
}

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

  pulse(1, true);
  
  must_refresh = false;
  
  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.locate(table[i].x0, table[i].y0);
      dsp.set_font((unsigned char*) table[i].font);
      oldv = table[i].buffer;
      

      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 (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("]");
      }

      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.rect(frames[l].x0, frames[l].y0,
			   frames[l].x1, frames[l].y1,
			   fgcolor); 
		else
		  dsp.rect(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)) {
		  if (flags[l].msg != NULL) { // a string
		    dsp.locate(flags[l].x, flags[l].y);
		    dsp.printf(flags[l].msg);}
		  else { // an icon
		    Bitmap_s pic = {9, 10, 2, flags[l].icon};
		    dsp.Bitmap_BW(pic, flags[l].x, flags[l].y);
		  }
		  //break;
		}
	      }	      
	    }
	  }
	}
      }
      
      for(uint8_t j=0; j<table[i].maxsize; j++)
	oldv[j] = txt[j];
    }
  }

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

void test_dsp()
{
  show(0x00, "8g8g8g8g8g8g8", 13); // main dsp
  show(0x0C, "888", 3); // channel dsp
  show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags
}


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);
  tloop.start(loop);
  while(1);
  //loop();
}

mercurial