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