21 |
21 |
22 |
22 |
23 Display *dsp; |
23 Display *dsp; |
24 volatile bool splashscreen; |
24 volatile bool splashscreen; |
25 HPSerial *hp; |
25 HPSerial *hp; |
26 Thread tdsp; |
26 Thread tdsp(osPriorityNormal, OS_STACK_SIZE, nullptr, "DSP"); |
27 Ticker blinker; |
27 Ticker dsp_refresh; |
28 Timeout rst_delay; |
28 Timeout rst_delay; |
29 Timeout splashscreen_timer; |
29 Timeout splashscreen_timer; |
|
30 Timeout byescreen_timer; |
30 InterruptIn rst(HP_RST); |
31 InterruptIn rst(HP_RST); |
31 |
32 |
32 QEI qenc(KP_ENC1, KP_ENC2, NC, 16); |
33 QEI qenc(KP_ENC1, KP_ENC2, NC, 16); |
33 volatile uint8_t knob; |
34 volatile uint8_t knob; |
34 bool shift; // true when kp is shifted, cleared by command 0x01 from Unit |
35 bool shift; // true when kp is shifted, cleared by command 0x01 from Unit |
|
36 bool must_reset; |
|
37 bool must_shutdown; |
35 |
38 |
36 typedef enum { |
39 typedef enum { |
37 KEY_NONE=0, |
40 KEY_NONE=0, |
38 KEY_PRESSED, |
41 KEY_PRESSED, |
39 KEY_RELEASED |
42 KEY_RELEASED |
92 {0x06, 0x05, 0x04, 0x0D, 0x0F}, |
94 {0x06, 0x05, 0x04, 0x0D, 0x0F}, |
93 {0x07, 0x11, 0x10, 0x0C, 0xFF}, |
95 {0x07, 0x11, 0x10, 0x0C, 0xFF}, |
94 {0x0A, 0x09, 0x08, 0x02, 0xFF} |
96 {0x0A, 0x09, 0x08, 0x02, 0xFF} |
95 }; |
97 }; |
96 |
98 |
|
99 #define KC_SHIFT 0x0C |
|
100 |
97 void kp_cb(uint8_t row, uint8_t col); |
101 void kp_cb(uint8_t row, uint8_t col); |
98 void kr_cb(uint8_t row, uint8_t col); |
102 void kr_cb(uint8_t row, uint8_t col); |
99 |
103 |
100 Keypad *kpad; |
104 Keypad *kpad; |
|
105 keycode_t last_key = {0, 0, KEY_NONE}; |
|
106 |
101 uint8_t curchar; |
107 uint8_t curchar; |
102 //uint8_t curcmd; |
108 //uint8_t curcmd; |
103 uint8_t nchars; |
109 uint8_t nchars; |
104 char buffer[MAX_BUFF+1]; |
110 char buffer[MAX_BUFF+1]; |
105 |
111 |
137 void reset(void); |
143 void reset(void); |
138 void reset_irq(void); |
144 void reset_irq(void); |
139 void qei_cb(int dir); |
145 void qei_cb(int dir); |
140 void end_splashscreen(void); |
146 void end_splashscreen(void); |
141 |
147 |
142 /* |
148 |
143 #if defined(HAVE_PC) |
149 #if defined(HAVE_PC) |
144 FileHandle *mbed::mbed_override_console(int fd) |
150 FileHandle *mbed::mbed_override_console(int fd) |
145 { |
151 { |
146 return static_cast<FileHandle*> (&pc); |
152 return static_cast<FileHandle*> (&pc); |
147 } |
153 } |
148 #endif |
154 #endif |
149 */ |
155 |
150 |
156 |
151 void setup() { |
157 void setup() { |
152 #if defined(HAVE_PC) |
158 #if defined(HAVE_PC) |
153 #if defined(TARGET_NUCLEO_F446RE) |
|
154 pc.set_baud(115200); |
|
155 #endif |
|
156 |
|
157 /* |
159 /* |
158 #if defined(TARGET_HP34970_FP_F303RD) |
160 #if defined(TARGET_HP34970_FP_F303RD) |
159 pc.init(); |
161 pc.init(); |
160 pc.connect(); |
162 pc.connect(); |
161 #endif |
163 #endif |
162 */ |
164 */ |
163 #endif |
165 #endif |
164 |
166 |
165 printf("\n\nSETUP\n"); |
167 printf("\n\nSETUP\n"); |
166 printf(" System Core Clock = %.3f MHZ\r\n", |
168 printf(" System Core Clock = %ld MHZ\r\n", SystemCoreClock/1000000); |
167 (float)SystemCoreClock/1000000); |
|
168 |
169 |
169 /* |
170 /* |
170 #if defined(HAS_LED) |
171 #if defined(HAS_LED) |
171 printf("Attaching Led 1: %d\n", LED1); |
172 printf("Attaching Led 1: %d\n", LED1); |
172 blinker.attach(callback(timeout_h), 0.5f); |
173 blinker.attach(callback(timeout_h), 0.5f); |
197 printf(" ENC2=%d\r\n", KP_ENC2); |
198 printf(" ENC2=%d\r\n", KP_ENC2); |
198 DigitalIn(KP_ENC2).mode(PullDown); |
199 DigitalIn(KP_ENC2).mode(PullDown); |
199 qenc.attach(&qei_cb); |
200 qenc.attach(&qei_cb); |
200 |
201 |
201 printf(" setup Keypad\r\n"); |
202 printf(" setup Keypad\r\n"); |
202 //cur_keycode.keyevent = KEY_NONE; |
|
203 |
203 |
204 shift = false; |
204 shift = false; |
|
205 must_reset = false; |
|
206 must_shutdown = false; |
205 kpad = new Keypad(KP_NROWS, kp_rows, KP_NCOLS, kp_columns); |
207 kpad = new Keypad(KP_NROWS, kp_rows, KP_NCOLS, kp_columns); |
206 printf(" attach Keypad callbacks\r\n"); |
208 printf(" attach Keypad callbacks\r\n"); |
207 kpad->attach(&kp_cb, &kr_cb); |
209 kpad->attach(&kp_cb, &kr_cb); |
208 printf(" start Keypad\r\n"); |
210 printf(" start Keypad\r\n"); |
209 kpad->start(); |
211 kpad->start(); |
228 |
230 |
229 printf(" display splash screen\r\n"); |
231 printf(" display splash screen\r\n"); |
230 dsp->show_splashscreen(); |
232 dsp->show_splashscreen(); |
231 |
233 |
232 printf("Starting LCD thread\r\n"); |
234 printf("Starting LCD thread\r\n"); |
|
235 // does not compile... |
|
236 // dsp_refresh.attach(callback(dsp, &Display::copy_to_lcd), 50ms); |
233 tdsp.start(&refresh_display); |
237 tdsp.start(&refresh_display); |
234 |
|
235 /* |
|
236 dsp->clrbuff(); |
|
237 show(0x00, "HH:MM:\tSS\t:mmmm", 15); // main dsp |
|
238 show(0x0C, "888", 3); // channel dsp |
|
239 show(0x0A, "\xFF\xFF\xFF\xFF", 4); // all flags |
|
240 */ |
|
241 |
238 |
242 printf("Attaching timers\r\n"); |
239 printf("Attaching timers\r\n"); |
243 splashscreen = true; |
240 splashscreen = true; |
244 splashscreen_timer.attach(callback(&end_splashscreen), 2ms); |
241 splashscreen_timer.attach(callback(&end_splashscreen), 2ms); |
245 rst.fall(&reset_irq); |
242 rst.fall(&reset_irq); |
252 // print is forbidden here because we are in an ISR context here |
249 // print is forbidden here because we are in an ISR context here |
253 //printf("End of splash screen CB\r\n"); |
250 //printf("End of splash screen CB\r\n"); |
254 splashscreen = false; |
251 splashscreen = false; |
255 } |
252 } |
256 |
253 |
|
254 void reset_irq_tmr(void) |
|
255 { |
|
256 must_reset = true; |
|
257 } |
|
258 |
257 void reset_irq(void) |
259 void reset_irq(void) |
258 { |
260 { |
259 rst_delay.attach(callback(&reset), 1ms); |
261 rst_delay.attach(callback(&reset_irq_tmr), 50ms); |
260 } |
262 } |
261 |
263 |
262 void reset(void) |
264 void reset(void) |
263 { |
265 { |
|
266 // this should be called as a result of the HP_RST pin going LO |
|
267 printf("Reset connection to the main unit\n"); |
264 if (DigitalIn(HP_RST).read() == 0) { |
268 if (DigitalIn(HP_RST).read() == 0) { |
265 if (hp == NULL) { |
269 if (hp == NULL) { |
266 printf("setup HP communication handler\r\n"); |
270 printf("setup HP communication handler\r\n"); |
267 hp = new HPSerial(HP_TX, HP_RX); |
271 hp = new HPSerial(HP_TX, HP_RX); |
268 } |
272 } |
|
273 else { |
|
274 printf("Connection already initialized\n"); |
|
275 } |
269 |
276 |
270 printf("!! RST !! (gstate=%d, state=%d)\r\n", |
277 printf("!! RST !! (gstate=%d, state=%d)\r\n", |
271 hp->gstate(), hp->state()); |
278 hp->gstate(), hp->state()); |
272 //printf("Value is ... %X\n", hp->search()); |
279 //printf("Value is ... %X\n", hp->search()); |
273 hp->startup(); |
280 dsp->power_on(); |
|
281 dsp->cls(); |
|
282 printf("Initiate startup sequence\n"); |
|
283 if (last_key.keyevent == KEY_PRESSED) |
|
284 hp->startup(kp_mapping[last_key.row][last_key.col]); |
|
285 else |
|
286 hp->startup(); |
274 } |
287 } |
|
288 else |
|
289 { |
|
290 printf("HP_RST is not LOW, skipping\n"); |
|
291 } |
275 } |
292 } |
276 |
293 |
277 void refresh_display(void) { |
294 void refresh_display(void) { |
278 //uint8_t mask=1; |
295 while(1) { //!must_shutdown) { |
279 |
296 dsp->copy_to_lcd(); |
280 while(1) { |
297 ThisThread::sleep_for(50ms); |
281 pulse(0, true); |
298 } |
282 if (splashscreen == false) { |
299 } |
283 //Thread::wait(20); // give a bit of time for some more cmds |
300 |
284 dsp->copy_to_lcd(); |
301 void shutdown(void) |
285 } |
302 { |
286 |
303 must_shutdown = true; |
287 /* |
|
288 if (must_refresh & mask) { |
|
289 for(uint8_t i=0; i<sizeof(zones)/sizeof(zones[0]); i++) |
|
290 if (zones[i].flag == mask) { |
|
291 dsp->copy_to_lcd(zones[i].x0/4, (zones[i].x1+3)/4, |
|
292 zones[i].y0, zones[i].y1); |
|
293 must_refresh &= ~mask; |
|
294 break; |
|
295 } |
|
296 } |
|
297 mask = mask << 1; |
|
298 if (mask == 0) { |
|
299 mask = 1; |
|
300 } |
|
301 */ |
|
302 pulse(0, false); |
|
303 |
|
304 ThisThread::sleep_for(30ms); |
|
305 } |
|
306 } |
304 } |
307 |
305 |
308 void mainloop() |
306 void mainloop() |
309 { // run over and over |
307 { // run over and over |
310 keycode_t key = {0, 0, KEY_NONE}; |
308 keycode_t key = {0, 0, KEY_NONE}; |
311 |
309 uint8_t keycode; // actual sent value to the CPU |
|
310 HPSerial::CMD cmd; |
|
311 unsigned int nkeys = 0; |
312 unsigned int err[8]; |
312 unsigned int err[8]; |
313 for (uint8_t i=0; i<8; i++) |
313 for (uint8_t i=0; i<8; i++) |
314 err[i] = 0; |
314 err[i] = 0; |
315 int p, pp; // rot encoder pulse counters |
|
316 p = 0; |
|
317 pp = 0; |
|
318 |
315 |
319 while(1) { |
316 while(1) { |
320 p = qenc.getPulses(); |
317 if (must_reset) { |
321 if (p != pp) |
318 must_reset = false; |
322 { |
319 reset(); |
323 dsp->locate(0, 0); |
320 } |
324 dsp->printf("Pulses = %d ", p); |
321 if (must_shutdown) { |
325 dsp->copy_to_lcd(); |
322 //tdsp.join(); |
326 pp = p; |
323 //dsp_refresh.detach(); |
327 } |
324 must_shutdown = false; |
|
325 dsp->power_off(); |
|
326 } |
328 |
327 |
329 if (knob != 0) |
328 if (knob != 0) |
330 { |
329 { |
331 if (hp != NULL) |
330 if (hp != NULL) |
332 { |
331 { |
333 printf("Sending keycode %X\r\n", knob); |
332 printf("KEY[%d] %s%X\n", nkeys++, knob<0x0F ? "0" : "", knob); |
334 hp->sendkey(knob); |
333 hp->sendkey(knob); |
335 printf(" DONE\r\n"); |
|
336 } |
334 } |
337 else |
335 else |
338 { |
336 { |
339 dsp->locate(70, 0); |
337 dsp->locate(70, 0); |
340 dsp->printf("Knob = %X ", knob); |
338 dsp->printf("Knob = %X ", knob); |
341 dsp->copy_to_lcd(); |
339 dsp->copy_to_lcd(); |
342 } |
340 } |
343 knob = 0; |
341 knob = 0; |
344 } |
342 } |
345 |
343 |
346 if (!key_buf.empty()) //cur_keycode.keyevent != KEY_NONE) |
344 if (!key_buf.empty()) |
347 { |
345 { |
348 key_buf.pop(key); |
346 key_buf.pop(key); |
349 printf("Keycode %dx%d: %s\r\n", |
347 keycode = kp_mapping[key.row][key.col]; |
350 key.row, key.col, key.keyevent==KEY_PRESSED?"pressed":"released"); |
348 |
|
349 if ((keycode == KC_SHIFT) && (key.keyevent == KEY_PRESSED)) |
|
350 { |
|
351 shift = true; |
|
352 dsp->shift_on(); |
|
353 } |
|
354 |
351 if (hp != NULL) { |
355 if (hp != NULL) { |
352 uint8_t keycode = kp_mapping[key.row][key.col]; |
356 if ((shift) && (keycode != KC_SHIFT)) |
|
357 { |
|
358 keycode |= 0x20; // bit 5: key shifted |
|
359 shift = false; |
|
360 dsp->shift_off(); |
|
361 } |
353 if (key.keyevent == KEY_RELEASED) |
362 if (key.keyevent == KEY_RELEASED) |
354 keycode |= 0x40; // bit 6: key relased |
363 keycode |= 0x40; // bit 6: key relased |
355 if (shift) |
364 printf("KEY[%d] %s%X\n", nkeys++, keycode<0x0F ? "0" : "", keycode); |
356 keycode |= 0x20; // bit 5: key shifted |
365 hp->sendkey(keycode); |
357 |
|
358 hp->sendkey(kp_mapping[key.row][key.col]); |
|
359 } |
366 } |
360 else |
367 else |
361 { |
368 { |
362 dsp->locate(140, 0); |
369 dsp->locate(140, 0); |
363 dsp->printf("KC: %dx%d[0x%s%X] %s", |
370 dsp->printf("KC: %dx%d[0x%s%X] %s", |
365 kp_mapping[key.row][key.col] <= 0x0F ? "0" : "", |
372 kp_mapping[key.row][key.col] <= 0x0F ? "0" : "", |
366 kp_mapping[key.row][key.col], |
373 kp_mapping[key.row][key.col], |
367 key.keyevent==KEY_PRESSED ? "PRE" : "REL"); |
374 key.keyevent==KEY_PRESSED ? "PRE" : "REL"); |
368 dsp->copy_to_lcd(); |
375 dsp->copy_to_lcd(); |
369 } |
376 } |
370 // cur_keycode.keyevent = KEY_NONE; |
|
371 } |
377 } |
372 |
378 |
|
379 // at each loop iteration, send buffered keycodes, if any |
|
380 if (hp != NULL) |
|
381 hp->send_key_when_idle(); |
373 |
382 |
374 if ((hp != NULL) && (hp->cmd_available())) |
383 if ((hp != NULL) && (hp->cmd_available())) |
375 { |
384 { |
376 HPSerial::CMD cmd; |
|
377 if (hp->pop(cmd)) |
385 if (hp->pop(cmd)) |
378 { |
386 { |
379 #if defined(HAS_LED) |
387 #if defined(HAS_LED) |
380 led = 1; |
388 led = 1; |
381 #endif |
389 #endif |
382 for (uint8_t i=0; i<7; i++) |
390 for (uint8_t i=0; i<7; i++) |
383 if (hp->nerrors(i) > err[i]) { |
391 if (hp->nerrors(i) > err[i]) { |
384 printf("ERR: %d/%d/%d/%d/%d/%d/%d\r\n", |
392 printf("ERR: %X/%X/%X/%X/%X/%X/%X\n", |
385 hp->nerrors(0), |
393 hp->nerrors(0), |
386 hp->nerrors(1), |
394 hp->nerrors(1), |
387 hp->nerrors(2), |
395 hp->nerrors(2), |
388 hp->nerrors(3), |
396 hp->nerrors(3), |
389 hp->nerrors(4), |
397 hp->nerrors(4), |
393 break; |
401 break; |
394 } |
402 } |
395 for (uint8_t i=0; i<7; i++) |
403 for (uint8_t i=0; i<7; i++) |
396 err[i] = hp->nerrors(i); |
404 err[i] = hp->nerrors(i); |
397 |
405 |
398 printf("CMD[%d] %02X", (int)cmd.id, cmd.cmd); |
406 printf("CMD[%d] %s%X", (int)cmd.id, cmd.cmd<0x10 ? "0" : "", cmd.cmd); |
399 |
407 |
400 // 0x00: main display |
408 // 0x00: main display |
401 // 0x0C: channel display |
409 // 0x0C: channel display |
402 if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C)) |
410 if ((cmd.cmd == 0x00) || (cmd.cmd == 0x0C)) |
403 printf(": '%s'\r\n", cmd.value); |
411 printf(": '%s'\n", cmd.value); |
404 else { |
412 else { |
405 printf(":"); |
413 printf(": "); |
406 for (uint8_t i=0; i<cmd.size; i++) |
414 for (uint8_t i=0; i<cmd.size; i++) |
407 printf("%02x ", cmd.value[i]); |
415 printf("%s%X ", cmd.value[i] < 0x10 ? "0" : "", cmd.value[i]); |
408 printf("\r\n"); |
416 printf("\n"); |
409 } |
417 } |
410 |
418 |
411 if (cmd.cmd == 0x01) { |
419 if (cmd.cmd == 0x01) { |
412 // clear a flag |
420 // clear a flag |
413 if (cmd.value[0] == 0x0E) { |
421 if (cmd.value[0] == 0x0E) { |
414 // clear the Shift flag |
422 // clear the Shift flag |
415 shift = false; |
423 shift = false; |
|
424 dsp->shift_off(); |
416 } |
425 } |
417 } else if (cmd.cmd == 0x86) { |
426 } else if (cmd.cmd == 0x86) { |
418 // shutdown |
427 // shutdown |
419 // TODO |
428 dsp->show_byescreen(); |
420 } else { |
429 byescreen_timer.attach(callback(&shutdown), 2s); |
|
430 } else { |
421 // display related commands |
431 // display related commands |
422 dsp->show(cmd.cmd, cmd.value, cmd.size); |
432 dsp->show(cmd.cmd, cmd.value, cmd.size); |
423 } |
433 } |
424 #if defined(HAS_LED) |
434 #if defined(HAS_LED) |
425 led = 0; |
435 led = 0; |