B15F Board 15 Famulus Edition

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
11 B15F &B15F::getInstance(void)
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 {
24 delay_ms(RECONNECT_TIMEOUT);
25 discard();
26
27 try
28 {
29 testConnection();
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
64 void B15F::testConnection()
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
200 void B15F::activateSelfTestMode()
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
540 uint16_t* B15F::getInterruptCounterOffset()
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 }
B15F::testIntConv
void testIntConv(void)
Definition: b15f.cpp:83
B15F::pwmSetValue
void pwmSetValue(uint8_t value)
Definition: b15f.cpp:431
B15F::exec
static std::string exec(std::string cmd)
Definition: b15f.cpp:153
B15F::analogWrite0
void analogWrite0(uint16_t port)
Definition: b15f.cpp:296
B15F::setServoPosition
void setServoPosition(uint16_t pos)
Definition: b15f.cpp:589
B15F::analogWrite1
void analogWrite1(uint16_t port)
Definition: b15f.cpp:313
B15F::getMem16
uint16_t getMem16(volatile uint16_t *adr)
Definition: b15f.cpp:509
B15F::delay_us
void delay_us(uint16_t us)
Definition: b15f.cpp:140
B15F::digitalRead0
uint8_t digitalRead0(void)
Definition: b15f.cpp:245
B15F::pwmSetFrequency
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:410
B15F::digitalWrite0
void digitalWrite0(uint8_t)
Definition: b15f.cpp:213
B15F::analogSequence
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
B15F::readDipSwitch
uint8_t readDipSwitch(void)
Definition: b15f.cpp:277
B15F::getRegister
uint8_t getRegister(volatile uint8_t *adr)
Definition: b15f.cpp:533
B15F::getMem8
uint8_t getMem8(volatile uint8_t *adr)
Definition: b15f.cpp:469
B15F::delay_ms
void delay_ms(uint16_t ms)
Definition: b15f.cpp:135
B15F::testConnection
void testConnection(void)
Definition: b15f.cpp:63
B15F::getInstance
static B15F & getInstance(void)
Definition: b15f.cpp:10
B15F
Definition: b15f.h:38
USART::transmit
void transmit(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:75
B15F::abort
static void abort(std::string msg)
Definition: b15f.cpp:169
USART::receive
void receive(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:84
USART::clearInputBuffer
void clearInputBuffer(void)
Definition: usart.cpp:54
B15F::getInterruptCounterOffset
uint16_t * getInterruptCounterOffset(void)
Definition: b15f.cpp:538
B15F::setMem16
void setMem16(volatile uint16_t *adr, uint16_t val)
Definition: b15f.cpp:488
USART::clearOutputBuffer
void clearOutputBuffer(void)
Definition: usart.cpp:61
B15F::analogRead
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:330
B15F::activateSelfTestMode
void activateSelfTestMode(void)
Definition: b15f.cpp:198
B15F::PRE
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:310
B15F::reverse
void reverse(uint8_t &b)
Definition: b15f.cpp:145
USART::setBaudrate
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:131
B15F::getBoardInfo
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:103
B15F::RECONNECT_TIMEOUT
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:313
B15F::discard
void discard(void)
Definition: b15f.cpp:40
B15F::setRegister
void setRegister(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:528
B15F::MSG_OK
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:311
USART::openDevice
void openDevice(std::string device)
Definition: usart.cpp:9
B15F::digitalRead1
uint8_t digitalRead1(void)
Definition: b15f.cpp:261
B15F::reconnect
void reconnect(void)
Definition: b15f.cpp:18
B15F::BAUDRATE
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:316
B15F::setAbortHandler
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:186
USART::drop
void drop(uint8_t len)
Definition: usart.cpp:114
B15F::digitalWrite1
void digitalWrite1(uint8_t)
Definition: b15f.cpp:229
B15F::setServoEnabled
void setServoEnabled(void)
Definition: b15f.cpp:555
B15F::RECONNECT_TRIES
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:315
B15F::setMem8
void setMem8(volatile uint8_t *adr, uint8_t val)
Definition: b15f.cpp:449
B15F::setServoDisabled
void setServoDisabled(void)
Definition: b15f.cpp:572
DriverException
Definition: driverexception.h:10