src/main.cpp

changeset 4
219766126afb
parent 3
a3233abe730e
child 5
f1c85c2500f2
equal deleted inserted replaced
3:a3233abe730e 4:219766126afb
1 #include "stdio.h" 1 #include "stdio.h"
2
2 #include "mbed.h" 3 #include "mbed.h"
3 #include "string" 4 #include "string"
5 #include "CircularBuffer.h"
6
4 #include "Terminal6x8.h" 7 #include "Terminal6x8.h"
5 #include "Mono19x27.h" 8 #include "Mono19x27.h"
6 #include "Mono15x22.h" 9 #include "Mono15x22.h"
7 #include "Arial12x12.h" 10 #include "Arial12x12.h"
8 11
9 #include "BufferedSerial.h"
10
11 #include "SSD1322.h" 12 #include "SSD1322.h"
12 13
13 Serial pc(USBTX, USBRX); 14 Serial pc(USBTX, USBRX);
14 BufferedSerial hp(NC, PA_1, 64, 0); // serial4 15
16 //BufferedSerial hp(NC, PA_1, 64, 0); // serial4
17 #define HP_SERIAL_TX PC_7 // serial6 RX
18 #define HP_SERIAL_RX PA_1 // serial4 RX
15 19
16 SSD1322 dsp(SPI_8, 10000000, PB_15, PB_14, PB_13, PB_12, D11, D12, "SSD1322", 256, 64); 20 SSD1322 dsp(SPI_8, 10000000, PB_15, PB_14, PB_13, PB_12, D11, D12, "SSD1322", 256, 64);
17 21
18 #define MAX_BUFF 14 22 #define BUF_SIZE 32
23 #define MAX_BUFF 15
24 #define MAX_ERRS 10
19 uint8_t curchar; 25 uint8_t curchar;
20 uint8_t cmd; 26 uint8_t cmd;
21 uint8_t nchars; 27 uint8_t nchars;
22 char buffer[MAX_BUFF+1]; 28 char buffer[MAX_BUFF+1];
23 29
135 #else 141 #else
136 inline void DebugPulse(uint8_t count=1) 142 inline void DebugPulse(uint8_t count=1)
137 {} 143 {}
138 #endif 144 #endif
139 145
146
147
148 /***** HP 34970A communication class ***/
149
150 class HPSerial {
151
152 public:
153 enum TrState {
154 Idle = 0,
155 Tx,
156 Rx,
157 };
158 typedef struct _CMD
159 {
160 TrState direction;
161 uint8_t cmd;
162 uint8_t size;
163 char value[MAX_BUFF+1];
164 unsigned long id;
165 } CMD;
166
167
168
169 HPSerial(): ncmd(0), serial_tx(NC, HP_SERIAL_TX), serial_rx(NC, HP_SERIAL_RX) {
170 pc.printf("HPSerial init\n");
171 for(uint8_t i=0; i<MAX_ERRS; i++)
172 errs[i] = 0;
173 reset();
174
175 serial_tx.baud(187500);
176 serial_tx.attach(this, &HPSerial::txIrq, Serial::RxIrq); //sic!
177
178 serial_rx.baud(187500);
179 serial_rx.attach(this, &HPSerial::rxIrq, Serial::RxIrq);
180 }
181
182 bool cmd_available(void) {
183 return !cmdbuf.empty();
184 }
185
186 bool pop(CMD& cmd) {
187 return cmdbuf.pop(cmd);
188 }
189
190 bool cmd_buf_full(void) {
191 return cmdbuf.full();
192 }
193
194 unsigned int nerrors(uint8_t errorno) {
195 return errs[errorno];
196 }
197
198
199
200 private:
201 void reset(uint8_t errorno=0xFF) {
202 head = 0;
203 tx_state = Idle;
204 tx_cmd = 0xFF;
205 tx_ack = false;
206 tx_len = 0xFF;
207 memset(buf, 0, BUF_SIZE);
208 if (errorno != 0xFF)
209 errs[errorno]++;
210 }
211
212 void handleAck(uint8_t val) {
213 if (tx_ack == true)
214 reset(0);
215
216 else
217 if (tx_cmd == 0xFF) // still at the beginning of a packet, expect 0x99 as ack
218 if (val == 0x99)
219 tx_ack = true;
220 else
221 reset(1);
222
223 else // expect 0x00 as ack
224 if (val == 0x00)
225 tx_ack = true;
226 else
227 reset(2);
228 }
229
230 void pushCmd(TrState direction, uint8_t cmd, uint8_t size, char *payload) {
231 CMD val;
232 uint8_t i;
233 val.id = ncmd++;
234 val.direction = direction;
235 val.cmd = cmd;
236 val.size = size;
237 for(i=0; i<size; i++)
238 val.value[i] = payload[i];
239 val.value[i] = 0x00;
240 cmdbuf.push(val);
241 }
242
243 void handleChar(uint8_t val) {
244 if (tx_ack == false)
245 reset(3);
246 else // remaining of the state machine
247 if (tx_cmd == 0xFF) {
248 // begin of transmission, expect a cmd
249 tx_cmd = val;
250 tx_ack = false;
251 tx_len = 0xFF;
252 }
253 else if (tx_len == 0xFF) {
254 // got a cmd, expect a payload size
255 tx_len = val;
256 tx_ack = false;
257 }
258 else if (tx_len > 0) {
259 // a payload char
260 buf[head++] = val;
261 tx_len--;
262 tx_ack = false;
263 }
264 else {
265 uint8_t cur_state = tx_state;
266 pushCmd(tx_state, tx_cmd, head, buf);
267 reset();
268
269 if (val != 0x55) { // not an end of transmission
270 // should be another cmd I think
271 tx_cmd = val;
272 tx_state = cur_state;
273 }
274 }
275 }
276
277
278 void rxIrq(void) {
279 uint8_t val;
280 if(serial_rx.readable()) { // no reason why we would end here without this condition, but hey
281 val = serial_rx.getc();
282
283 if (tx_state == Idle)
284 if (val == 0x66) {
285 // no transmission in progress, expect a start of transmission
286 tx_state = Rx;
287 tx_ack = false;
288 }
289 else
290 reset(4);
291
292 else if (tx_state == Tx) // manage the acks
293 handleAck(val);
294
295 else
296 handleChar(val);
297 }
298 }
299
300 void txIrq(void) {
301 uint8_t val;
302 if(serial_tx.readable()) { // no reason why we would end here without this condition, but hey
303 val = serial_tx.getc();
304
305 if (tx_state == Idle)
306 if (val == 0x66) {
307 // no transmission in progress, expect a start of transmission
308 tx_state = Tx;
309 tx_ack = false;
310 }
311 else
312 reset(5);
313
314 else if (tx_state == Rx) // manage the acks
315 handleAck(val);
316
317 else
318 handleChar(val);
319 }
320 }
321
322 private:
323 RawSerial serial_tx;
324 RawSerial serial_rx;
325 uint8_t buf[BUF_SIZE];
326 uint8_t head;
327 uint8_t tx_state;
328 uint8_t tx_cmd;
329 uint8_t tx_len;
330 bool tx_ack;
331 CircularBuffer<CMD, 32> cmdbuf;
332 unsigned long ncmd;
333 unsigned int errs[MAX_ERRS];
334 };
335
336
337 HPSerial hp;
338 Ticker dsp_refresher;
339 volatile bool must_refresh;
340
341 void copy_to_lcd(void);
140 void test_dsp(); 342 void test_dsp();
141 343
142 void setup() { 344 void setup() {
143 // init the LCD 345 // init the LCD
144 346
145 //dsp.set_orientation(3); 347 //dsp.set_orientation(3);
146 pc.baud (115200); 348 pc.baud (115200);
147 pc.printf("\n\nSystem Core Clock = %.3f MHZ\r\n", 349 pc.printf("\n\nSystem Core Clock = %.3f MHZ\r\n",
148 (float)SystemCoreClock/1000000); 350 (float)SystemCoreClock/1000000);
149
150 hp.baud(187500);
151 351
152 // myLCD.set_font((unsigned char*) Terminal6x8); 352 // myLCD.set_font((unsigned char*) Terminal6x8);
153 // myLCD.claim(stdout); // send stdout to the LCD display 353 // myLCD.claim(stdout); // send stdout to the LCD display
154 // myLCD.claim(stderr); // send stderr to the LCD display 354 // myLCD.claim(stderr); // send stderr to the LCD display
155 dsp.background(Black); // set background to black 355 dsp.background(Black); // set background to black
159 dsp.set_font(Mono19x27); 359 dsp.set_font(Mono19x27);
160 360
161 cmd = 0xFF; 361 cmd = 0xFF;
162 curchar = 0; 362 curchar = 0;
163 nchars = 0; 363 nchars = 0;
364
164 365
165 dsp.printf("HP34970A"); 366 dsp.printf("HP34970A");
166 dsp.set_font(Terminal6x8); 367 dsp.set_font(Terminal6x8);
167 for(uint8_t i=0; i<4; i++) { 368 for(uint8_t i=0; i<4; i++) {
168 dsp.locate(160, i*8); 369 dsp.locate(160, i*8);
171 dsp.printf("Lg %d", i+1); 372 dsp.printf("Lg %d", i+1);
172 } 373 }
173 dsp.copy_to_lcd(); 374 dsp.copy_to_lcd();
174 wait(2); 375 wait(2);
175 dsp.cls(); 376 dsp.cls();
377
378 dsp_refresher.attach(&copy_to_lcd, 0.1);
176 test_dsp(); 379 test_dsp();
177 wait(2); 380 wait(2);
178 dsp.cls(); 381 dsp.cls();
179 } 382
180 383 }
181 void go_msg() { 384
182 dsp.set_font((unsigned char*) Arial12x12); 385 void copy_to_lcd(void) {
183 dsp.locate(0, 38); 386 if (must_refresh)
387 dsp.copy_to_lcd();
184 } 388 }
185 389
186 void show(uint8_t cmd, char *txt, uint8_t nchar=0) { 390 void show(uint8_t cmd, char *txt, uint8_t nchar=0) {
187 uint8_t i, len; 391 uint8_t i, len;
188 uint16_t bgcolor, fgcolor; 392 uint16_t bgcolor, fgcolor;
189 char *oldv; 393 char *oldv;
190 394
395 must_refresh = false;
396
191 len = MAX_BUFF; 397 len = MAX_BUFF;
192 398
193 for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) { 399 for (i=0; i<sizeof(table)/sizeof(table[0]); ++i) {
194 if (table[i].cmd == cmd) { 400 if (table[i].cmd == cmd) {
195 bgcolor = table[i].bgcolor; 401 bgcolor = table[i].bgcolor;
264 case 4: //ignore 470 case 4: //ignore
265 break; 471 break;
266 } 472 }
267 } 473 }
268 } 474 }
269 dsp.copy_to_lcd(); 475 must_refresh = true;
270 476 //dsp.copy_to_lcd();
271 } 477 }
272 478
273 void test_dsp() 479 void test_dsp()
274 { 480 {
275 show(0x00, "8g8g8g8g8g8g8", 13); // main dsp 481 show(0x00, "8g8g8g8g8g8g8", 13); // main dsp
276 show(0x0C, "888", 3); // channel dsp 482 show(0x0C, "888", 3); // channel dsp
277 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // flags 483 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // flags
278 dsp.copy_to_lcd();
279 } 484 }
280 485
281 486
282 void loop() { // run over and over 487 void loop() { // run over and over
283 if (hp.readable()) { 488 if (hp.cmd_available())
284 uint8_t val = hp.getc(); 489 {
285 DebugPulse(3); 490 HPSerial::CMD cmd;
286 // 0xFF: idle 491 if (hp.pop(cmd))
287 // 0xFE: frame finished 492 {
288 // 0x66: Start of transmission received 493 pc.printf("CMD[%s:%d %d/%d/%d/%d/%d/%d] %X\n", (cmd.direction==HPSerial::Rx)?"Rx":"Tx", cmd.id,
289 pc.printf(" VAL=0x%X\tCMD=0x%X\n", val, cmd); 494 hp.nerrors(0),
290 if (cmd == 0xFF) { 495 hp.nerrors(1),
291 if ((val == 0x66) || (val == 0x99)) { 496 hp.nerrors(2),
292 cmd = val; 497 hp.nerrors(3),
293 } else if ((val == 0x00) || (val == 0x55)){ 498 hp.nerrors(4),
294 // probably an ACK for a keypad related event 499 hp.nerrors(5),
295 } else { 500 cmd.cmd);
296 // display "junk" byte 501
297 //DebugPulse(); 502 if (cmd.direction == HPSerial::Rx) {
298 show(0xFF, "", 0); 503 if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C))
299 dsp.printf("%02X:> %02x", cmd, val); 504 pc.printf(" data=%s\n", cmd.value);
300 } 505 show(cmd.cmd, cmd.value, cmd.size);
301 506
302 } else if (cmd == 0xFE ) { 507 }
303 if ((val == 0x66) || (val == 0x99)) { 508 }
304 cmd = val; 509 }
305 } else if (val == 0x55) {
306 cmd = 0xFF;
307 } else if (val == 0x00){
308 // probably an ACK for a keypad related event
309 } else {
310 // display "junk" byte
311 DebugPulse();
312 show(0xFF, "", 5);
313 dsp.printf("%02X=> %02x", cmd, val);
314 }
315
316 } else if (cmd == 0x66) { // waiting for the display command
317 if ((val == 0x0C) || (val == 0x00) || (val == 0x01) || (val == 0x02) || (val == 0x0A)) {
318 cmd = val;
319 nchars = 0;
320 } else {
321 cmd = 0xFE;
322 // display unknown cmd byte
323 DebugPulse();
324 show(0xFF, "", 10);
325 dsp.printf("%02X-> %02x", cmd, val);
326 }
327
328 } else if (cmd == 0x99) { // waiting for a 0x00, it's the DP that sent a keypress event
329 if (val != 0x00) {
330 show(0xFF, "", 0);
331 dsp.printf("%02X kp %02X", cmd, val);
332 }
333 cmd = 0xFF;
334
335 } else if (nchars == 0) { // waiting for the number of chars to display
336 if (val>MAX_BUFF) {
337 // display warning
338 //dsp();
339 //dsp << cmd << " got len " << val;
340 //DebugPulse();
341 show(0xFF, "", 0);
342 dsp.printf("%02X len %d", cmd, val);
343 cmd = 0xFE; // weird
344 } else {
345 nchars = val;
346 curchar = 0;
347 }
348
349 } else { // a character to display
350 buffer[curchar] = val;
351 curchar++;
352 if (curchar == nchars) {
353 buffer[curchar] = 0x00;
354 show(cmd, buffer, nchars);
355 nchars = 0;
356 curchar = 0;
357 cmd = 0xFE;
358 }
359 }
360
361 DebugPulse(4);
362
363 }
364 } 510 }
365 511
366 int main() 512 int main()
367 { 513 {
368 setup(); 514 setup();

mercurial