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 B15F::B15F()
7 {
8  init();
9 }
10 
11 void B15F::init()
12 {
13 
14  std::string device = exec("bash -c 'ls /dev/ttyUSB*'");
15  while(device.find(' ') != std::string::npos || device.find('\n') != std::string::npos || device.find('\t') != std::string::npos)
16  device.pop_back();
17 
18  if(device.length() == 0)
19  abort("Adapter nicht gefunden");
20 
21  std::cout << PRE << "Verwende Adapter: " << device << std::endl;
22 
23 
24 
25  std::cout << PRE << "Stelle Verbindung mit Adapter her... " << std::flush;
26  usart.setBaudrate(BAUDRATE);
27  usart.openDevice(device);
28  std::cout << "OK" << std::endl;
29 
30 
31 
32  std::cout << PRE << "Teste Verbindung... " << std::flush;
33  uint8_t tries = 3;
34  while(tries--)
35  {
36  // verwerfe Daten, die µC noch hat
37  //discard();
38 
39  if(!testConnection())
40  continue;
41 
42  if(!testIntConv())
43  continue;
44 
45  break;
46  }
47  if(tries == 0)
48  abort("Verbindungstest fehlgeschlagen. Neueste Version im Einsatz?");
49  std::cout << "OK" << std::endl;
50 
51 
52  // Gib board info aus
53  std::vector<std::string> info = getBoardInfo();
54  std::cout << PRE << "AVR Firmware Version: " << info[0] << " um " << info[1] << " Uhr (" << info[2] << ")" << std::endl;
55 }
56 
58 {
59  uint8_t tries = RECONNECT_TRIES;
60  while(tries--)
61  {
62  delay_ms(RECONNECT_TIMEOUT);
63  discard();
64 
65  if(testConnection())
66  return;
67  }
68 
69  abort("Verbindung kann nicht repariert werden");
70 }
71 
72 void B15F::discard(void)
73 {
74  try
75  {
76  usart.clearOutputBuffer();
77  for(uint8_t i = 0; i < 16; i++)
78  {
79  usart.writeByte(RQ_DISC); // sende discard Befehl (verwerfe input)
80  delay_ms(4);
81  }
82  usart.clearInputBuffer();
83  }
84  catch(std::exception& ex)
85  {
86  abort(ex);
87  }
88 }
89 
91 {
92  // erzeuge zufälliges Byte
93  srand(time(NULL));
94  uint8_t dummy = rand() % 256;
95 
96  usart.writeByte(RQ_TEST);
97  usart.writeByte(dummy);
98 
99  uint8_t aw = usart.readByte();
100  uint8_t mirror = usart.readByte();
101 
102  return aw == MSG_OK && mirror == dummy;
103 }
104 
106 {
107  srand(time(NULL));
108  uint16_t dummy = rand() % (0xFFFF / 3);
109 
110  usart.writeByte(RQ_INT);
111  usart.writeInt(dummy);
112 
113  uint16_t aw = usart.readInt();
114  return aw == dummy * 3;
115 }
116 
117 
118 std::vector<std::string> B15F::getBoardInfo(void)
119 {
120  std::vector<std::string> info;
121 
122  usart.writeByte(RQ_INFO);
123 
124  uint8_t n = usart.readByte();
125  while(n--)
126  {
127  uint8_t len = usart.readByte();
128  std::string str;
129 
130  while(len--) {
131  str += static_cast<char>(usart.readByte());
132  }
133 
134  info.push_back(str);
135  }
136 
137  uint8_t aw = usart.readByte();
138  if(aw != MSG_OK)
139  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
140 
141  return info;
142 }
143 
145 {
146  usart.writeByte(RQ_ST);
147 
148  uint8_t aw = usart.readByte();
149  return aw == MSG_OK;
150 }
151 
152 bool B15F::digitalWrite0(uint8_t port)
153 {
154  usart.writeByte(RQ_BA0);
155  usart.writeByte(port);
156 
157  uint8_t aw = usart.readByte();
158  delay_us(10);
159  return aw == MSG_OK;
160 }
161 
162 bool B15F::digitalWrite1(uint8_t port)
163 {
164  usart.writeByte(RQ_BA1);
165  usart.writeByte(port);
166 
167  uint8_t aw = usart.readByte();
168  delay_us(10);
169  return aw == MSG_OK;
170 }
171 
173 {
174  usart.clearInputBuffer();
175  usart.writeByte(RQ_BE0);
176  uint8_t byte = usart.readByte();
177  delay_us(10);
178  return byte;
179 }
180 
182 {
183  usart.clearInputBuffer();
184  usart.writeByte(RQ_BE1);
185  uint8_t byte = usart.readByte();
186  delay_us(10);
187  return byte;
188 }
189 
191 {
192  usart.clearInputBuffer();
193  usart.writeByte(RQ_DSW);
194  uint8_t byte = usart.readByte();
195  delay_us(10);
196  return byte;
197 }
198 
199 bool B15F::analogWrite0(uint16_t value)
200 {
201  usart.writeByte(RQ_AA0);
202  usart.writeInt(value);
203 
204  uint8_t aw = usart.readByte();
205  delay_us(10);
206  return aw == MSG_OK;
207 }
208 
209 bool B15F::analogWrite1(uint16_t value)
210 {
211  usart.writeByte(RQ_AA1);
212  usart.writeInt(value);
213 
214  uint8_t aw = usart.readByte();
215  delay_us(10);
216  return aw == MSG_OK;
217 }
218 
219 uint16_t B15F::analogRead(uint8_t channel)
220 {
221  usart.clearInputBuffer();
222  if(channel > 7)
223  abort("Bad ADC channel: " + std::to_string(channel));
224 
225  uint8_t rq[] = {
226  RQ_ADC,
227  channel
228  };
229 
230  int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000);
231  if(n_sent != sizeof(rq))
232  abort("Sent failed");
233 
234  uint16_t adc = usart.readInt();
235 
236  if(adc > 1023)
237  abort("Bad ADC data detected (1)");
238  return adc;
239 }
240 
241 void B15F::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)
242 {
243  // check pointers
244  buffer_a += offset_a;
245  buffer_b += offset_b;
246 
247 
248  usart.clearInputBuffer();
249  usart.writeByte(RQ_ADC_DAC_STROKE);
250  usart.writeByte(channel_a);
251  usart.writeByte(channel_b);
252  usart.writeInt(start);
253  usart.writeInt(static_cast<uint16_t>(delta));
254  usart.writeInt(count);
255 
256  for(uint16_t i = 0; i < count; i++)
257  {
258  if(buffer_a)
259  {
260  buffer_a[i] = usart.readInt();
261 
262  if(buffer_a[i] > 1023) // check for broken usart connection
263  abort("Bad ADC data detected (2)");
264  }
265  else
266  {
267  usart.readInt();
268  }
269 
270  if(buffer_b)
271  {
272  buffer_b[i] = usart.readInt();
273 
274  if(buffer_b[i] > 1023) // check for broken usart connection
275  abort("Bad ADC data detected (3)");
276  }
277  else
278  {
279  usart.readInt();
280  }
281  }
282 
283  uint8_t aw = usart.readByte();
284  if(aw != MSG_OK)
285  abort("Sequenz unterbrochen");
286 
287  delay_us(10);
288 }
289 
290 void B15F::delay_ms(uint16_t ms)
291 {
292  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
293 }
294 
295 void B15F::delay_us(uint16_t us)
296 {
297  std::this_thread::sleep_for(std::chrono::microseconds(us));
298 }
299 
301 {
302  if(!instance)
303  instance = new B15F();
304 
305  return *instance;
306 }
307 
308 // https://stackoverflow.com/a/478960
309 std::string B15F::exec(std::string cmd) {
310  std::array<char, 128> buffer;
311  std::string result;
312  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
313  if (!pipe) {
314  throw std::runtime_error("popen() failed!");
315  }
316  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
317  result += buffer.data();
318  }
319  return result;
320 }
321 
322 void B15F::abort(std::string msg)
323 {
324  DriverException ex(msg);
325  abort(ex);
326 }
327 void B15F::abort(std::exception& ex)
328 {
329  if(errorhandler)
330  errorhandler(ex);
331  else
332  {
333  std::cerr << "NOTICE: B15F::errorhandler not set" << std::endl;
334  std::cout << ex.what() << std::endl;
335  throw DriverException(ex.what());
336  }
337 }
338 
339 void B15F::setAbortHandler(errorhandler_t func)
340 {
341  errorhandler = func;
342 }
B15F::exec
static std::string exec(std::string cmd)
Definition: b15f.cpp:309
USART::readByte
uint8_t readByte(void)
Definition: usart.cpp:210
B15F::delay_us
void delay_us(uint16_t us)
Definition: b15f.cpp:295
B15F::digitalRead0
uint8_t digitalRead0(void)
Definition: b15f.cpp:172
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:241
B15F::testConnection
bool testConnection(void)
Definition: b15f.cpp:90
B15F::readDipSwitch
uint8_t readDipSwitch(void)
Definition: b15f.cpp:190
B15F::delay_ms
void delay_ms(uint16_t ms)
Definition: b15f.cpp:290
B15F::analogWrite1
bool analogWrite1(uint16_t)
Definition: b15f.cpp:209
B15F::getInstance
static B15F & getInstance(void)
Definition: b15f.cpp:300
B15F
Definition: b15f.h:24
B15F::abort
static void abort(std::string msg)
Definition: b15f.cpp:322
USART::clearInputBuffer
void clearInputBuffer(void)
Definition: usart.cpp:39
USART::clearOutputBuffer
void clearOutputBuffer(void)
Definition: usart.cpp:46
B15F::analogRead
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:219
B15F::digitalWrite0
bool digitalWrite0(uint8_t)
Definition: b15f.cpp:152
USART::setBaudrate
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:316
B15F::activateSelfTestMode
bool activateSelfTestMode(void)
Definition: b15f.cpp:144
B15F::getBoardInfo
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:118
USART::writeByte
void writeByte(uint8_t b)
Definition: usart.cpp:67
B15F::digitalWrite1
bool digitalWrite1(uint8_t)
Definition: b15f.cpp:162
B15F::discard
void discard(void)
Definition: b15f.cpp:72
B15F::analogWrite0
bool analogWrite0(uint16_t)
Definition: b15f.cpp:199
USART::openDevice
void openDevice(std::string device)
Definition: usart.cpp:3
USART::readInt
uint16_t readInt(void)
Definition: usart.cpp:229
B15F::digitalRead1
uint8_t digitalRead1(void)
Definition: b15f.cpp:181
B15F::reconnect
void reconnect(void)
Definition: b15f.cpp:57
B15F::setAbortHandler
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:339
USART::writeInt
void writeInt(uint16_t d)
Definition: usart.cpp:81
B15F::testIntConv
bool testIntConv(void)
Definition: b15f.cpp:105
DriverException
Definition: driverexception.h:8