diff --git a/control/src/drv/b15f.cpp b/control/src/drv/b15f.cpp index f0f9eb1..1d9e218 100644 --- a/control/src/drv/b15f.cpp +++ b/control/src/drv/b15f.cpp @@ -72,6 +72,8 @@ void B15F::testConnection() RQ_TEST, dummy }; + + assertRequestLength(rq, RQ_TEST); usart.transmit(&rq[0], 0, sizeof(rq)); uint8_t aw[2]; @@ -92,6 +94,8 @@ void B15F::testIntConv() static_cast(dummy & 0xFF), static_cast(dummy >> 8) }; + + assertRequestLength(rq, RQ_INT_TEST); usart.transmit(&rq[0], 0, sizeof(rq)); uint16_t aw; @@ -109,6 +113,8 @@ std::vector B15F::getBoardInfo(void) { RQ_INFO }; + + assertRequestLength(rq, RQ_INFO); usart.transmit(&rq[0], 0, sizeof(rq)); uint8_t n; @@ -686,7 +692,7 @@ void B15F::init() std::vector info = getBoardInfo(); std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")" << std::endl; - + // Überprüfe Version std::string& avr_commit_hash = info[3]; if(avr_commit_hash.compare(COMMIT_HASH)) diff --git a/control/src/drv/commit_hash.h b/control/src/drv/commit_hash.h index f0106a0..99b6041 100644 --- a/control/src/drv/commit_hash.h +++ b/control/src/drv/commit_hash.h @@ -1,4 +1,4 @@ #ifndef COMMIT_HASH_H #define COMMIT_HASH_H -const char COMMIT_HASH[] = "018bd1057deef81d8a44a808b7c68fb29abc3be6"; +const char COMMIT_HASH[] = "6dff81fb75d39a4b063b6c8a1cb98a9aff0c3669"; #endif // COMMIT_HASH_H diff --git a/control/src/kleine_hilfe b/control/src/kleine_hilfe deleted file mode 100755 index 3900cbd..0000000 --- a/control/src/kleine_hilfe +++ /dev/null @@ -1,2 +0,0 @@ -make -su krause -c "sudo -S make install" diff --git a/control/src/publish_helper b/control/src/publish_helper new file mode 100755 index 0000000..d9f92fc --- /dev/null +++ b/control/src/publish_helper @@ -0,0 +1,2 @@ +#!/bin/bash +make clean && make && make doc && make clean && make doc && make diff --git a/control/src/ui/view_monitor.cpp b/control/src/ui/view_monitor.cpp index 7b63702..0036ad2 100644 --- a/control/src/ui/view_monitor.cpp +++ b/control/src/ui/view_monitor.cpp @@ -78,7 +78,7 @@ void ViewMonitor::worker() { try { - + #ifdef __arm__ // Raspberry Pi is much slower std::this_thread::sleep_for(std::chrono::milliseconds(1000)); diff --git a/docs/html/annotated.html b/docs/html/annotated.html index d0cc50d..2e716c6 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -85,7 +85,7 @@ $(function() { diff --git a/docs/html/b15f_8cpp_source.html b/docs/html/b15f_8cpp_source.html index fff65bb..dc8de76 100644 --- a/docs/html/b15f_8cpp_source.html +++ b/docs/html/b15f_8cpp_source.html @@ -70,58 +70,58 @@ $(function() {
b15f.cpp
-
1 #include "b15f.h"
2 
3 B15F *B15F::instance = nullptr;
4 errorhandler_t B15F::errorhandler = nullptr;
5 
6 
7 /*************************************
8  * Grundfunktionen des B15F Treibers *
9  *************************************/
10 
12 {
13  if (!instance)
14  instance = new B15F();
15 
16  return *instance;
17 }
18 
19 void B15F::reconnect()
20 {
21  uint8_t tries = RECONNECT_TRIES;
22  while (tries--)
23  {
25  discard();
26 
27  try
28  {
30  return; // no exceptionm means success
31  }
32  catch(DriverException& eDE)
33  {
34  // discard exception
35  }
36  }
37 
38  abort("Verbindung kann nicht repariert werden");
39 }
40 
41 void B15F::discard(void)
42 {
43  try
44  {
45  uint8_t rq[] =
46  {
47  RQ_DISCARD
48  };
49 
50  usart.clearOutputBuffer();
51  for (uint8_t i = 0; i < 16; i++)
52  {
53  usart.transmit(&rq[0], 0, sizeof(rq)); // sende discard Befehl (verwerfe input)
54  delay_ms(4);
55  }
56  usart.clearInputBuffer();
57  }
58  catch (std::exception &ex)
59  {
60  abort(ex);
61  }
62 }
63 
65 {
66  // erzeuge zufälliges Byte
67  srand(time(NULL));
68  uint8_t dummy = rand() % 256;
69 
70  uint8_t rq[] =
71  {
72  RQ_TEST,
73  dummy
74  };
75  usart.transmit(&rq[0], 0, sizeof(rq));
76 
77  uint8_t aw[2];
78  usart.receive(&aw[0], 0, sizeof(aw));
79 
80  assertCode(aw[0], MSG_OK);
81  assertCode(aw[1], dummy);
82 }
83 
84 void B15F::testIntConv()
85 {
86  srand(time(NULL));
87  uint16_t dummy = rand() % (0xFFFF / 3);
88 
89  uint8_t rq[] =
90  {
91  RQ_INT_TEST,
92  static_cast<uint8_t >(dummy & 0xFF),
93  static_cast<uint8_t >(dummy >> 8)
94  };
95  usart.transmit(&rq[0], 0, sizeof(rq));
96 
97  uint16_t aw;
98  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
99 
100  assertCode(aw, dummy * 3);
101 }
102 
103 
104 std::vector<std::string> B15F::getBoardInfo(void)
105 {
106  std::vector<std::string> info;
107 
108  uint8_t rq[] =
109  {
110  RQ_INFO
111  };
112  usart.transmit(&rq[0], 0, sizeof(rq));
113 
114  uint8_t n;
115  usart.receive(&n, 0, sizeof(n));
116  while (n--)
117  {
118  uint8_t len;
119  usart.receive(&len, 0, sizeof(len));
120 
121  char str[len + 1];
122  usart.receive(reinterpret_cast<uint8_t *>(&str[0]), 0, len);
123  str[len] = '\0';
124 
125  info.push_back(std::string(str));
126  }
127 
128  uint8_t aw;
129  usart.receive(&aw, 0, sizeof(aw));
130  if (aw != MSG_OK)
131  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
132 
133  return info;
134 }
135 
136 void B15F::delay_ms(uint16_t ms)
137 {
138  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
139 }
140 
141 void B15F::delay_us(uint16_t us)
142 {
143  std::this_thread::sleep_for(std::chrono::microseconds(us));
144 }
145 
146 void B15F::reverse(uint8_t& b)
147 {
148  b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
149  b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
150  b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
151 }
152 
153 // https://stackoverflow.com/a/478960
154 std::string B15F::exec(std::string cmd)
155 {
156  std::array<char, 128> buffer;
157  std::string result;
158  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
159  if (!pipe)
160  {
161  throw std::runtime_error("popen() failed!");
162  }
163  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
164  {
165  result += buffer.data();
166  }
167  return result;
168 }
169 
170 void B15F::abort(std::string msg)
171 {
172  DriverException ex(msg);
173  abort(ex);
174 }
175 
176 void B15F::abort(std::exception &ex)
177 {
178  if (errorhandler)
179  errorhandler(ex);
180  else
181  {
182  std::cout << ex.what() << std::endl;
183  throw DriverException(ex.what());
184  }
185 }
186 
187 void B15F::setAbortHandler(errorhandler_t func)
188 {
189  errorhandler = func;
190 }
191 
192 /*************************************/
193 
194 
195 
196 /*************************
197  * Steuerbefehle für B15 *
198  *************************/
199 
201 {
202  uint8_t rq[] =
203  {
204  RQ_SELF_TEST
205  };
206 
207  assertRequestLength(rq, RQ_SELF_TEST);
208  usart.transmit(&rq[0], 0, sizeof(rq));
209 
210  uint8_t aw;
211  usart.receive(&aw, 0, sizeof(aw));
212  assertCode(aw, MSG_OK);
213 }
214 
215 void B15F::digitalWrite0(uint8_t port)
216 {
217  uint8_t rq[] =
218  {
219  RQ_DIGITAL_WRITE_0,
220  port
221  };
222 
223  assertRequestLength(rq, RQ_DIGITAL_WRITE_0);
224  usart.transmit(&rq[0], 0, sizeof(rq));
225 
226  uint8_t aw;
227  usart.receive(&aw, 0, sizeof(aw));
228  assertCode(aw, MSG_OK);
229 }
230 
231 void B15F::digitalWrite1(uint8_t port)
232 {
233  uint8_t rq[] =
234  {
235  RQ_DIGITAL_WRITE_1,
236  port
237  };
238 
239  assertRequestLength(rq, RQ_DIGITAL_WRITE_1);
240  usart.transmit(&rq[0], 0, sizeof(rq));
241 
242  uint8_t aw;
243  usart.receive(&aw, 0, sizeof(aw));
244  assertCode(aw, MSG_OK);
245 }
246 
247 uint8_t B15F::digitalRead0()
248 {
249  usart.clearInputBuffer();
250  uint8_t rq[] =
251  {
252  RQ_DIGITAL_READ_0
253  };
254 
255  assertRequestLength(rq, RQ_DIGITAL_READ_0);
256  usart.transmit(&rq[0], 0, sizeof(rq));
257 
258  uint8_t aw;
259  usart.receive(&aw, 0, sizeof(aw));
260  return aw;
261 }
262 
263 uint8_t B15F::digitalRead1()
264 {
265  usart.clearInputBuffer();
266  uint8_t rq[] =
267  {
268  RQ_DIGITAL_READ_1
269  };
270 
271  assertRequestLength(rq, RQ_DIGITAL_READ_1);
272  usart.transmit(&rq[0], 0, sizeof(rq));
273 
274  uint8_t aw;
275  usart.receive(&aw, 0, sizeof(aw));
276  return aw;
277 }
278 
279 uint8_t B15F::readDipSwitch()
280 {
281  usart.clearInputBuffer();
282  uint8_t rq[] =
283  {
284  RQ_READ_DIP_SWITCH
285  };
286 
287  assertRequestLength(rq, RQ_READ_DIP_SWITCH);
288  usart.transmit(&rq[0], 0, sizeof(rq));
289 
290  uint8_t aw;
291  usart.receive(&aw, 0, sizeof(aw));
292 
293  reverse(aw); // DIP Schalter muss invertiert werden!
294 
295  return aw;
296 }
297 
298 void B15F::analogWrite0(uint16_t value)
299 {
300  uint8_t rq[] =
301  {
302  RQ_ANALOG_WRITE_0,
303  static_cast<uint8_t >(value & 0xFF),
304  static_cast<uint8_t >(value >> 8)
305  };
306 
307  assertRequestLength(rq, RQ_ANALOG_WRITE_0);
308  usart.transmit(&rq[0], 0, sizeof(rq));
309 
310  uint8_t aw;
311  usart.receive(&aw, 0, sizeof(aw));
312  assertCode(aw, MSG_OK);
313 }
314 
315 void B15F::analogWrite1(uint16_t value)
316 {
317  uint8_t rq[] =
318  {
319  RQ_ANALOG_WRITE_1,
320  static_cast<uint8_t >(value & 0xFF),
321  static_cast<uint8_t >(value >> 8)
322  };
323 
324  assertRequestLength(rq, RQ_ANALOG_WRITE_1);
325  usart.transmit(&rq[0], 0, sizeof(rq));
326 
327  uint8_t aw;
328  usart.receive(&aw, 0, sizeof(aw));
329  assertCode(aw, MSG_OK);
330 }
331 
332 uint16_t B15F::analogRead(uint8_t channel)
333 {
334  usart.clearInputBuffer();
335  if (channel > 7)
336  abort("Bad ADC channel: " + std::to_string(channel));
337 
338  uint8_t rq[] =
339  {
340  RQ_ANALOG_READ,
341  channel
342  };
343 
344  assertRequestLength(rq, RQ_ANALOG_READ);
345  usart.transmit(&rq[0], 0, sizeof(rq));
346 
347  uint16_t aw;
348  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
349 
350  if (aw > 1023)
351  abort("Bad ADC data detected (1)");
352  return aw;
353 }
354 
355 void B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b,
356  uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
357 {
358  // prepare pointers
359  buffer_a += offset_a;
360  buffer_b += offset_b;
361 
362 
363  usart.clearInputBuffer();
364  uint8_t rq[] =
365  {
366  RQ_ADC_DAC_STROKE,
367  channel_a,
368  channel_b,
369  static_cast<uint8_t >(start & 0xFF),
370  static_cast<uint8_t >(start >> 8),
371  static_cast<uint8_t >(delta & 0xFF),
372  static_cast<uint8_t >(delta >> 8),
373  static_cast<uint8_t >(count & 0xFF),
374  static_cast<uint8_t >(count >> 8)
375  };
376 
377  assertRequestLength(rq, RQ_ADC_DAC_STROKE);
378  usart.transmit(&rq[0], 0, sizeof(rq));
379 
380  for (uint16_t i = 0; i < count; i++)
381  {
382  if (buffer_a)
383  {
384  usart.receive(reinterpret_cast<uint8_t *>(&buffer_a[i]), 0, 2);
385 
386  if (buffer_a[i] > 1023) // check for broken usart connection
387  abort("Bad ADC data detected (2)");
388  }
389  else
390  {
391  usart.drop(2);
392  }
393 
394  if (buffer_b)
395  {
396  usart.receive(reinterpret_cast<uint8_t *>(&buffer_b[i]), 0, 2);
397 
398  if (buffer_b[i] > 1023) // check for broken usart connection
399  abort("Bad ADC data detected (3)");
400  }
401  else
402  {
403  usart.drop(2);
404  }
405  }
406 
407  uint8_t aw;
408  usart.receive(&aw, 0, sizeof(aw));
409  assertCode(aw, MSG_OK);
410 }
411 
412 uint8_t B15F::pwmSetFrequency(uint32_t freq)
413 {
414  usart.clearInputBuffer();
415 
416  uint8_t rq[] =
417  {
418  RQ_PWM_SET_FREQ,
419  static_cast<uint8_t>((freq >> 0) & 0xFF),
420  static_cast<uint8_t>((freq >> 8) & 0xFF),
421  static_cast<uint8_t>((freq >> 16) & 0xFF),
422  static_cast<uint8_t>((freq >> 24) & 0xFF)
423  };
424 
425  assertRequestLength(rq, RQ_PWM_SET_FREQ);
426  usart.transmit(&rq[0], 0, sizeof(rq));
427 
428  uint8_t aw;
429  usart.receive(&aw, 0, sizeof(aw));
430  return aw;
431 }
432 
433 void B15F::pwmSetValue(uint8_t value)
434 {
435  usart.clearInputBuffer();
436 
437  uint8_t rq[] =
438  {
439  RQ_PWM_SET_VALUE,
440  value
441  };
442 
443  assertRequestLength(rq, RQ_PWM_SET_VALUE);
444  usart.transmit(&rq[0], 0, sizeof(rq));
445 
446  uint8_t aw;
447  usart.receive(&aw, 0, sizeof(aw));
448  assertCode(aw, MSG_OK);
449 }
450 
451 void B15F::setMem8(volatile uint8_t* adr, uint8_t val)
452 {
453  usart.clearInputBuffer();
454 
455  uint8_t rq[] =
456  {
457  RQ_SET_MEM_8,
458  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
459  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
460  val
461  };
462 
463  assertRequestLength(rq, RQ_SET_MEM_8);
464  usart.transmit(&rq[0], 0, sizeof(rq));
465 
466  uint8_t aw;
467  usart.receive(&aw, 0, sizeof(aw));
468  assertCode(aw, MSG_OK);
469 }
470 
471 uint8_t B15F::getMem8(volatile uint8_t* adr)
472 {
473  usart.clearInputBuffer();
474 
475  uint8_t rq[] =
476  {
477  RQ_GET_MEM_8,
478  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
479  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
480  };
481 
482  assertRequestLength(rq, RQ_GET_MEM_8);
483  usart.transmit(&rq[0], 0, sizeof(rq));
484 
485  uint8_t aw;
486  usart.receive(&aw, 0, sizeof(aw));
487  return aw;
488 }
489 
490 void B15F::setMem16(volatile uint16_t* adr, uint16_t val)
491 {
492  usart.clearInputBuffer();
493 
494  uint8_t rq[] =
495  {
496  RQ_SET_MEM_16,
497  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
498  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
499  static_cast<uint8_t >(val & 0xFF),
500  static_cast<uint8_t >(val >> 8)
501  };
502 
503  assertRequestLength(rq, RQ_SET_MEM_16);
504  usart.transmit(&rq[0], 0, sizeof(rq));
505 
506  uint16_t aw;
507  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
508  assertCode(aw, MSG_OK);
509 }
510 
511 uint16_t B15F::getMem16(volatile uint16_t* adr)
512 {
513  usart.clearInputBuffer();
514 
515  uint8_t rq[] =
516  {
517  RQ_GET_MEM_16,
518  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
519  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
520  };
521 
522  assertRequestLength(rq, RQ_GET_MEM_16);
523  usart.transmit(&rq[0], 0, sizeof(rq));
524 
525  uint16_t aw;
526  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
527  return aw;
528 }
529 
530 void B15F::setRegister(volatile uint8_t* adr, uint8_t val)
531 {
532  setMem8(adr, val);
533 }
534 
535 uint8_t B15F::getRegister(volatile uint8_t* adr)
536 {
537  return getMem8(adr);
538 }
539 
541 {
542  usart.clearInputBuffer();
543 
544  uint8_t rq[] =
545  {
546  RQ_COUNTER_OFFSET
547  };
548 
549  assertRequestLength(rq, RQ_COUNTER_OFFSET);
550  usart.transmit(&rq[0], 0, sizeof(rq));
551 
552  uint16_t aw;
553  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
554  return reinterpret_cast<uint16_t*>(aw);
555 }
556 
557 void B15F::setServoEnabled(void)
558 {
559  usart.clearInputBuffer();
560 
561  uint8_t rq[] =
562  {
563  RQ_SERVO_ENABLE
564  };
565 
566  assertRequestLength(rq, RQ_SERVO_ENABLE);
567  usart.transmit(&rq[0], 0, sizeof(rq));
568 
569  uint8_t aw;
570  usart.receive(&aw, 0, sizeof(aw));
571  assertCode(aw, MSG_OK);
572 }
573 
574 void B15F::setServoDisabled(void)
575 {
576  usart.clearInputBuffer();
577 
578  uint8_t rq[] =
579  {
580  RQ_SERVO_DISABLE
581  };
582 
583  assertRequestLength(rq, RQ_SERVO_DISABLE);
584  usart.transmit(&rq[0], 0, sizeof(rq));
585 
586  uint8_t aw;
587  usart.receive(&aw, 0, sizeof(aw));
588  assertCode(aw, MSG_OK);
589 }
590 
591 void B15F::setServoPosition(uint16_t pos)
592 {
593  if(pos > 19000)
594  throw DriverException("Impulslänge ist zu lang: " + std::to_string(pos));
595 
596  usart.clearInputBuffer();
597 
598  uint8_t rq[] =
599  {
600  RQ_SERVO_SET_POS,
601  static_cast<uint8_t >(pos & 0xFF),
602  static_cast<uint8_t >(pos >> 8)
603  };
604 
605  assertRequestLength(rq, RQ_SERVO_SET_POS);
606  usart.transmit(&rq[0], 0, sizeof(rq));
607 
608  uint8_t aw;
609  usart.receive(&aw, 0, sizeof(aw));
610  assertCode(aw, MSG_OK);
611 }
612 
613 /*************************/
614 
615 
616 /**********************
617  * Private Funktionen *
618  **********************/
619 
620 B15F::B15F()
621 {
622  init();
623 }
624 
625 
626 void B15F::init()
627 {
628 
629 #ifdef __arm__
630  // Raspberry Pi serial interface
631  std::string device = exec("bash -c 'ls /dev/ttyAMA* 2> /dev/null'");
632 #else
633  // normal PC serial interface
634  std::string device = exec("bash -c 'ls /dev/ttyUSB* 2> /dev/null'");
635 #endif
636 
637  while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos ||
638  device.find('\t') != std::string::npos)
639  device.pop_back();
640 
641  if (device.length() == 0)
642  abort("Adapter nicht gefunden");
643 
644  std::cout << PRE << "Verwende Adapter: " << device << std::endl;
645 
646 
647  std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush;
648  usart.setBaudrate(BAUDRATE);
649  usart.openDevice(device);
650  std::cout << "OK" << std::endl;
651 
652 
653  std::cout << PRE << "Teste Verbindung... " << std::flush;
654  int tries = 4;
655  while (--tries)
656  {
657  discard();
658 
659  try
660  {
661  testConnection();
662  }
663  catch(DriverException& eDE)
664  {
665  continue;
666  }
667 
668  try
669  {
670  testIntConv();
671  }
672  catch(DriverException& eDE)
673  {
674  continue;
675  }
676 
677  break;
678  }
679  if (!tries)
680  abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?");
681 
682  std::cout << "OK" << std::endl;
683 
684 
685  // Gib board info aus
686  std::vector<std::string> info = getBoardInfo();
687  std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")"
688  << std::endl;
689 
690  // Überprüfe Version
691  std::string& avr_commit_hash = info[3];
692  if(avr_commit_hash.compare(COMMIT_HASH))
693  {
694  std::cout << PRE << "Unterschiedliche commit hashes: " << std::endl;
695  std::cout << std::string(PRE.length(), ' ') << "AVR: " << avr_commit_hash << std::endl;
696  std::cout << std::string(PRE.length(), ' ') << "Control: " << COMMIT_HASH << std::endl << std::endl;
697  abort("Versionen inkompatibel. Bitte Software aktualisieren!");
698  }
699 }
-
void testIntConv(void)
Definition: b15f.cpp:83
-
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:431
-
static std::string exec(std::string cmd)
Definition: b15f.cpp:153
-
void analogWrite0(uint16_t port)
Definition: b15f.cpp:296
-
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:589
-
void analogWrite1(uint16_t port)
Definition: b15f.cpp:313
-
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:509
-
void delay_us(uint16_t us)
Definition: b15f.cpp:140
-
uint8_t digitalRead0(void)
Definition: b15f.cpp:245
-
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:410
-
void digitalWrite0(uint8_t)
Definition: b15f.cpp:213
-
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:353
-
uint8_t readDipSwitch(void)
Definition: b15f.cpp:277
-
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:533
-
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:469
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
+
1 #include "b15f.h"
2 
3 B15F *B15F::instance = nullptr;
4 errorhandler_t B15F::errorhandler = nullptr;
5 
6 
7 /*************************************
8  * Grundfunktionen des B15F Treibers *
9  *************************************/
10 
12 {
13  if (!instance)
14  instance = new B15F();
15 
16  return *instance;
17 }
18 
19 void B15F::reconnect()
20 {
21  uint8_t tries = RECONNECT_TRIES;
22  while (tries--)
23  {
25  discard();
26 
27  try
28  {
30  return; // no exceptionm means success
31  }
32  catch(DriverException& eDE)
33  {
34  // discard exception
35  }
36  }
37 
38  abort("Verbindung kann nicht repariert werden");
39 }
40 
41 void B15F::discard(void)
42 {
43  try
44  {
45  uint8_t rq[] =
46  {
47  RQ_DISCARD
48  };
49 
50  usart.clearOutputBuffer();
51  for (uint8_t i = 0; i < 16; i++)
52  {
53  usart.transmit(&rq[0], 0, sizeof(rq)); // sende discard Befehl (verwerfe input)
54  delay_ms(4);
55  }
56  usart.clearInputBuffer();
57  }
58  catch (std::exception &ex)
59  {
60  abort(ex);
61  }
62 }
63 
65 {
66  // erzeuge zufälliges Byte
67  srand(time(NULL));
68  uint8_t dummy = rand() % 256;
69 
70  uint8_t rq[] =
71  {
72  RQ_TEST,
73  dummy
74  };
75 
76  assertRequestLength(rq, RQ_TEST);
77  usart.transmit(&rq[0], 0, sizeof(rq));
78 
79  uint8_t aw[2];
80  usart.receive(&aw[0], 0, sizeof(aw));
81 
82  assertCode(aw[0], MSG_OK);
83  assertCode(aw[1], dummy);
84 }
85 
86 void B15F::testIntConv()
87 {
88  srand(time(NULL));
89  uint16_t dummy = rand() % (0xFFFF / 3);
90 
91  uint8_t rq[] =
92  {
93  RQ_INT_TEST,
94  static_cast<uint8_t >(dummy & 0xFF),
95  static_cast<uint8_t >(dummy >> 8)
96  };
97 
98  assertRequestLength(rq, RQ_INT_TEST);
99  usart.transmit(&rq[0], 0, sizeof(rq));
100 
101  uint16_t aw;
102  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
103 
104  assertCode(aw, dummy * 3);
105 }
106 
107 
108 std::vector<std::string> B15F::getBoardInfo(void)
109 {
110  std::vector<std::string> info;
111 
112  uint8_t rq[] =
113  {
114  RQ_INFO
115  };
116 
117  assertRequestLength(rq, RQ_INFO);
118  usart.transmit(&rq[0], 0, sizeof(rq));
119 
120  uint8_t n;
121  usart.receive(&n, 0, sizeof(n));
122  while (n--)
123  {
124  uint8_t len;
125  usart.receive(&len, 0, sizeof(len));
126 
127  char str[len + 1];
128  usart.receive(reinterpret_cast<uint8_t *>(&str[0]), 0, len);
129  str[len] = '\0';
130 
131  info.push_back(std::string(str));
132  }
133 
134  uint8_t aw;
135  usart.receive(&aw, 0, sizeof(aw));
136  if (aw != MSG_OK)
137  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
138 
139  return info;
140 }
141 
142 void B15F::delay_ms(uint16_t ms)
143 {
144  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
145 }
146 
147 void B15F::delay_us(uint16_t us)
148 {
149  std::this_thread::sleep_for(std::chrono::microseconds(us));
150 }
151 
152 void B15F::reverse(uint8_t& b)
153 {
154  b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
155  b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
156  b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
157 }
158 
159 // https://stackoverflow.com/a/478960
160 std::string B15F::exec(std::string cmd)
161 {
162  std::array<char, 128> buffer;
163  std::string result;
164  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
165  if (!pipe)
166  {
167  throw std::runtime_error("popen() failed!");
168  }
169  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
170  {
171  result += buffer.data();
172  }
173  return result;
174 }
175 
176 void B15F::abort(std::string msg)
177 {
178  DriverException ex(msg);
179  abort(ex);
180 }
181 
182 void B15F::abort(std::exception &ex)
183 {
184  if (errorhandler)
185  errorhandler(ex);
186  else
187  {
188  std::cout << ex.what() << std::endl;
189  throw DriverException(ex.what());
190  }
191 }
192 
193 void B15F::setAbortHandler(errorhandler_t func)
194 {
195  errorhandler = func;
196 }
197 
198 /*************************************/
199 
200 
201 
202 /*************************
203  * Steuerbefehle für B15 *
204  *************************/
205 
207 {
208  uint8_t rq[] =
209  {
210  RQ_SELF_TEST
211  };
212 
213  assertRequestLength(rq, RQ_SELF_TEST);
214  usart.transmit(&rq[0], 0, sizeof(rq));
215 
216  uint8_t aw;
217  usart.receive(&aw, 0, sizeof(aw));
218  assertCode(aw, MSG_OK);
219 }
220 
221 void B15F::digitalWrite0(uint8_t port)
222 {
223  uint8_t rq[] =
224  {
225  RQ_DIGITAL_WRITE_0,
226  port
227  };
228 
229  assertRequestLength(rq, RQ_DIGITAL_WRITE_0);
230  usart.transmit(&rq[0], 0, sizeof(rq));
231 
232  uint8_t aw;
233  usart.receive(&aw, 0, sizeof(aw));
234  assertCode(aw, MSG_OK);
235 }
236 
237 void B15F::digitalWrite1(uint8_t port)
238 {
239  uint8_t rq[] =
240  {
241  RQ_DIGITAL_WRITE_1,
242  port
243  };
244 
245  assertRequestLength(rq, RQ_DIGITAL_WRITE_1);
246  usart.transmit(&rq[0], 0, sizeof(rq));
247 
248  uint8_t aw;
249  usart.receive(&aw, 0, sizeof(aw));
250  assertCode(aw, MSG_OK);
251 }
252 
253 uint8_t B15F::digitalRead0()
254 {
255  usart.clearInputBuffer();
256  uint8_t rq[] =
257  {
258  RQ_DIGITAL_READ_0
259  };
260 
261  assertRequestLength(rq, RQ_DIGITAL_READ_0);
262  usart.transmit(&rq[0], 0, sizeof(rq));
263 
264  uint8_t aw;
265  usart.receive(&aw, 0, sizeof(aw));
266  return aw;
267 }
268 
269 uint8_t B15F::digitalRead1()
270 {
271  usart.clearInputBuffer();
272  uint8_t rq[] =
273  {
274  RQ_DIGITAL_READ_1
275  };
276 
277  assertRequestLength(rq, RQ_DIGITAL_READ_1);
278  usart.transmit(&rq[0], 0, sizeof(rq));
279 
280  uint8_t aw;
281  usart.receive(&aw, 0, sizeof(aw));
282  return aw;
283 }
284 
285 uint8_t B15F::readDipSwitch()
286 {
287  usart.clearInputBuffer();
288  uint8_t rq[] =
289  {
290  RQ_READ_DIP_SWITCH
291  };
292 
293  assertRequestLength(rq, RQ_READ_DIP_SWITCH);
294  usart.transmit(&rq[0], 0, sizeof(rq));
295 
296  uint8_t aw;
297  usart.receive(&aw, 0, sizeof(aw));
298 
299  reverse(aw); // DIP Schalter muss invertiert werden!
300 
301  return aw;
302 }
303 
304 void B15F::analogWrite0(uint16_t value)
305 {
306  uint8_t rq[] =
307  {
308  RQ_ANALOG_WRITE_0,
309  static_cast<uint8_t >(value & 0xFF),
310  static_cast<uint8_t >(value >> 8)
311  };
312 
313  assertRequestLength(rq, RQ_ANALOG_WRITE_0);
314  usart.transmit(&rq[0], 0, sizeof(rq));
315 
316  uint8_t aw;
317  usart.receive(&aw, 0, sizeof(aw));
318  assertCode(aw, MSG_OK);
319 }
320 
321 void B15F::analogWrite1(uint16_t value)
322 {
323  uint8_t rq[] =
324  {
325  RQ_ANALOG_WRITE_1,
326  static_cast<uint8_t >(value & 0xFF),
327  static_cast<uint8_t >(value >> 8)
328  };
329 
330  assertRequestLength(rq, RQ_ANALOG_WRITE_1);
331  usart.transmit(&rq[0], 0, sizeof(rq));
332 
333  uint8_t aw;
334  usart.receive(&aw, 0, sizeof(aw));
335  assertCode(aw, MSG_OK);
336 }
337 
338 uint16_t B15F::analogRead(uint8_t channel)
339 {
340  usart.clearInputBuffer();
341  if (channel > 7)
342  abort("Bad ADC channel: " + std::to_string(channel));
343 
344  uint8_t rq[] =
345  {
346  RQ_ANALOG_READ,
347  channel
348  };
349 
350  assertRequestLength(rq, RQ_ANALOG_READ);
351  usart.transmit(&rq[0], 0, sizeof(rq));
352 
353  uint16_t aw;
354  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
355 
356  if (aw > 1023)
357  abort("Bad ADC data detected (1)");
358  return aw;
359 }
360 
361 void B15F::analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b,
362  uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
363 {
364  // prepare pointers
365  buffer_a += offset_a;
366  buffer_b += offset_b;
367 
368 
369  usart.clearInputBuffer();
370  uint8_t rq[] =
371  {
372  RQ_ADC_DAC_STROKE,
373  channel_a,
374  channel_b,
375  static_cast<uint8_t >(start & 0xFF),
376  static_cast<uint8_t >(start >> 8),
377  static_cast<uint8_t >(delta & 0xFF),
378  static_cast<uint8_t >(delta >> 8),
379  static_cast<uint8_t >(count & 0xFF),
380  static_cast<uint8_t >(count >> 8)
381  };
382 
383  assertRequestLength(rq, RQ_ADC_DAC_STROKE);
384  usart.transmit(&rq[0], 0, sizeof(rq));
385 
386  for (uint16_t i = 0; i < count; i++)
387  {
388  if (buffer_a)
389  {
390  usart.receive(reinterpret_cast<uint8_t *>(&buffer_a[i]), 0, 2);
391 
392  if (buffer_a[i] > 1023) // check for broken usart connection
393  abort("Bad ADC data detected (2)");
394  }
395  else
396  {
397  usart.drop(2);
398  }
399 
400  if (buffer_b)
401  {
402  usart.receive(reinterpret_cast<uint8_t *>(&buffer_b[i]), 0, 2);
403 
404  if (buffer_b[i] > 1023) // check for broken usart connection
405  abort("Bad ADC data detected (3)");
406  }
407  else
408  {
409  usart.drop(2);
410  }
411  }
412 
413  uint8_t aw;
414  usart.receive(&aw, 0, sizeof(aw));
415  assertCode(aw, MSG_OK);
416 }
417 
418 uint8_t B15F::pwmSetFrequency(uint32_t freq)
419 {
420  usart.clearInputBuffer();
421 
422  uint8_t rq[] =
423  {
424  RQ_PWM_SET_FREQ,
425  static_cast<uint8_t>((freq >> 0) & 0xFF),
426  static_cast<uint8_t>((freq >> 8) & 0xFF),
427  static_cast<uint8_t>((freq >> 16) & 0xFF),
428  static_cast<uint8_t>((freq >> 24) & 0xFF)
429  };
430 
431  assertRequestLength(rq, RQ_PWM_SET_FREQ);
432  usart.transmit(&rq[0], 0, sizeof(rq));
433 
434  uint8_t aw;
435  usart.receive(&aw, 0, sizeof(aw));
436  return aw;
437 }
438 
439 void B15F::pwmSetValue(uint8_t value)
440 {
441  usart.clearInputBuffer();
442 
443  uint8_t rq[] =
444  {
445  RQ_PWM_SET_VALUE,
446  value
447  };
448 
449  assertRequestLength(rq, RQ_PWM_SET_VALUE);
450  usart.transmit(&rq[0], 0, sizeof(rq));
451 
452  uint8_t aw;
453  usart.receive(&aw, 0, sizeof(aw));
454  assertCode(aw, MSG_OK);
455 }
456 
457 void B15F::setMem8(volatile uint8_t* adr, uint8_t val)
458 {
459  usart.clearInputBuffer();
460 
461  uint8_t rq[] =
462  {
463  RQ_SET_MEM_8,
464  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
465  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
466  val
467  };
468 
469  assertRequestLength(rq, RQ_SET_MEM_8);
470  usart.transmit(&rq[0], 0, sizeof(rq));
471 
472  uint8_t aw;
473  usart.receive(&aw, 0, sizeof(aw));
474  assertCode(aw, MSG_OK);
475 }
476 
477 uint8_t B15F::getMem8(volatile uint8_t* adr)
478 {
479  usart.clearInputBuffer();
480 
481  uint8_t rq[] =
482  {
483  RQ_GET_MEM_8,
484  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
485  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
486  };
487 
488  assertRequestLength(rq, RQ_GET_MEM_8);
489  usart.transmit(&rq[0], 0, sizeof(rq));
490 
491  uint8_t aw;
492  usart.receive(&aw, 0, sizeof(aw));
493  return aw;
494 }
495 
496 void B15F::setMem16(volatile uint16_t* adr, uint16_t val)
497 {
498  usart.clearInputBuffer();
499 
500  uint8_t rq[] =
501  {
502  RQ_SET_MEM_16,
503  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
504  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8),
505  static_cast<uint8_t >(val & 0xFF),
506  static_cast<uint8_t >(val >> 8)
507  };
508 
509  assertRequestLength(rq, RQ_SET_MEM_16);
510  usart.transmit(&rq[0], 0, sizeof(rq));
511 
512  uint16_t aw;
513  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
514  assertCode(aw, MSG_OK);
515 }
516 
517 uint16_t B15F::getMem16(volatile uint16_t* adr)
518 {
519  usart.clearInputBuffer();
520 
521  uint8_t rq[] =
522  {
523  RQ_GET_MEM_16,
524  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) & 0xFF),
525  static_cast<uint8_t >(reinterpret_cast<size_t>(adr) >> 8)
526  };
527 
528  assertRequestLength(rq, RQ_GET_MEM_16);
529  usart.transmit(&rq[0], 0, sizeof(rq));
530 
531  uint16_t aw;
532  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
533  return aw;
534 }
535 
536 void B15F::setRegister(volatile uint8_t* adr, uint8_t val)
537 {
538  setMem8(adr, val);
539 }
540 
541 uint8_t B15F::getRegister(volatile uint8_t* adr)
542 {
543  return getMem8(adr);
544 }
545 
547 {
548  usart.clearInputBuffer();
549 
550  uint8_t rq[] =
551  {
552  RQ_COUNTER_OFFSET
553  };
554 
555  assertRequestLength(rq, RQ_COUNTER_OFFSET);
556  usart.transmit(&rq[0], 0, sizeof(rq));
557 
558  uint16_t aw;
559  usart.receive(reinterpret_cast<uint8_t *>(&aw), 0, sizeof(aw));
560  return reinterpret_cast<uint16_t*>(aw);
561 }
562 
563 void B15F::setServoEnabled(void)
564 {
565  usart.clearInputBuffer();
566 
567  uint8_t rq[] =
568  {
569  RQ_SERVO_ENABLE
570  };
571 
572  assertRequestLength(rq, RQ_SERVO_ENABLE);
573  usart.transmit(&rq[0], 0, sizeof(rq));
574 
575  uint8_t aw;
576  usart.receive(&aw, 0, sizeof(aw));
577  assertCode(aw, MSG_OK);
578 }
579 
580 void B15F::setServoDisabled(void)
581 {
582  usart.clearInputBuffer();
583 
584  uint8_t rq[] =
585  {
586  RQ_SERVO_DISABLE
587  };
588 
589  assertRequestLength(rq, RQ_SERVO_DISABLE);
590  usart.transmit(&rq[0], 0, sizeof(rq));
591 
592  uint8_t aw;
593  usart.receive(&aw, 0, sizeof(aw));
594  assertCode(aw, MSG_OK);
595 }
596 
597 void B15F::setServoPosition(uint16_t pos)
598 {
599  if(pos > 19000)
600  throw DriverException("Impulslänge ist zu lang: " + std::to_string(pos));
601 
602  usart.clearInputBuffer();
603 
604  uint8_t rq[] =
605  {
606  RQ_SERVO_SET_POS,
607  static_cast<uint8_t >(pos & 0xFF),
608  static_cast<uint8_t >(pos >> 8)
609  };
610 
611  assertRequestLength(rq, RQ_SERVO_SET_POS);
612  usart.transmit(&rq[0], 0, sizeof(rq));
613 
614  uint8_t aw;
615  usart.receive(&aw, 0, sizeof(aw));
616  assertCode(aw, MSG_OK);
617 }
618 
619 /*************************/
620 
621 
622 /**********************
623  * Private Funktionen *
624  **********************/
625 
626 B15F::B15F()
627 {
628  init();
629 }
630 
631 
632 void B15F::init()
633 {
634 
635 #ifdef __arm__
636  // Raspberry Pi serial interface
637  std::string device = exec("bash -c 'ls /dev/ttyAMA* 2> /dev/null'");
638 #else
639  // normal PC serial interface
640  std::string device = exec("bash -c 'ls /dev/ttyUSB* 2> /dev/null'");
641 #endif
642 
643  while (device.find(' ') != std::string::npos || device.find('\n') != std::string::npos ||
644  device.find('\t') != std::string::npos)
645  device.pop_back();
646 
647  if (device.length() == 0)
648  abort("Adapter nicht gefunden");
649 
650  std::cout << PRE << "Verwende Adapter: " << device << std::endl;
651 
652 
653  std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush;
654  usart.setBaudrate(BAUDRATE);
655  usart.openDevice(device);
656  std::cout << "OK" << std::endl;
657 
658 
659  std::cout << PRE << "Teste Verbindung... " << std::flush;
660  int tries = 4;
661  while (--tries)
662  {
663  discard();
664 
665  try
666  {
667  testConnection();
668  }
669  catch(DriverException& eDE)
670  {
671  continue;
672  }
673 
674  try
675  {
676  testIntConv();
677  }
678  catch(DriverException& eDE)
679  {
680  continue;
681  }
682 
683  break;
684  }
685  if (!tries)
686  abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?");
687 
688  std::cout << "OK" << std::endl;
689 
690 
691  // Gib board info aus
692  std::vector<std::string> info = getBoardInfo();
693  std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")"
694  << std::endl;
695 
696  // Überprüfe Version
697  std::string& avr_commit_hash = info[3];
698  if(avr_commit_hash.compare(COMMIT_HASH))
699  {
700  std::cout << PRE << "Unterschiedliche commit hashes: " << std::endl;
701  std::cout << std::string(PRE.length(), ' ') << "AVR: " << avr_commit_hash << std::endl;
702  std::cout << std::string(PRE.length(), ' ') << "Control: " << COMMIT_HASH << std::endl << std::endl;
703  abort("Versionen inkompatibel. Bitte Software aktualisieren!");
704  }
705 }
+
void testIntConv(void)
Definition: b15f.cpp:85
+
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:437
+
static std::string exec(std::string cmd)
Definition: b15f.cpp:159
+
void analogWrite0(uint16_t port)
Definition: b15f.cpp:302
+
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:595
+
void analogWrite1(uint16_t port)
Definition: b15f.cpp:319
+
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:515
+
void delay_us(uint16_t us)
Definition: b15f.cpp:146
+
uint8_t digitalRead0(void)
Definition: b15f.cpp:251
+
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:416
+
void digitalWrite0(uint8_t)
Definition: b15f.cpp:219
+
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:359
+
uint8_t readDipSwitch(void)
Definition: b15f.cpp:283
+
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:539
+
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:475
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:141
void testConnection(void)
Definition: b15f.cpp:63
static B15F & getInstance(void)
Definition: b15f.cpp:10
Definition: b15f.h:38
void transmit(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:75
-
static void abort(std::string msg)
Definition: b15f.cpp:169
+
static void abort(std::string msg)
Definition: b15f.cpp:175
void receive(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:84
void clearInputBuffer(void)
Definition: usart.cpp:54
-
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:538
-
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:488
+
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:544
+
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:494
void clearOutputBuffer(void)
Definition: usart.cpp:61
-
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:330
-
void activateSelfTestMode(void)
Definition: b15f.cpp:198
+
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:336
+
void activateSelfTestMode(void)
Definition: b15f.cpp:204
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:310
-
void reverse(uint8_t &b)
Definition: b15f.cpp:145
+
void reverse(uint8_t &b)
Definition: b15f.cpp:151
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:131
-
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:103
+
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:107
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:313
void discard(void)
Definition: b15f.cpp:40
-
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:528
+
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:534
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:311
void openDevice(std::string device)
Definition: usart.cpp:9
-
uint8_t digitalRead1(void)
Definition: b15f.cpp:261
+
uint8_t digitalRead1(void)
Definition: b15f.cpp:267
void reconnect(void)
Definition: b15f.cpp:18
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:316
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:192
void drop(uint8_t len)
Definition: usart.cpp:114
-
void digitalWrite1(uint8_t)
Definition: b15f.cpp:229
-
void setServoEnabled(void)
Definition: b15f.cpp:555
+
void digitalWrite1(uint8_t)
Definition: b15f.cpp:235
+
void setServoEnabled(void)
Definition: b15f.cpp:561
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:315
-
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:449
-
void setServoDisabled(void)
Definition: b15f.cpp:572
+
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:455
+
void setServoDisabled(void)
Definition: b15f.cpp:578
diff --git a/docs/html/b15f_8h_source.html b/docs/html/b15f_8h_source.html index 72c751e..c9c37f0 100644 --- a/docs/html/b15f_8h_source.html +++ b/docs/html/b15f_8h_source.html @@ -71,53 +71,53 @@ $(function() {
1 #ifndef B15F_H
2 #define B15F_H
3 
4 #include <iostream>
5 #include <bits/stdc++.h>
6 #include <string>
7 #include <fstream>
8 #include <cstdlib>
9 #include <chrono>
10 #include <cstdint>
11 #include <vector>
12 
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <sys/ioctl.h>
16 #include <termios.h>
17 
18 #include "commit_hash.h"
19 #include "requests.h"
20 #include "usart.h"
21 #include "driverexception.h"
22 #include "timeoutexception.h"
23 
24 // wichtig für die Register-Zugriffe
25 #define _AVR_IO_H_ 1 // Erzwinge die Inklusion
26 #include "/usr/lib/avr/include/avr/sfr_defs.h"
27 #include "/usr/lib/avr/include/avr/iom1284p.h"
28 
29 typedef std::function<void(std::exception&)> errorhandler_t;
30 
31 // Wrapper für Codeposition-Ersetzung
32 #define assertCode(code, expectation) assertCodeFunc(code, expectation, &__FUNCTION__[0], &__FILE__[0], __LINE__)
33 #define assertRequestLength(rq, rq_num) assertRequestLengthFunc(rq, rq_num,& __FUNCTION__[0], &__FILE__[0], __LINE__)
34 
35 
38 class B15F
39 {
40 public:
41 
42  /*************************************
43  * Grundfunktionen des B15F Treibers *
44  *************************************/
45 
50  static B15F& getInstance(void);
51 
56  void reconnect(void);
57 
62  void discard(void);
63 
68  void testConnection(void);
69 
74  void testIntConv(void);
75 
80  std::vector<std::string> getBoardInfo(void);
81 
86  void delay_ms(uint16_t ms);
87 
92  void delay_us(uint16_t us);
93 
99  void reverse(uint8_t& b);
100 
105  static std::string exec(std::string cmd);
106 
111  static void abort(std::string msg);
112 
117  static void abort(std::exception& ex);
118 
123  static void setAbortHandler(errorhandler_t func);
124 
125  /*************************************/
126 
127 
128 
129  /*************************
130  * Steuerbefehle für B15 *
131  *************************/
132 
138  void activateSelfTestMode(void);
139 
145  void digitalWrite0(uint8_t);
146 
152  void digitalWrite1(uint8_t);
153 
159  uint8_t digitalRead0(void);
160 
166  uint8_t digitalRead1(void);
167 
173  uint8_t readDipSwitch(void);
174 
180  void analogWrite0(uint16_t port);
181 
187  void analogWrite1(uint16_t port);
188 
194  uint16_t analogRead(uint8_t channel);
195 
211  void analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t* buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count);
212 
222  uint8_t pwmSetFrequency(uint32_t freq);
223 
229  void pwmSetValue(uint8_t value);
230 
239  void setMem8(volatile uint8_t* adr, uint8_t val);
240 
247  uint8_t getMem8(volatile uint8_t* adr);
248 
257  void setMem16(volatile uint16_t* adr, uint16_t val);
258 
265  uint16_t getMem16(volatile uint16_t* adr);
266 
274  void setRegister(volatile uint8_t* adr, uint8_t val);
275 
281  uint8_t getRegister(volatile uint8_t* adr);
282 
287  uint16_t* getInterruptCounterOffset(void);
288 
293  void setServoEnabled(void);
294 
299  void setServoDisabled(void);
300 
306  void setServoPosition(uint16_t pos);
307 
308  /*************************/
309 
310 
311  // CONSTANTS
312  const std::string PRE = "[B15F] ";
313  constexpr static uint8_t MSG_OK = 0xFF;
314  constexpr static uint8_t MSG_FAIL = 0xFE;
315  constexpr static uint16_t RECONNECT_TIMEOUT = 64;
316  constexpr static uint16_t WDT_TIMEOUT = 15;
317  constexpr static uint8_t RECONNECT_TRIES = 3;
318  constexpr static uint32_t BAUDRATE = 57600;
319 
320 private:
321 
325  B15F(void);
326 
331  void init(void);
332 
338  template<typename CodeType, typename ExpectationType>
339  void assertCodeFunc(CodeType& code, ExpectationType expectation, const char* func, const char* file, int line) const
340  {
341  if(code != static_cast<CodeType>(expectation))
342  throw DriverException("Ungültige Antwort erhalten: " + std::to_string((int) code) + " (erwartet: " + std::to_string((int) expectation) + ") in " + std::string(func) + ": " + std::string(file) + "#" + std::to_string(line));
343  }
344 
350  template<size_t RequestLength>
351  void assertRequestLengthFunc(uint8_t (&)[RequestLength], uint8_t rq_num, const char* func, const char* file, int line)
352  {
353  if(RequestLength != rq_len[rq_num])
354  throw DriverException("Ungültige Request Länge: " + std::to_string(RequestLength) + " (erwartet: " + std::to_string(rq_len[rq_num]) + ") in " + std::string(func) + ": " + std::string(file) + "#" + std::to_string(line));
355  }
356 
357  USART usart;
358  static B15F* instance;
359  static errorhandler_t errorhandler;
360 };
361 
362 #endif // B15F_H
-
void testIntConv(void)
Definition: b15f.cpp:83
-
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:431
-
static std::string exec(std::string cmd)
Definition: b15f.cpp:153
+
void testIntConv(void)
Definition: b15f.cpp:85
+
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:437
+
static std::string exec(std::string cmd)
Definition: b15f.cpp:159
constexpr static uint8_t MSG_FAIL
Value to reject a received command.
Definition: b15f.h:312
-
void analogWrite0(uint16_t port)
Definition: b15f.cpp:296
-
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:589
-
void analogWrite1(uint16_t port)
Definition: b15f.cpp:313
-
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:509
-
void delay_us(uint16_t us)
Definition: b15f.cpp:140
-
uint8_t digitalRead0(void)
Definition: b15f.cpp:245
-
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:410
-
void digitalWrite0(uint8_t)
Definition: b15f.cpp:213
-
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:353
-
uint8_t readDipSwitch(void)
Definition: b15f.cpp:277
-
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:533
-
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:469
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
+
void analogWrite0(uint16_t port)
Definition: b15f.cpp:302
+
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:595
+
void analogWrite1(uint16_t port)
Definition: b15f.cpp:319
+
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:515
+
void delay_us(uint16_t us)
Definition: b15f.cpp:146
+
uint8_t digitalRead0(void)
Definition: b15f.cpp:251
+
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:416
+
void digitalWrite0(uint8_t)
Definition: b15f.cpp:219
+
void analogSequence(uint8_t channel_a, uint16_t *buffer_a, uint32_t offset_a, uint8_t channel_b, uint16_t *buffer_b, uint32_t offset_b, uint16_t start, int16_t delta, uint16_t count)
Definition: b15f.cpp:359
+
uint8_t readDipSwitch(void)
Definition: b15f.cpp:283
+
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:539
+
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:475
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:141
void testConnection(void)
Definition: b15f.cpp:63
static B15F & getInstance(void)
Definition: b15f.cpp:10
Definition: b15f.h:38
-
static void abort(std::string msg)
Definition: b15f.cpp:169
-
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:538
+
static void abort(std::string msg)
Definition: b15f.cpp:175
+
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:544
Definition: usart.h:16
-
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:488
-
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:330
-
void activateSelfTestMode(void)
Definition: b15f.cpp:198
+
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:494
+
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:336
+
void activateSelfTestMode(void)
Definition: b15f.cpp:204
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:310
-
void reverse(uint8_t &b)
Definition: b15f.cpp:145
-
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:103
+
void reverse(uint8_t &b)
Definition: b15f.cpp:151
+
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:107
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:313
void discard(void)
Definition: b15f.cpp:40
-
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:528
+
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:534
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:311
-
uint8_t digitalRead1(void)
Definition: b15f.cpp:261
+
uint8_t digitalRead1(void)
Definition: b15f.cpp:267
constexpr static uint16_t WDT_TIMEOUT
Time in ms after which the watch dog timer resets the MCU.
Definition: b15f.h:314
void reconnect(void)
Definition: b15f.cpp:18
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:316
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
-
void digitalWrite1(uint8_t)
Definition: b15f.cpp:229
-
void setServoEnabled(void)
Definition: b15f.cpp:555
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:192
+
void digitalWrite1(uint8_t)
Definition: b15f.cpp:235
+
void setServoEnabled(void)
Definition: b15f.cpp:561
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:315
-
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:449
-
void setServoDisabled(void)
Definition: b15f.cpp:572
+
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:455
+
void setServoDisabled(void)
Definition: b15f.cpp:578
diff --git a/docs/html/classB15F-members.html b/docs/html/classB15F-members.html index 9664079..f0a81b4 100644 --- a/docs/html/classB15F-members.html +++ b/docs/html/classB15F-members.html @@ -114,7 +114,7 @@ $(function() { diff --git a/docs/html/classB15F.html b/docs/html/classB15F.html index 2fea9d4..8dd4758 100644 --- a/docs/html/classB15F.html +++ b/docs/html/classB15F.html @@ -220,7 +220,7 @@ constexpr static uint32_t  -

Definition at line 175 of file b15f.cpp.

+

Definition at line 181 of file b15f.cpp.

@@ -254,7 +254,7 @@ constexpr static uint32_t  -

Definition at line 169 of file b15f.cpp.

+

Definition at line 175 of file b15f.cpp.

@@ -280,7 +280,7 @@ constexpr static uint32_t  -

Definition at line 198 of file b15f.cpp.

+

Definition at line 204 of file b15f.cpp.

@@ -312,7 +312,7 @@ constexpr static uint32_t  -

Definition at line 330 of file b15f.cpp.

+

Definition at line 336 of file b15f.cpp.

@@ -404,7 +404,7 @@ constexpr static uint32_t  -

Definition at line 353 of file b15f.cpp.

+

Definition at line 359 of file b15f.cpp.

@@ -436,7 +436,7 @@ constexpr static uint32_t  -

Definition at line 296 of file b15f.cpp.

+

Definition at line 302 of file b15f.cpp.

@@ -468,7 +468,7 @@ constexpr static uint32_t  -

Definition at line 313 of file b15f.cpp.

+

Definition at line 319 of file b15f.cpp.

@@ -494,7 +494,7 @@ constexpr static uint32_t  -

Definition at line 135 of file b15f.cpp.

+

Definition at line 141 of file b15f.cpp.

@@ -520,7 +520,7 @@ constexpr static uint32_t  -

Definition at line 140 of file b15f.cpp.

+

Definition at line 146 of file b15f.cpp.

@@ -547,7 +547,7 @@ constexpr static uint32_t  -

Definition at line 245 of file b15f.cpp.

+

Definition at line 251 of file b15f.cpp.

@@ -574,7 +574,7 @@ constexpr static uint32_t  -

Definition at line 261 of file b15f.cpp.

+

Definition at line 267 of file b15f.cpp.

@@ -606,7 +606,7 @@ constexpr static uint32_t  -

Definition at line 213 of file b15f.cpp.

+

Definition at line 219 of file b15f.cpp.

@@ -638,7 +638,7 @@ constexpr static uint32_t  -

Definition at line 229 of file b15f.cpp.

+

Definition at line 235 of file b15f.cpp.

@@ -698,7 +698,7 @@ constexpr static uint32_t  -

Definition at line 153 of file b15f.cpp.

+

Definition at line 159 of file b15f.cpp.

@@ -724,7 +724,7 @@ constexpr static uint32_t  -

Definition at line 103 of file b15f.cpp.

+

Definition at line 107 of file b15f.cpp.

@@ -779,7 +779,7 @@ constexpr static uint32_t  @@ -806,7 +806,7 @@ constexpr static uint32_t 
Returns
Wert der Speicherzelle
-

Definition at line 509 of file b15f.cpp.

+

Definition at line 515 of file b15f.cpp.

@@ -833,7 +833,7 @@ constexpr static uint32_t 
Returns
Wert der Speicherzelle
-

Definition at line 469 of file b15f.cpp.

+

Definition at line 475 of file b15f.cpp.

@@ -860,7 +860,7 @@ constexpr static uint32_t 
Returns
Wert des Registers
-

Definition at line 533 of file b15f.cpp.

+

Definition at line 539 of file b15f.cpp.

@@ -893,7 +893,7 @@ constexpr static uint32_t  -

Definition at line 410 of file b15f.cpp.

+

Definition at line 416 of file b15f.cpp.

@@ -925,7 +925,7 @@ constexpr static uint32_t  -

Definition at line 431 of file b15f.cpp.

+

Definition at line 437 of file b15f.cpp.

@@ -952,7 +952,7 @@ constexpr static uint32_t  -

Definition at line 277 of file b15f.cpp.

+

Definition at line 283 of file b15f.cpp.

@@ -1004,7 +1004,7 @@ constexpr static uint32_t  -

Definition at line 145 of file b15f.cpp.

+

Definition at line 151 of file b15f.cpp.

@@ -1038,7 +1038,7 @@ constexpr static uint32_t  -

Definition at line 186 of file b15f.cpp.

+

Definition at line 192 of file b15f.cpp.

@@ -1081,7 +1081,7 @@ constexpr static uint32_t  -

Definition at line 488 of file b15f.cpp.

+

Definition at line 494 of file b15f.cpp.

@@ -1119,7 +1119,7 @@ constexpr static uint32_t 
Returns
true, falls Vorgang erfolgreich
-

Definition at line 449 of file b15f.cpp.

+

Definition at line 455 of file b15f.cpp.

@@ -1162,7 +1162,7 @@ constexpr static uint32_t  -

Definition at line 528 of file b15f.cpp.

+

Definition at line 534 of file b15f.cpp.

@@ -1188,7 +1188,7 @@ constexpr static uint32_t  -

Definition at line 572 of file b15f.cpp.

+

Definition at line 578 of file b15f.cpp.

@@ -1214,7 +1214,7 @@ constexpr static uint32_t  -

Definition at line 555 of file b15f.cpp.

+

Definition at line 561 of file b15f.cpp.

@@ -1246,7 +1246,7 @@ constexpr static uint32_t  -

Definition at line 589 of file b15f.cpp.

+

Definition at line 595 of file b15f.cpp.

@@ -1298,7 +1298,7 @@ constexpr static uint32_t  -

Definition at line 83 of file b15f.cpp.

+

Definition at line 85 of file b15f.cpp.

@@ -1309,7 +1309,7 @@ constexpr static uint32_t  diff --git a/docs/html/classDot-members.html b/docs/html/classDot-members.html index 4786d83..26d9db2 100644 --- a/docs/html/classDot-members.html +++ b/docs/html/classDot-members.html @@ -76,7 +76,7 @@ $(function() { diff --git a/docs/html/classDot.html b/docs/html/classDot.html index 65612a5..4499d6a 100644 --- a/docs/html/classDot.html +++ b/docs/html/classDot.html @@ -196,7 +196,7 @@ Public Member Functions diff --git a/docs/html/classDriverException-members.html b/docs/html/classDriverException-members.html index 10c1b75..06da3e4 100644 --- a/docs/html/classDriverException-members.html +++ b/docs/html/classDriverException-members.html @@ -77,7 +77,7 @@ $(function() { diff --git a/docs/html/classDriverException.html b/docs/html/classDriverException.html index a9fefb8..5b1ea4f 100644 --- a/docs/html/classDriverException.html +++ b/docs/html/classDriverException.html @@ -109,7 +109,7 @@ std::string msg_< diff --git a/docs/html/classPlottyFile-members.html b/docs/html/classPlottyFile-members.html index 9b4d8d7..cdb09fc 100644 --- a/docs/html/classPlottyFile-members.html +++ b/docs/html/classPlottyFile-members.html @@ -100,7 +100,7 @@ $(function() { diff --git a/docs/html/classPlottyFile.html b/docs/html/classPlottyFile.html index 6cd1eac..084762a 100644 --- a/docs/html/classPlottyFile.html +++ b/docs/html/classPlottyFile.html @@ -811,7 +811,7 @@ Public Member Functions diff --git a/docs/html/classTimeoutException-members.html b/docs/html/classTimeoutException-members.html index 7836524..5a91fa0 100644 --- a/docs/html/classTimeoutException-members.html +++ b/docs/html/classTimeoutException-members.html @@ -77,7 +77,7 @@ $(function() { diff --git a/docs/html/classTimeoutException.html b/docs/html/classTimeoutException.html index 3f0d010..f04b7f4 100644 --- a/docs/html/classTimeoutException.html +++ b/docs/html/classTimeoutException.html @@ -239,7 +239,7 @@ std::string  diff --git a/docs/html/classUSART-members.html b/docs/html/classUSART-members.html index e4ff867..27675fc 100644 --- a/docs/html/classUSART-members.html +++ b/docs/html/classUSART-members.html @@ -86,7 +86,7 @@ $(function() { diff --git a/docs/html/classUSART.html b/docs/html/classUSART.html index 01f7ce6..ea3cec9 100644 --- a/docs/html/classUSART.html +++ b/docs/html/classUSART.html @@ -523,7 +523,7 @@ Public Member Functions diff --git a/docs/html/classUSARTException-members.html b/docs/html/classUSARTException-members.html index 5b1c786..348e435 100644 --- a/docs/html/classUSARTException-members.html +++ b/docs/html/classUSARTException-members.html @@ -77,7 +77,7 @@ $(function() { diff --git a/docs/html/classUSARTException.html b/docs/html/classUSARTException.html index 9fa1175..f8b0fc7 100644 --- a/docs/html/classUSARTException.html +++ b/docs/html/classUSARTException.html @@ -239,7 +239,7 @@ std::string  diff --git a/docs/html/classView-members.html b/docs/html/classView-members.html index 9ba325e..0d7c3fe 100644 --- a/docs/html/classView-members.html +++ b/docs/html/classView-members.html @@ -89,7 +89,7 @@ $(function() { diff --git a/docs/html/classView.html b/docs/html/classView.html index 8ecc82e..8debb8f 100644 --- a/docs/html/classView.html +++ b/docs/html/classView.html @@ -157,7 +157,7 @@ constexpr static int KEY_E diff --git a/docs/html/classViewInfo-members.html b/docs/html/classViewInfo-members.html index 88d6156..1ae3f69 100644 --- a/docs/html/classViewInfo-members.html +++ b/docs/html/classViewInfo-members.html @@ -99,7 +99,7 @@ $(function() { diff --git a/docs/html/classViewInfo.html b/docs/html/classViewInfo.html index 5b8d953..f35e741 100644 --- a/docs/html/classViewInfo.html +++ b/docs/html/classViewInfo.html @@ -185,7 +185,7 @@ static std::vector< std::string >  diff --git a/docs/html/classViewMonitor-members.html b/docs/html/classViewMonitor-members.html index 35087e1..71a6c74 100644 --- a/docs/html/classViewMonitor-members.html +++ b/docs/html/classViewMonitor-members.html @@ -103,7 +103,7 @@ $(function() { diff --git a/docs/html/classViewMonitor.html b/docs/html/classViewMonitor.html index 6540876..9e1d556 100644 --- a/docs/html/classViewMonitor.html +++ b/docs/html/classViewMonitor.html @@ -197,7 +197,7 @@ constexpr static int KEY_E diff --git a/docs/html/classViewPromt-members.html b/docs/html/classViewPromt-members.html index 6c8b55b..60d9323 100644 --- a/docs/html/classViewPromt-members.html +++ b/docs/html/classViewPromt-members.html @@ -105,7 +105,7 @@ $(function() { diff --git a/docs/html/classViewPromt.html b/docs/html/classViewPromt.html index d3b4acb..440adab 100644 --- a/docs/html/classViewPromt.html +++ b/docs/html/classViewPromt.html @@ -205,7 +205,7 @@ static std::vector< std::string >  diff --git a/docs/html/classViewSelection-members.html b/docs/html/classViewSelection-members.html index cb4eeae..12df272 100644 --- a/docs/html/classViewSelection-members.html +++ b/docs/html/classViewSelection-members.html @@ -94,7 +94,7 @@ $(function() { diff --git a/docs/html/classViewSelection.html b/docs/html/classViewSelection.html index b3c1ddf..a674efc 100644 --- a/docs/html/classViewSelection.html +++ b/docs/html/classViewSelection.html @@ -172,7 +172,7 @@ static std::vector< std::string >  diff --git a/docs/html/classes.html b/docs/html/classes.html index 3e7be3a..0380d18 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -105,7 +105,7 @@ $(function() { diff --git a/docs/html/cli_8cpp_source.html b/docs/html/cli_8cpp_source.html index c96199c..c9f7cd6 100644 --- a/docs/html/cli_8cpp_source.html +++ b/docs/html/cli_8cpp_source.html @@ -69,10 +69,10 @@ $(function() {
1 //#define B15F_CLI_DEBUG
2 
3 #include <stdio.h>
4 #include <ncurses.h> // sudo apt-get install libncurses5-dev
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 #include <signal.h>
9 #include <sys/ioctl.h>
10 #include <unistd.h>
11 #include <signal.h>
12 #include <future>
13 #include <thread>
14 #include <chrono>
15 #include "drv/b15f.h"
16 #include "ui/ui.h"
17 #include "ui/view_selection.h"
18 #include "ui/view_info.h"
19 #include "ui/view_monitor.h"
20 #include "ui/view_promt.h"
21 
22 constexpr uint8_t WIN_WIDTH = 80;
23 constexpr uint8_t WIN_HEIGHT = 24;
24 
25 volatile int win_changed_cooldown = 0;
26 volatile bool t_refresh_active = false;
27 
28 void signal_handler(int signal)
29 {
30  if(signal == SIGWINCH)
31  {
32  win_changed_cooldown = 10; // 100ms
33 
34  if (!t_refresh_active)
35  {
36  if(t_refresh.joinable())
37  t_refresh.join();
38  t_refresh_active = true;
39  t_refresh = std::thread([]()
40  {
41 
42  while(win_changed_cooldown--)
43  std::this_thread::sleep_for(std::chrono::milliseconds(10));
44 
45  t_refresh_active = false;
46 
47  if(win_stack.size())
48  win_stack.back()->repaint();
49 
50  });
51  }
52 
53  }
54  else if(signal == SIGINT)
55  {
56  cleanup();
57  std::cout << "SIGINT - Abbruch." << std::endl;
58  exit(EXIT_FAILURE);
59  }
60 }
61 
62 void abort_handler(std::exception& ex)
63 {
64  ViewInfo* view = new ViewInfo();
65  view->setTitle("Fehler");
66  std::string msg(ex.what());
67  msg += "\n\nBeende in 5 Sekunden.";
68  view->setText(msg.c_str());
69  view->setLabelClose("");
70  view->repaint();
71 
72  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
73 
74  cleanup();
75  std::cerr << std::endl << "*** EXCEPTION ***" << std::endl << ex.what() << std::endl;
76  exit(EXIT_FAILURE);
77 }
78 
79 void init()
80 {
81  // init b15 driver
83 #ifndef B15F_CLI_DEBUG
84  std::cout << std::endl << "Starte in 3s ..." << std::endl;
85  sleep(3);
86 #endif
87 
88  // init all ncurses stuff
89  initscr();
90  start_color();
91  curs_set(0); // 0: invisible, 1: normal, 2: very visible
92  clear();
93  noecho();
94  cbreak(); // Line buffering disabled. pass on everything
95  mousemask(ALL_MOUSE_EVENTS, NULL);
96 
97  // connect signals to handler
98  signal(SIGWINCH, signal_handler);
99  signal(SIGINT, signal_handler);
100 
101  // set view context
102  View::setWinContext(newwin(WIN_HEIGHT, WIN_WIDTH, 0, 0));
103 
104  // set graphical error handler
105  B15F::setAbortHandler(&abort_handler);
106 }
107 
108 
109 int main()
110 {
111  init();
112 
113  int exit_code = EXIT_SUCCESS;
114 
115  show_main(0);
116 
117  cleanup();
118 
119  return exit_code;
120 }
static B15F & getInstance(void)
Definition: b15f.cpp:10
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:192
diff --git a/docs/html/commit__hash_8h_source.html b/docs/html/commit__hash_8h_source.html index 7bb89be..e19add4 100644 --- a/docs/html/commit__hash_8h_source.html +++ b/docs/html/commit__hash_8h_source.html @@ -69,7 +69,7 @@ $(function() {
1 #ifndef COMMIT_HASH_H
2 #define COMMIT_HASH_H
3 const char COMMIT_HASH[] = "a43c1610917fa01cb5fb07edbb2090d01fb846f7";
4 #endif // COMMIT_HASH_H
diff --git a/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html b/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html index b724d94..370ef68 100644 --- a/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html +++ b/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html @@ -73,7 +73,7 @@ $(function() { diff --git a/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html b/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html index 72ac5bc..0c7cdb7 100644 --- a/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html +++ b/docs/html/dir_587c94d866dbb2f408f78cf41f9b2f8d.html @@ -73,7 +73,7 @@ $(function() { diff --git a/docs/html/dot_8cpp_source.html b/docs/html/dot_8cpp_source.html index 6e9771e..76a8080 100644 --- a/docs/html/dot_8cpp_source.html +++ b/docs/html/dot_8cpp_source.html @@ -77,7 +77,7 @@ $(function() {
Dot(uint16_t x, uint16_t y, uint8_t curve)
Definition: dot.cpp:3
diff --git a/docs/html/dot_8h_source.html b/docs/html/dot_8h_source.html index 3750aa8..eda8126 100644 --- a/docs/html/dot_8h_source.html +++ b/docs/html/dot_8h_source.html @@ -78,7 +78,7 @@ $(function() {
Dot(uint16_t x, uint16_t y, uint8_t curve)
Definition: dot.cpp:3
diff --git a/docs/html/driverexception_8h_source.html b/docs/html/driverexception_8h_source.html index 1eec841..1bd596c 100644 --- a/docs/html/driverexception_8h_source.html +++ b/docs/html/driverexception_8h_source.html @@ -74,7 +74,7 @@ $(function() { diff --git a/docs/html/drv_2commit__hash_8h_source.html b/docs/html/drv_2commit__hash_8h_source.html index 044f9af..9f9a510 100644 --- a/docs/html/drv_2commit__hash_8h_source.html +++ b/docs/html/drv_2commit__hash_8h_source.html @@ -70,10 +70,10 @@ $(function() {
commit_hash.h
-
1 #ifndef COMMIT_HASH_H
2 #define COMMIT_HASH_H
3 const char COMMIT_HASH[] = "018bd1057deef81d8a44a808b7c68fb29abc3be6";
4 #endif // COMMIT_HASH_H
+
1 #ifndef COMMIT_HASH_H
2 #define COMMIT_HASH_H
3 const char COMMIT_HASH[] = "6dff81fb75d39a4b063b6c8a1cb98a9aff0c3669";
4 #endif // COMMIT_HASH_H
diff --git a/docs/html/files.html b/docs/html/files.html index 833f4f7..b885b79 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -102,7 +102,7 @@ $(function() { diff --git a/docs/html/functions.html b/docs/html/functions.html index 3d33420..fa905d3 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -407,7 +407,7 @@ $(function() { diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html index d2cad70..200ada7 100644 --- a/docs/html/functions_func.html +++ b/docs/html/functions_func.html @@ -374,7 +374,7 @@ $(function() { diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html index 7e07809..09374c0 100644 --- a/docs/html/functions_vars.html +++ b/docs/html/functions_vars.html @@ -92,7 +92,7 @@ $(function() { diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html index 6244661..d33b497 100644 --- a/docs/html/hierarchy.html +++ b/docs/html/hierarchy.html @@ -86,7 +86,7 @@ $(function() { diff --git a/docs/html/index.html b/docs/html/index.html index 1cd5d8b..1c18a00 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -170,7 +170,7 @@ Dabei gehören Punkte mit dem gleichen Index für curve (uint8_ diff --git a/docs/html/plottyfile_8cpp_source.html b/docs/html/plottyfile_8cpp_source.html index bce966e..0961f9f 100644 --- a/docs/html/plottyfile_8cpp_source.html +++ b/docs/html/plottyfile_8cpp_source.html @@ -101,7 +101,7 @@ $(function() {
std::string getUnitX(void) const
Definition: plottyfile.cpp:105
diff --git a/docs/html/plottyfile_8h_source.html b/docs/html/plottyfile_8h_source.html index e954852..2070fec 100644 --- a/docs/html/plottyfile_8h_source.html +++ b/docs/html/plottyfile_8h_source.html @@ -102,7 +102,7 @@ $(function() {
std::string getUnitX(void) const
Definition: plottyfile.cpp:105
diff --git a/docs/html/requests_8h_source.html b/docs/html/requests_8h_source.html index 10910fb..efc0bdf 100644 --- a/docs/html/requests_8h_source.html +++ b/docs/html/requests_8h_source.html @@ -73,7 +73,7 @@ $(function() {
1 #ifndef REQUESTS_H
2 #define REQUESTS_H
3 
4 constexpr static uint8_t RQ_DISCARD = 0;
5 constexpr static uint8_t RQ_TEST = 1;
6 constexpr static uint8_t RQ_INFO = 2;
7 constexpr static uint8_t RQ_INT_TEST = 3;
8 constexpr static uint8_t RQ_SELF_TEST = 4;
9 constexpr static uint8_t RQ_DIGITAL_WRITE_0 = 5;
10 constexpr static uint8_t RQ_DIGITAL_WRITE_1 = 6;
11 constexpr static uint8_t RQ_DIGITAL_READ_0 = 7;
12 constexpr static uint8_t RQ_DIGITAL_READ_1 = 8;
13 constexpr static uint8_t RQ_READ_DIP_SWITCH = 9;
14 constexpr static uint8_t RQ_ANALOG_WRITE_0 = 10;
15 constexpr static uint8_t RQ_ANALOG_WRITE_1 = 11;
16 constexpr static uint8_t RQ_ANALOG_READ = 12;
17 constexpr static uint8_t RQ_ADC_DAC_STROKE = 13;
18 constexpr static uint8_t RQ_PWM_SET_FREQ = 14;
19 constexpr static uint8_t RQ_PWM_SET_VALUE = 15;
20 constexpr static uint8_t RQ_SET_MEM_8 = 16;
21 constexpr static uint8_t RQ_GET_MEM_8 = 17;
22 constexpr static uint8_t RQ_SET_MEM_16 = 18;
23 constexpr static uint8_t RQ_GET_MEM_16 = 19;
24 constexpr static uint8_t RQ_COUNTER_OFFSET = 20;
25 constexpr static uint8_t RQ_SERVO_ENABLE = 21;
26 constexpr static uint8_t RQ_SERVO_DISABLE = 22;
27 constexpr static uint8_t RQ_SERVO_SET_POS = 23;
28 
29 uint8_t const rq_len[] =
30 {
31  1 /* RQ_DISCARD */,
32  1 /* RQ_TEST */ + 1 /* test byte */,
33  1 /* RQ_INFO */,
34  1 /* RQ_INT_TEST */ + 1 /* test int high low */ + 1 /* test int high high */,
35  1 /* RQ_SELF_TEST */,
36  1 /* RQ_DIGITAL_WRITE_0 */ + 1 /* port value */,
37  1 /* RQ_DIGITAL_WRITE_1 */ + 1 /* port value */,
38  1 /* RQ_DIGITAL_READ_0 */,
39  1 /* RQ_DIGITAL_READ_1 */,
40  1 /* RQ_READ_DIP_SWITCH */,
41  1 /* RQ_ANALOG_WRITE_0 */ + 1 /* test int high low */ + 1 /* test int high high */,
42  1 /* RQ_ANALOG_WRITE_1 */ + 1 /* test int high low */ + 1 /* test int high high */,
43  1 /* RQ_ANALOG_READ */ + 1 /* adc channel */,
44  1 /* RQ_ADC_DAC_STROKE */ + 1 /* channel a */ + 1 /* channel b */ + 1 /* start low */ + 1 /* start high */ + 1 /* delta low */ + 1 /* delta high */ + 1 /* count low */ + 1 /* count high */,
45  1 /* RQ_PWM_SET_FREQ */ + 1 /* freq low low */ + 1 /* freq low high */ + 1 /* freq high low */ + 1 /* freq high high */,
46  1 /* RQ_PWM_SET_VALUE */ + 1 /* pwm value */,
47  1 /* RQ_SET_MEM_8 */ + 1 /* memory address low */ + 1 /* memory address high */ + 1 /* memory value (8-bit) */,
48  1 /* RQ_GET_MEM_8 */ + 1 /* memory address low */ + 1 /* memory address high */,
49  1 /* RQ_SET_MEM_16 */ + 1 /* memory address low */ + 1 /* memory address high */ + 1 /* memory value low */ + 1 /* memory value high */,
50  1 /* RQ_GET_MEM_16 */ + 1 /* memory address low */ + 1 /* memory address high */,
51  1 /* RQ_COUNTER_OFFSET */,
52  1 /* RQ_SERVO_ENABLE */,
53  1 /* RQ_SERVO_DISABLE */,
54  1 /* RQ_SERVO_SET_POS */ + 1 /* pulse length low */ + 1 /* pulse length high */,
55 };
56 
57 #endif // REQUESTS_H
diff --git a/docs/html/timeoutexception_8h_source.html b/docs/html/timeoutexception_8h_source.html index eb6425e..0e99717 100644 --- a/docs/html/timeoutexception_8h_source.html +++ b/docs/html/timeoutexception_8h_source.html @@ -79,7 +79,7 @@ $(function() {
TimeoutException(const std::string &message)
diff --git a/docs/html/ui_8cpp_source.html b/docs/html/ui_8cpp_source.html index 126d3c4..9112c15 100644 --- a/docs/html/ui_8cpp_source.html +++ b/docs/html/ui_8cpp_source.html @@ -72,23 +72,23 @@ $(function() {
1 #include "ui.h"
2 #include "../drv/b15f.h"
3 
4 std::vector<View*> win_stack;
5 std::thread t_refresh;
6 
7 void show_main(int)
8 {
9  ViewSelection* view = new ViewSelection();
10  view->setTitle("B15F - Command Line Interface");
11  view->addChoice("[ Monitor - Eingaben beobachten ]", &show_monitor);
12  view->addChoice("[ Digitale Ausgabe BA0 ]", &show_digital_output0);
13  view->addChoice("[ Digitale Ausgabe BA1 ]", &show_digital_output1);
14  view->addChoice("[ Analoge Ausgabe AA0 ]", &show_analog_output0);
15  view->addChoice("[ Analoge Ausgabe AA1 ]", &show_analog_output1);
16  view->addChoice("[ Selbsttest des B15 ]", &show_selftest_info);
17  view->addChoice("[ Informationen ]", &show_info);
18  view->addChoice("", nullptr);
19  view->addChoice("[ Beenden ]", &finish);
20  view->repaint();
21 
22  win_stack.push_back(view);
23  input(0);
24 }
25 
26 void input(int)
27 {
28  call_t nextCall;
29  int key;
30  do
31  {
32  key = wgetch(View::getWinContext());
33  win_stack.back()->repaint();
34  nextCall = win_stack.back()->keypress(key);
35 
36  if(key == -1)
37  view_back(key);
38 
39  if(nextCall)
40  nextCall(key);
41  }
42  while(win_stack.size());
43 }
44 
45 void view_back(int)
46 {
47  if(win_stack.size())
48  {
49  delete win_stack.back();
50  win_stack.pop_back();
51  }
52  if(win_stack.size())
53  win_stack.back()->repaint();
54 }
55 
56 void finish(int)
57 {
58  cleanup();
59  exit(EXIT_SUCCESS);
60 }
61 
62 void cleanup()
63 {
64  if(t_refresh.joinable())
65  t_refresh.join();
66  clrtoeol();
67  refresh();
68  endwin();
69 }
70 
71 void show_info(int)
72 {
73  ViewInfo* view = new ViewInfo();
74  view->setTitle("Info");
75  view->setText("Informationen zu Board 15 Famulus Edition\n \nProjektseite: https://github.com/devfix/b15f/\nDokumentation: https://devfix.github.io/b15f/\n \nB15F Software entwickelt von Tristan Krause für das Hardware-Labor.\nKontakt: tristan.krause@stud.htwk-leipzig.de");
76  view->setLabelClose("[ Zurueck ]");
77  view->repaint();
78 
79  win_stack.push_back(view);
80  input(0);
81 }
82 
83 void show_monitor(int)
84 {
85  ViewMonitor* view = new ViewMonitor();
86  view->setTitle("Monitor");
87  view->setText("\nErfasse Messwerte...");
88  view->setLabelClose("[ Zurueck ]");
89  view->repaint();
90 
91  win_stack.push_back(view);
92  input(0);
93 }
94 
95 void show_invalid_port_input(int)
96 {
97  ViewInfo* view = new ViewInfo();
98  view->setTitle("Falsche Eingabe");
99  view->setText("Bitte geben Sie einen Wert aus dem Intervall [0, FF] an.");
100  view->setLabelClose("[ Schliessen ]");
101  view->repaint();
102 
103  win_stack.push_back(view);
104  input(0);
105 }
106 
107 void show_invalid_dac_input(int)
108 {
109  ViewInfo* view = new ViewInfo();
110  view->setTitle("Falsche Eingabe");
111  view->setText("Bitte geben Sie einen Wert aus dem Intervall [0, 1023] an.");
112  view->setLabelClose("[ Schliessen ]");
113  view->repaint();
114 
115  win_stack.push_back(view);
116  input(0);
117 }
118 
119 void write_digital_output0(int)
120 {
121  try
122  {
123  int d = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput(), 0, 16);
124  if(d > 255 || 0 > d)
125  throw std::invalid_argument("bad value");
126  uint8_t port = static_cast<uint8_t>(d);
127 
128  B15F& drv = B15F::getInstance();
129  drv.digitalWrite0(port);
130  view_back(0);
131  }
132  catch(std::invalid_argument& ex)
133  {
134  show_invalid_port_input(0);
135  }
136 }
137 
138 void write_digital_output1(int)
139 {
140  try
141  {
142  int d = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput(), 0, 16);
143  if(d > 255 || 0 > d)
144  throw std::invalid_argument("bad value");
145  uint8_t port = static_cast<uint8_t>(d);
146 
147  B15F& drv = B15F::getInstance();
148  drv.digitalWrite1(port);
149  view_back(0);
150  }
151  catch(std::invalid_argument& ex)
152  {
153  show_invalid_port_input(0);
154  }
155 }
156 
157 void write_analog_output0(int)
158 {
159  try
160  {
161  uint16_t port = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput());
162  if(port > 1023)
163  throw std::invalid_argument("bad value");
164 
165  B15F& drv = B15F::getInstance();
166  drv.analogWrite0(port);
167  view_back(0);
168  }
169  catch(std::invalid_argument& ex)
170  {
171  show_invalid_dac_input(0);
172  }
173 }
174 
175 void write_analog_output1(int)
176 {
177  try
178  {
179  uint16_t port = std::stoi(static_cast<ViewPromt*>(win_stack.back())->getInput());
180  if(port > 1023)
181  throw std::invalid_argument("bad value");
182 
183  B15F& drv = B15F::getInstance();
184  drv.analogWrite1(port);
185  view_back(0);
186  }
187  catch(std::invalid_argument& ex)
188  {
189  show_invalid_dac_input(0);
190  }
191 }
192 
193 void show_digital_output0(int)
194 {
195  ViewPromt* view = new ViewPromt();
196  view->setTitle("Digitale Ausgabe BE0");
197  view->setMessage("\nAusgabe Port-Wert (hex): 0x");
198  view->setCancel("[ Zurueck ]", true);
199  view->setConfirm("[ OK ]", &write_digital_output0);
200  view->repaint();
201 
202  win_stack.push_back(view);
203  input(0);
204 }
205 
206 void show_digital_output1(int)
207 {
208  ViewPromt* view = new ViewPromt();
209  view->setTitle("Digitale Ausgabe BE1");
210  view->setMessage("\nAusgabe Port-Wert (hex): 0x");
211  view->setCancel("[ Zurueck ]", true);
212  view->setConfirm("[ OK ]", &write_digital_output1);
213  view->repaint();
214 
215  win_stack.push_back(view);
216  input(0);
217 }
218 
219 void show_analog_output0(int)
220 {
221  ViewPromt* view = new ViewPromt();
222  view->setTitle("Analoge Ausgabe AA0");
223  view->setMessage("\nAusgabe 10-Bit-Wert (0...1023): ");
224  view->setCancel("[ Zurueck ]", true);
225  view->setConfirm("[ OK ]", &write_analog_output0);
226  view->repaint();
227 
228  win_stack.push_back(view);
229  input(0);
230 }
231 
232 void show_analog_output1(int)
233 {
234  ViewPromt* view = new ViewPromt();
235  view->setTitle("Analoge Ausgabe AA1");
236  view->setMessage("\nAusgabe 10-Bit-Wert (0...1023): ");
237  view->setCancel("[ Zurueck ]", true);
238  view->setConfirm("[ OK ]", &write_analog_output1);
239  view->repaint();
240 
241  win_stack.push_back(view);
242  input(0);
243 }
244 
245 void start_selftest(int)
246 {
247  B15F& drv = B15F::getInstance();
248  drv.activateSelfTestMode();
249 
250  ViewInfo* view = new ViewInfo();
251  view->setTitle("Selbsttest aktiv");
252  view->setText("Das B15 befindet sich jetzt im Selbsttestmodus.\n \nSelbsttest:\nZu Beginn geht der Reihe nach jede LED von BA0 bis BA1 an.\nDanach leuchten die LEDs an AA0 und AA1 kurz auf.\nZum Schluss spiegelt in einer Endlosschleife:\n* BA0 Port BE0\n* BA1 die DIP-Schalter S7\n* AA0 ADC0\n* AA1 ADC1");
253  view->setLabelClose("[ Selbsttest Beenden ]");
254  view->setCall(&stop_selftest);
255  view->repaint();
256 
257  win_stack.push_back(view);
258  input(0);
259 }
260 
261 void stop_selftest(int)
262 {
263  B15F& drv = B15F::getInstance();
264  drv.discard();
266  drv.reconnect();
267  drv.digitalWrite0(0);
268  drv.digitalWrite1(0);
269 }
270 
271 void show_selftest_info(int)
272 {
273  ViewInfo* view = new ViewInfo();
274  view->setTitle("Selbsttest");
275  view->setText("Bitte entfernen Sie jetzt alle Draehte von den Anschlussklemmen und\nbestätigen mit Enter.");
276  view->setLabelClose("[ Weiter ]");
277  view->setCall(&start_selftest);
278  view->repaint();
279 
280  win_stack.push_back(view);
281  input(0);
282 }
-
void analogWrite0(uint16_t port)
Definition: b15f.cpp:296
-
void analogWrite1(uint16_t port)
Definition: b15f.cpp:313
-
void digitalWrite0(uint8_t)
Definition: b15f.cpp:213
+
void analogWrite0(uint16_t port)
Definition: b15f.cpp:302
+
void analogWrite1(uint16_t port)
Definition: b15f.cpp:319
+
void digitalWrite0(uint8_t)
Definition: b15f.cpp:219
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:141
static B15F & getInstance(void)
Definition: b15f.cpp:10
Definition: b15f.h:38
-
void activateSelfTestMode(void)
Definition: b15f.cpp:198
+
void activateSelfTestMode(void)
Definition: b15f.cpp:204
void discard(void)
Definition: b15f.cpp:40
constexpr static uint16_t WDT_TIMEOUT
Time in ms after which the watch dog timer resets the MCU.
Definition: b15f.h:314
void reconnect(void)
Definition: b15f.cpp:18
-
void digitalWrite1(uint8_t)
Definition: b15f.cpp:229
+
void digitalWrite1(uint8_t)
Definition: b15f.cpp:235
diff --git a/docs/html/ui_8h_source.html b/docs/html/ui_8h_source.html index f45635b..0a6b0c4 100644 --- a/docs/html/ui_8h_source.html +++ b/docs/html/ui_8h_source.html @@ -73,7 +73,7 @@ $(function() {
1 #ifndef UI_H
2 #define UI_H
3 
4 #include <vector>
5 #include "view_selection.h"
6 #include "view_info.h"
7 #include "view_monitor.h"
8 #include "view_promt.h"
9 
10 void show_main(int);
11 void input(int);
12 void view_back(int);
13 void finish(int);
14 void cleanup();
15 
16 void show_info(int);
17 void show_monitor(int);
18 void show_invalid_port_input(int);
19 void show_invalid_dac_input(int);
20 void write_digital_output0(int);
21 void write_digital_output1(int);
22 void write_analog_output0(int);
23 void write_analog_output1(int);
24 void show_digital_output0(int);
25 void show_digital_output1(int);
26 void show_analog_output0(int);
27 void show_analog_output1(int);
28 
29 // selftest group
30 void show_selftest_info(int);
31 void start_selftest(int);
32 void stop_selftest(int);
33 
34 
35 extern std::vector<View*> win_stack;
36 extern std::thread t_refresh;
37 
38 #endif // UI_H
diff --git a/docs/html/usart_8cpp_source.html b/docs/html/usart_8cpp_source.html index f3f564a..4639003 100644 --- a/docs/html/usart_8cpp_source.html +++ b/docs/html/usart_8cpp_source.html @@ -88,7 +88,7 @@ $(function() { diff --git a/docs/html/usart_8h_source.html b/docs/html/usart_8h_source.html index e3b56c6..09111c9 100644 --- a/docs/html/usart_8h_source.html +++ b/docs/html/usart_8h_source.html @@ -88,7 +88,7 @@ $(function() {
void flushOutputBuffer(void)
Definition: usart.cpp:68
diff --git a/docs/html/usartexception_8h_source.html b/docs/html/usartexception_8h_source.html index 181fe28..3e392e8 100644 --- a/docs/html/usartexception_8h_source.html +++ b/docs/html/usartexception_8h_source.html @@ -79,7 +79,7 @@ $(function() {
virtual ~USARTException()=default
diff --git a/docs/html/view_8cpp_source.html b/docs/html/view_8cpp_source.html index 53a6ab6..62d065c 100644 --- a/docs/html/view_8cpp_source.html +++ b/docs/html/view_8cpp_source.html @@ -71,10 +71,10 @@ $(function() {
1 #include "view.h"
2 
3 WINDOW* View::win = nullptr;
4 
5 View::View()
6 {
7  if(!win)
8  {
9  B15F::abort("View::win not initialized, missing context");
10  }
11  getmaxyx(win, height, width); // init width and height
12  keypad(win, TRUE);
13 }
14 
15 View::~View()
16 {
17 }
18 
19 void View::setWinContext(WINDOW* win)
20 {
21  View::win = win;
22 }
23 
24 WINDOW* View::getWinContext()
25 {
26  return win;
27 }
28 
29 // from: https://stackoverflow.com/a/37454181
30 std::vector<std::string> View::str_split(const std::string& str, const std::string delim)
31 {
32  std::vector<std::string> tokens;
33  size_t prev = 0, pos = 0;
34  do
35  {
36  pos = str.find(delim, prev);
37  if (pos == std::string::npos) pos = str.length();
38  std::string token = str.substr(prev, pos-prev);
39  if (!token.empty()) tokens.push_back(token);
40  prev = pos + delim.length();
41  }
42  while (pos < str.length() && prev < str.length());
43  return tokens;
44 }
45 
46 
47 void View::setTitle(std::string title)
48 {
49  this->title = title;
50 }
51 
52 void View::repaint()
53 {
54  // get screen size
55  struct winsize size;
56  if (ioctl(0, TIOCGWINSZ, (char *) &size) < 0)
57  throw std::runtime_error("TIOCGWINSZ error");
58 
59 
60  start_x = floor((size.ws_col - width) / 2.);
61  start_y = floor((size.ws_row - height) / 2.);
62 
63  curs_set(0); // hide cursor
64  mvwin(win, start_y, start_x);
65  clear();
66  wclear(win);
67 
68  // generic draw
69  box(win, 0, 0);
70  int offset_x = (width - title.length()) / 2;
71  mvwprintw(win, 1, offset_x, "%s", title.c_str());
72 
73  // specific draw
74  draw();
75 
76  refresh();
77  wrefresh(win);
78 }
-
static void abort(std::string msg)
Definition: b15f.cpp:169
+
static void abort(std::string msg)
Definition: b15f.cpp:175
diff --git a/docs/html/view_8h_source.html b/docs/html/view_8h_source.html index 35ac2a9..5a95ecf 100644 --- a/docs/html/view_8h_source.html +++ b/docs/html/view_8h_source.html @@ -74,7 +74,7 @@ $(function() {
Definition: view.h:19
diff --git a/docs/html/view__info_8cpp_source.html b/docs/html/view__info_8cpp_source.html index fb227d5..b916c9f 100644 --- a/docs/html/view__info_8cpp_source.html +++ b/docs/html/view__info_8cpp_source.html @@ -73,7 +73,7 @@ $(function() {
1 #include "view_info.h"
2 
3 ViewInfo::ViewInfo()
4 {
5  calls.push_back(nullptr);
6 }
7 
8 void ViewInfo::setText(std::string text)
9 {
10  this->text = text;
11 }
12 
13 void ViewInfo::setLabelClose(std::string label)
14 {
15  this->label_close = label;
16 }
17 
18 void ViewInfo::setCall(call_t call)
19 {
20  calls[0] = call;
21 }
22 
23 void ViewInfo::draw()
24 {
25  int li = 0;
26  for(std::string line : str_split(text, "\n"))
27  mvwprintw(win, text_offset_y + li++, text_offset_x, "%s", line.c_str());
28 
29  close_offset_x = (width - label_close.length()) / 2;
30  close_offset_y = height - 2;
31 
32  wattron(win, A_REVERSE);
33  mvwprintw(win, close_offset_y, close_offset_x, "%s", label_close.c_str());
34  wattroff(win, A_REVERSE);
35 }
36 
37 call_t ViewInfo::keypress(int& key)
38 {
39  switch(key)
40  {
41 
42  case KEY_MOUSE:
43  {
44  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
45  MEVENT event;
46  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
47  {
48  size_t column = start_x + close_offset_x;
49  size_t row = start_y + close_offset_y;
50  size_t mouse_x = event.x, mouse_y = event.y;
51  if(mouse_y == row && mouse_x >= column && mouse_x < column + label_close.length())
52  key = -1; // do return from view
53  }
54  break;
55  }
56  case KEY_ENT:
57  key = -1; // do return from view
58  break;
59  default:
60  break;
61  }
62  return calls[0];
63 }
diff --git a/docs/html/view__info_8h_source.html b/docs/html/view__info_8h_source.html index ee4401a..e65ed7a 100644 --- a/docs/html/view__info_8h_source.html +++ b/docs/html/view__info_8h_source.html @@ -75,7 +75,7 @@ $(function() {
Definition: view.h:19
diff --git a/docs/html/view__monitor_8cpp_source.html b/docs/html/view__monitor_8cpp_source.html index 3ab8372..2641d7e 100644 --- a/docs/html/view__monitor_8cpp_source.html +++ b/docs/html/view__monitor_8cpp_source.html @@ -70,21 +70,21 @@ $(function() {
view_monitor.cpp
-
1 #include "view_monitor.h"
2 
3 ViewMonitor::ViewMonitor() : t_worker(&ViewMonitor::worker, this)
4 {
5 }
6 
7 call_t ViewMonitor::keypress(int& key)
8 {
9  switch(key)
10  {
11 
12  case KEY_MOUSE:
13  {
14  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
15  MEVENT event;
16  bool hit = false;
17  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
18  {
19  size_t column = start_x + close_offset_x;
20  size_t row = start_y + close_offset_y;
21  size_t mouse_x = event.x, mouse_y = event.y;
22  if(mouse_y == row && mouse_x >= column && mouse_x < column + label_close.length())
23  hit = true;
24  }
25  if(!hit)
26  break;
27 
28  // fall through to next case
29  [[fallthrough]];
30  }
31  case KEY_ENT:
32  run_worker = false;
33  key = -1; // do return from view
34  wclear(win);
35  wrefresh(win);
36  t_worker.join();
37  break;
38  default:
39  break;
40  }
41  return calls[0];
42 }
43 
44 std::string ViewMonitor::fancyDigitalString(uint8_t& b)
45 {
46  std::string bitstring(std::bitset<8>(b).to_string());
47  std::reverse(bitstring.begin(), bitstring.end());
48 
49  std::stringstream str;
50  str << bitstring;
51  str << " ";
52  str << "0x" << std::setfill ('0') << std::setw(2) << std::hex << (int) b << std::dec;
53  return str.str();
54 }
55 
56 std::string ViewMonitor::fancyAnalogString(uint16_t& v)
57 {
58  std::stringstream str;
59  double volt = round(v * 100.0 * 5.0 / 1023.0) / 100.0;
60 
61  str << std::setfill ('0') << std::setw(4) << (int) v << " " << std::fixed << std::setprecision(2) << volt << " V ";
62 
63  str << "[";
64  uint8_t p = round(v * 40.0 / 1023.0);
65  for(uint8_t i = 0; i < p; i++)
66  str << "X";
67  for(uint8_t i = 0; i < 40 - p; i++)
68  str << " ";
69  str << "]" << std::endl;
70 
71  return str.str();
72 }
73 
74 void ViewMonitor::worker()
75 {
76  B15F& drv = B15F::getInstance();
77  while(run_worker)
78  {
79  try
80  {
81 
82 #ifdef __arm__
83  // Raspberry Pi is much slower
84  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
85 #else
86  // normal PC is faster
87  std::this_thread::sleep_for(std::chrono::milliseconds(100));
88 #endif
89 
90  uint8_t be0 = drv.digitalRead0();
91  uint8_t be1 = drv.digitalRead1();
92  uint8_t dsw = drv.readDipSwitch();
93  uint16_t adc[8];
94  for(uint8_t i = 0; i < sizeof(adc) / sizeof(adc[0]); i++)
95  adc[i] = drv.analogRead(i);
96 
97 
98  std::stringstream str;
99 
100  // hline
101  for(uint8_t i = 0; i < width - 2 * text_offset_x; i++)
102  if(i % 2 == 0)
103  str << "-";
104  else
105  str << " ";
106  str << std::endl;
107 
108  str << "Digitale Enigaenge:" << std::endl;
109  str << "Binaere Eingabe 0: " << fancyDigitalString(be0) << std::endl;
110  str << "Binaere Eingabe 1: " << fancyDigitalString(be1) << std::endl;
111  str << "Dip Schalter (S7): " << fancyDigitalString(dsw) << std::endl;
112 
113  // hline
114  for(uint8_t i = 0; i < width - 2 * text_offset_x; i++)
115  if(i % 2 == 0)
116  str << "-";
117  else
118  str << " ";
119  str << std::endl;
120 
121  str << "Analoge Eingaenge:" << std::endl;
122  for(uint8_t i = 0; i < sizeof(adc) / sizeof(adc[0]); i++)
123  {
124  str << "Kanal " << std::to_string((int) i) << ": ";
125  str << fancyAnalogString(adc[i]) << std::endl;
126  }
127 
128  text = str.str();
129  repaint();
130  }
131  catch(DriverException& ex)
132  {
133  std::cout << "DriverException: " << ex.what() << std::endl;
134  drv.delay_ms(1000);
135  }
136  catch(...)
137  {
138  try
139  {
140  drv.reconnect();
141  }
142  catch(...)
143  {
144  B15F::abort("Die Verbindung ist unterbrochen worden. Wurde ein Stecker gezogen? :D");
145  return;
146  }
147  }
148  }
149 }
+
1 #include "view_monitor.h"
2 
3 ViewMonitor::ViewMonitor() : t_worker(&ViewMonitor::worker, this)
4 {
5 }
6 
7 call_t ViewMonitor::keypress(int& key)
8 {
9  switch(key)
10  {
11 
12  case KEY_MOUSE:
13  {
14  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
15  MEVENT event;
16  bool hit = false;
17  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
18  {
19  size_t column = start_x + close_offset_x;
20  size_t row = start_y + close_offset_y;
21  size_t mouse_x = event.x, mouse_y = event.y;
22  if(mouse_y == row && mouse_x >= column && mouse_x < column + label_close.length())
23  hit = true;
24  }
25  if(!hit)
26  break;
27 
28  // fall through to next case
29  [[fallthrough]];
30  }
31  case KEY_ENT:
32  run_worker = false;
33  key = -1; // do return from view
34  wclear(win);
35  wrefresh(win);
36  t_worker.join();
37  break;
38  default:
39  break;
40  }
41  return calls[0];
42 }
43 
44 std::string ViewMonitor::fancyDigitalString(uint8_t& b)
45 {
46  std::string bitstring(std::bitset<8>(b).to_string());
47  std::reverse(bitstring.begin(), bitstring.end());
48 
49  std::stringstream str;
50  str << bitstring;
51  str << " ";
52  str << "0x" << std::setfill ('0') << std::setw(2) << std::hex << (int) b << std::dec;
53  return str.str();
54 }
55 
56 std::string ViewMonitor::fancyAnalogString(uint16_t& v)
57 {
58  std::stringstream str;
59  double volt = round(v * 100.0 * 5.0 / 1023.0) / 100.0;
60 
61  str << std::setfill ('0') << std::setw(4) << (int) v << " " << std::fixed << std::setprecision(2) << volt << " V ";
62 
63  str << "[";
64  uint8_t p = round(v * 40.0 / 1023.0);
65  for(uint8_t i = 0; i < p; i++)
66  str << "X";
67  for(uint8_t i = 0; i < 40 - p; i++)
68  str << " ";
69  str << "]" << std::endl;
70 
71  return str.str();
72 }
73 
74 void ViewMonitor::worker()
75 {
76  B15F& drv = B15F::getInstance();
77  while(run_worker)
78  {
79  try
80  {
81 
82 #ifdef __arm__
83  // Raspberry Pi is much slower
84  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
85 #else
86  // normal PC is faster
87  std::this_thread::sleep_for(std::chrono::milliseconds(100));
88 #endif
89 
90  uint8_t be0 = drv.digitalRead0();
91  uint8_t be1 = drv.digitalRead1();
92  uint8_t dsw = drv.readDipSwitch();
93  uint16_t adc[8];
94  for(uint8_t i = 0; i < sizeof(adc) / sizeof(adc[0]); i++)
95  adc[i] = drv.analogRead(i);
96 
97 
98  std::stringstream str;
99 
100  // hline
101  for(uint8_t i = 0; i < width - 2 * text_offset_x; i++)
102  if(i % 2 == 0)
103  str << "-";
104  else
105  str << " ";
106  str << std::endl;
107 
108  str << "Digitale Enigaenge:" << std::endl;
109  str << "Binaere Eingabe 0: " << fancyDigitalString(be0) << std::endl;
110  str << "Binaere Eingabe 1: " << fancyDigitalString(be1) << std::endl;
111  str << "Dip Schalter (S7): " << fancyDigitalString(dsw) << std::endl;
112 
113  // hline
114  for(uint8_t i = 0; i < width - 2 * text_offset_x; i++)
115  if(i % 2 == 0)
116  str << "-";
117  else
118  str << " ";
119  str << std::endl;
120 
121  str << "Analoge Eingaenge:" << std::endl;
122  for(uint8_t i = 0; i < sizeof(adc) / sizeof(adc[0]); i++)
123  {
124  str << "Kanal " << std::to_string((int) i) << ": ";
125  str << fancyAnalogString(adc[i]) << std::endl;
126  }
127 
128  text = str.str();
129  repaint();
130  }
131  catch(DriverException& ex)
132  {
133  std::cout << "DriverException: " << ex.what() << std::endl;
134  drv.delay_ms(1000);
135  }
136  catch(...)
137  {
138  try
139  {
140  drv.reconnect();
141  }
142  catch(...)
143  {
144  B15F::abort("Die Verbindung ist unterbrochen worden. Wurde ein Stecker gezogen? :D");
145  return;
146  }
147  }
148  }
149 }
-
uint8_t digitalRead0(void)
Definition: b15f.cpp:245
-
uint8_t readDipSwitch(void)
Definition: b15f.cpp:277
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
+
uint8_t digitalRead0(void)
Definition: b15f.cpp:251
+
uint8_t readDipSwitch(void)
Definition: b15f.cpp:283
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:141
static B15F & getInstance(void)
Definition: b15f.cpp:10
Definition: b15f.h:38
-
static void abort(std::string msg)
Definition: b15f.cpp:169
-
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:330
-
uint8_t digitalRead1(void)
Definition: b15f.cpp:261
+
static void abort(std::string msg)
Definition: b15f.cpp:175
+
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:336
+
uint8_t digitalRead1(void)
Definition: b15f.cpp:267
void reconnect(void)
Definition: b15f.cpp:18
diff --git a/docs/html/view__monitor_8h_source.html b/docs/html/view__monitor_8h_source.html index 2e8baa4..413cafd 100644 --- a/docs/html/view__monitor_8h_source.html +++ b/docs/html/view__monitor_8h_source.html @@ -75,7 +75,7 @@ $(function() { diff --git a/docs/html/view__promt_8cpp_source.html b/docs/html/view__promt_8cpp_source.html index 754ceab..d87d373 100644 --- a/docs/html/view__promt_8cpp_source.html +++ b/docs/html/view__promt_8cpp_source.html @@ -73,7 +73,7 @@ $(function() {
1 #include "view_promt.h"
2 
3 void ViewPromt::draw()
4 {
5  curs_set(1); // show cursor
6 
7  int li = text_offset_y;
8  int ci = 0;
9  for(std::string line : str_split(message + input, "\n"))
10  {
11  mvwprintw(win, ++li, text_offset_x, "%s", line.c_str());
12  ci = line.length() + text_offset_x;
13  }
14 
15  button_offset_x = (width - label_cancel.length() - sep.length() - label_confirm.length()) / 2;
16  button_offset_y = height - text_offset_y;
17 
18  if(selection == 0)
19  {
20  wattron(win, A_REVERSE);
21  mvwprintw(win, button_offset_y, button_offset_x, "%s", label_cancel.c_str());
22  wattroff(win, A_REVERSE);
23  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length(), "%s", sep.c_str());
24  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length() + sep.length(), "%s", label_confirm.c_str());
25  }
26  else
27  {
28  mvwprintw(win, button_offset_y, button_offset_x, "%s", label_cancel.c_str());
29  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length(), "%s", sep.c_str());
30  wattron(win, A_REVERSE);
31  mvwprintw(win, button_offset_y, button_offset_x + label_cancel.length() + sep.length(), "%s", label_confirm.c_str());
32  wattroff(win, A_REVERSE);
33  }
34  wmove(win, li, ci);
35 }
36 
37 void ViewPromt::setMessage(std::string message)
38 {
39  this->message = message;
40 }
41 
42 void ViewPromt::setConfirm(std::string name, std::function<void(int)> call)
43 {
44  label_confirm = name;
45  call_confirm = call;
46 }
47 
48 void ViewPromt::setCancel(std::string name, bool cancelable)
49 {
50  label_cancel = name;
51  this->cancelable = cancelable;
52 }
53 
54 std::string ViewPromt::getInput()
55 {
56  return input;
57 }
58 
59 std::function<void(int)> ViewPromt::keypress(int& key)
60 {
61  std::function<void(int)> ret = nullptr;
62  switch(key)
63  {
64  case KEY_BACKSPACE:
65  if(input.length())
66  input.pop_back();
67  break;
68  case '\t':
69  case KEY_LEFT:
70  case KEY_RIGHT:
71  selection = (selection + 1 ) % 2;
72  break;
73  case KEY_MOUSE:
74  {
75  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
76  MEVENT event;
77  bool hit = false;
78  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
79  {
80  size_t column_start = start_x + button_offset_x;
81  size_t row_start = start_y + button_offset_y;
82  size_t mouse_x = event.x, mouse_y = event.y;
83  if(mouse_y == row_start)
84  {
85  if(cancelable && mouse_x >= column_start && mouse_x < column_start + label_cancel.length())
86  {
87  if(selection == 0 || event.bstate & BUTTON1_DOUBLE_CLICKED)
88  hit = true;
89  selection = 0;
90  }
91  if(mouse_x >= column_start + label_cancel.length() + sep.length() && mouse_x < column_start + label_cancel.length() + sep.length() + label_confirm.length())
92  {
93  if(selection == 1 || event.bstate & BUTTON1_DOUBLE_CLICKED)
94  hit = true;
95  selection = 1;
96  }
97  }
98  }
99  if(!hit)
100  break;
101 
102  // fall through to next case
103  [[fallthrough]];
104  }
105  case KEY_ENT:
106  if(selection == 0) // exit
107  key = -1; // do return from view
108  else
109  ret = call_confirm;
110  break;
111  default:
112  break;
113  }
114 
115  if(key >= ' ' && key <= '~')
116  input += (char) key;
117 
118  if(key != KEY_ENT)
119  repaint();
120  return ret;
121 }
diff --git a/docs/html/view__promt_8h_source.html b/docs/html/view__promt_8h_source.html index 699fbf8..94cd826 100644 --- a/docs/html/view__promt_8h_source.html +++ b/docs/html/view__promt_8h_source.html @@ -75,7 +75,7 @@ $(function() { diff --git a/docs/html/view__selection_8cpp_source.html b/docs/html/view__selection_8cpp_source.html index 5c581b6..c04c0af 100644 --- a/docs/html/view__selection_8cpp_source.html +++ b/docs/html/view__selection_8cpp_source.html @@ -73,7 +73,7 @@ $(function() {
1 #include "view_selection.h"
2 
3 void ViewSelection::draw()
4 {
5  //curs_set(0); // hide cursor
6  for(size_t i = 0; i < choices.size(); i++)
7  {
8  if(selection == i)
9  wattron(win, A_REVERSE);
10  mvwprintw(win, i + choice_offset_y, choice_offset_x, "%s", choices[i].c_str());
11  if(selection == i)
12  wattroff(win, A_REVERSE);
13  }
14 }
15 
16 void ViewSelection::addChoice(std::string name, call_t call)
17 {
18  choices.push_back(name);
19  calls.push_back(call);
20 }
21 
22 call_t ViewSelection::keypress(int& key)
23 {
24  call_t ret = nullptr;
25  switch(key)
26  {
27  case KEY_UP:
28  do
29  selection = (selection - 1 + choices.size()) % choices.size();
30  while(!choices[selection].length() && choices.size());
31  break;
32 
33  case '\t':
34  case KEY_DOWN:
35  do
36  selection = (selection + 1) % choices.size();
37  while(!choices[selection].length() && choices.size());
38  break;
39 
40  case KEY_MOUSE:
41  {
42  // http://pronix.linuxdelta.de/C/Linuxprogrammierung/Linuxsystemprogrammieren_C_Kurs_Kapitel10b.shtml
43  MEVENT event;
44  bool hit = false;
45  if(getmouse(&event) == OK && event.bstate & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))
46  {
47  size_t column_start = start_x + choice_offset_x;
48  size_t row_start = start_y + choice_offset_y;
49  size_t mouse_x = event.x, mouse_y = event.y;
50  for(size_t i = 0; i < choices.size(); i++)
51  if(choices[i].length() && mouse_y == row_start + i && mouse_x >= column_start && mouse_x < column_start + choices[i].length())
52  {
53  if(selection == i || event.bstate & BUTTON1_DOUBLE_CLICKED)
54  hit = true;
55  selection = i;
56  }
57  }
58  if(!hit)
59  break;
60 
61  // fall through to next case
62  [[fallthrough]];
63  }
64 
65  case KEY_ENT:
66  if(selection == choices.size() - 1) // exit
67  key = -1; // do return from view
68  else
69  ret = calls[selection];
70  break;
71  default:
72  break;
73  }
74  repaint();
75  return ret;
76 }
diff --git a/docs/html/view__selection_8h_source.html b/docs/html/view__selection_8h_source.html index 0e73ba7..7ad7847 100644 --- a/docs/html/view__selection_8h_source.html +++ b/docs/html/view__selection_8h_source.html @@ -75,7 +75,7 @@ $(function() {