# HG changeset patch # User David Douard # Date 1473795168 -7200 # Node ID 219766126afbf1f5478224711ea3d0020101b421 # Parent a3233abe730e09777a75179e82fde0a8967ec83a another attempt using a more complete support of the protocol and async serial stuff diff -r a3233abe730e -r 219766126afb src/main.cpp --- a/src/main.cpp Fri Sep 09 23:42:39 2016 +0200 +++ b/src/main.cpp Tue Sep 13 21:32:48 2016 +0200 @@ -1,21 +1,27 @@ #include "stdio.h" + #include "mbed.h" #include "string" +#include "CircularBuffer.h" + #include "Terminal6x8.h" #include "Mono19x27.h" #include "Mono15x22.h" #include "Arial12x12.h" -#include "BufferedSerial.h" - #include "SSD1322.h" Serial pc(USBTX, USBRX); -BufferedSerial hp(NC, PA_1, 64, 0); // serial4 + +//BufferedSerial hp(NC, PA_1, 64, 0); // serial4 +#define HP_SERIAL_TX PC_7 // serial6 RX +#define HP_SERIAL_RX PA_1 // serial4 RX SSD1322 dsp(SPI_8, 10000000, PB_15, PB_14, PB_13, PB_12, D11, D12, "SSD1322", 256, 64); -#define MAX_BUFF 14 +#define BUF_SIZE 32 +#define MAX_BUFF 15 +#define MAX_ERRS 10 uint8_t curchar; uint8_t cmd; uint8_t nchars; @@ -137,6 +143,202 @@ {} #endif + + +/***** HP 34970A communication class ***/ + +class HPSerial { + +public: + enum TrState { + Idle = 0, + Tx, + Rx, + }; + typedef struct _CMD + { + TrState direction; + uint8_t cmd; + uint8_t size; + char value[MAX_BUFF+1]; + unsigned long id; + } CMD; + + + + HPSerial(): ncmd(0), serial_tx(NC, HP_SERIAL_TX), serial_rx(NC, HP_SERIAL_RX) { + pc.printf("HPSerial init\n"); + for(uint8_t i=0; i 0) { + // a payload char + buf[head++] = val; + tx_len--; + tx_ack = false; + } + else { + uint8_t cur_state = tx_state; + pushCmd(tx_state, tx_cmd, head, buf); + reset(); + + if (val != 0x55) { // not an end of transmission + // should be another cmd I think + tx_cmd = val; + tx_state = cur_state; + } + } + } + + + void rxIrq(void) { + uint8_t val; + if(serial_rx.readable()) { // no reason why we would end here without this condition, but hey + val = serial_rx.getc(); + + if (tx_state == Idle) + if (val == 0x66) { + // no transmission in progress, expect a start of transmission + tx_state = Rx; + tx_ack = false; + } + else + reset(4); + + else if (tx_state == Tx) // manage the acks + handleAck(val); + + else + handleChar(val); + } + } + + void txIrq(void) { + uint8_t val; + if(serial_tx.readable()) { // no reason why we would end here without this condition, but hey + val = serial_tx.getc(); + + if (tx_state == Idle) + if (val == 0x66) { + // no transmission in progress, expect a start of transmission + tx_state = Tx; + tx_ack = false; + } + else + reset(5); + + else if (tx_state == Rx) // manage the acks + handleAck(val); + + else + handleChar(val); + } + } + +private: + RawSerial serial_tx; + RawSerial serial_rx; + uint8_t buf[BUF_SIZE]; + uint8_t head; + uint8_t tx_state; + uint8_t tx_cmd; + uint8_t tx_len; + bool tx_ack; + CircularBuffer cmdbuf; + unsigned long ncmd; + unsigned int errs[MAX_ERRS]; +}; + + +HPSerial hp; +Ticker dsp_refresher; +volatile bool must_refresh; + +void copy_to_lcd(void); void test_dsp(); void setup() { @@ -147,8 +349,6 @@ pc.printf("\n\nSystem Core Clock = %.3f MHZ\r\n", (float)SystemCoreClock/1000000); - hp.baud(187500); - // myLCD.set_font((unsigned char*) Terminal6x8); // myLCD.claim(stdout); // send stdout to the LCD display // myLCD.claim(stderr); // send stderr to the LCD display @@ -161,6 +361,7 @@ cmd = 0xFF; curchar = 0; nchars = 0; + dsp.printf("HP34970A"); dsp.set_font(Terminal6x8); @@ -173,14 +374,17 @@ dsp.copy_to_lcd(); wait(2); dsp.cls(); + + dsp_refresher.attach(©_to_lcd, 0.1); test_dsp(); wait(2); dsp.cls(); + } -void go_msg() { - dsp.set_font((unsigned char*) Arial12x12); - dsp.locate(0, 38); +void copy_to_lcd(void) { + if (must_refresh) + dsp.copy_to_lcd(); } void show(uint8_t cmd, char *txt, uint8_t nchar=0) { @@ -188,6 +392,8 @@ uint16_t bgcolor, fgcolor; char *oldv; + must_refresh = false; + len = MAX_BUFF; for (i=0; i %02x", cmd, val); - } - - } else if (cmd == 0xFE ) { - if ((val == 0x66) || (val == 0x99)) { - cmd = val; - } else if (val == 0x55) { - cmd = 0xFF; - } else if (val == 0x00){ - // probably an ACK for a keypad related event - } else { - // display "junk" byte - DebugPulse(); - show(0xFF, "", 5); - dsp.printf("%02X=> %02x", cmd, val); - } + if (hp.cmd_available()) + { + HPSerial::CMD cmd; + if (hp.pop(cmd)) + { + pc.printf("CMD[%s:%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), + cmd.cmd); - } else if (cmd == 0x66) { // waiting for the display command - if ((val == 0x0C) || (val == 0x00) || (val == 0x01) || (val == 0x02) || (val == 0x0A)) { - cmd = val; - nchars = 0; - } else { - cmd = 0xFE; - // display unknown cmd byte - DebugPulse(); - show(0xFF, "", 10); - dsp.printf("%02X-> %02x", cmd, val); - } - - } else if (cmd == 0x99) { // waiting for a 0x00, it's the DP that sent a keypress event - if (val != 0x00) { - show(0xFF, "", 0); - dsp.printf("%02X kp %02X", cmd, val); - } - cmd = 0xFF; - - } else if (nchars == 0) { // waiting for the number of chars to display - if (val>MAX_BUFF) { - // display warning - //dsp(); - //dsp << cmd << " got len " << val; - //DebugPulse(); - show(0xFF, "", 0); - dsp.printf("%02X len %d", cmd, val); - cmd = 0xFE; // weird - } else { - nchars = val; - curchar = 0; - } - - } else { // a character to display - buffer[curchar] = val; - curchar++; - if (curchar == nchars) { - buffer[curchar] = 0x00; - show(cmd, buffer, nchars); - nchars = 0; - curchar = 0; - cmd = 0xFE; - } - } - - DebugPulse(4); - - } + 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); + + } + } + } } int main()