From 2c47159df3dd33d3d1a423b902227b7bec26ac5a Mon Sep 17 00:00:00 2001 From: Tristan Krause Date: Tue, 28 May 2019 12:32:31 +0200 Subject: [PATCH] PWM ansteuerbar und TOP wird returned --- control/bin/b15fcli | Bin 0 -> 89776 bytes control/examples/pwm/Makefile | 30 +++++++ control/examples/pwm/main.cpp | 14 +++ control/src/drv/b15f.cpp | 41 +++++++++ control/src/drv/b15f.h | 18 ++++ control/src/drv/usart.cpp | 7 +- control/src/drv/usart.h | 9 +- docs/html/annotated.html | 2 +- docs/html/b15f_8cpp_source.html | 34 +++---- docs/html/b15f_8h_source.html | 32 +++---- docs/html/classB15F-members.html | 4 +- docs/html/classB15F.html | 85 ++++++++++++++++-- docs/html/classDot-members.html | 2 +- docs/html/classDot.html | 2 +- docs/html/classDriverException-members.html | 2 +- docs/html/classDriverException.html | 2 +- docs/html/classPlottyFile-members.html | 2 +- docs/html/classPlottyFile.html | 2 +- docs/html/classTimeoutException-members.html | 2 +- docs/html/classTimeoutException.html | 2 +- docs/html/classUSART-members.html | 3 +- docs/html/classUSART.html | 50 +++++++++-- docs/html/classUSARTException-members.html | 2 +- docs/html/classUSARTException.html | 2 +- docs/html/classView-members.html | 2 +- docs/html/classView.html | 2 +- docs/html/classViewInfo-members.html | 2 +- docs/html/classViewInfo.html | 2 +- docs/html/classViewMonitor-members.html | 2 +- docs/html/classViewMonitor.html | 2 +- docs/html/classViewPromt-members.html | 2 +- docs/html/classViewPromt.html | 2 +- docs/html/classViewSelection-members.html | 2 +- docs/html/classViewSelection.html | 2 +- docs/html/classes.html | 2 +- docs/html/cli_8cpp_source.html | 6 +- .../dir_1788f8309b1a812dcb800a185471cf6c.html | 2 +- .../dir_587c94d866dbb2f408f78cf41f9b2f8d.html | 2 +- docs/html/dot_8cpp_source.html | 2 +- docs/html/dot_8h_source.html | 2 +- docs/html/driverexception_8h_source.html | 2 +- docs/html/files.html | 2 +- docs/html/functions.html | 11 ++- docs/html/functions_func.html | 11 ++- docs/html/functions_vars.html | 2 +- docs/html/hierarchy.html | 2 +- docs/html/index.html | 2 +- docs/html/plottyfile_8cpp_source.html | 2 +- docs/html/plottyfile_8h_source.html | 2 +- docs/html/search/all_9.js | 4 +- docs/html/search/all_f.js | 3 +- docs/html/search/functions_7.js | 4 +- docs/html/search/functions_b.js | 3 +- docs/html/timeoutexception_8h_source.html | 2 +- docs/html/ui_8cpp_source.html | 8 +- docs/html/ui_8h_source.html | 2 +- docs/html/usart_8cpp_source.html | 17 ++-- docs/html/usart_8h_source.html | 17 ++-- docs/html/usartexception_8h_source.html | 2 +- docs/html/view_8cpp_source.html | 4 +- docs/html/view_8h_source.html | 2 +- docs/html/view__info_8cpp_source.html | 2 +- docs/html/view__info_8h_source.html | 2 +- docs/html/view__monitor_8cpp_source.html | 8 +- docs/html/view__monitor_8h_source.html | 2 +- docs/html/view__promt_8cpp_source.html | 2 +- docs/html/view__promt_8h_source.html | 2 +- docs/html/view__selection_8cpp_source.html | 2 +- docs/html/view__selection_8h_source.html | 2 +- firmware/global_vars.cpp | 1 + firmware/global_vars.h | 2 + firmware/main.cpp | 2 + firmware/pwm.cpp | 30 +++++-- firmware/pwm.h | 17 ++-- firmware/requests.cpp | 22 ++++- firmware/requests.h | 9 +- firmware/usart.cpp | 7 ++ firmware/usart.h | 6 ++ 78 files changed, 459 insertions(+), 148 deletions(-) create mode 100755 control/bin/b15fcli create mode 100644 control/examples/pwm/Makefile create mode 100644 control/examples/pwm/main.cpp diff --git a/control/bin/b15fcli b/control/bin/b15fcli new file mode 100755 index 0000000000000000000000000000000000000000..864a09cf34677967f19d0897dcce89ccb8ca853f GIT binary patch literal 89776 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 +#include +#include +#include + +const char PLOT_FILE[] = "plot.bin"; + +int main() +{ + + B15F& drv = B15F::getInstance(); + std::cout << "TOP: " << (int) drv.pwmSetFrequency(100000) << std::endl; + drv.pwmSetValue(40); +} diff --git a/control/src/drv/b15f.cpp b/control/src/drv/b15f.cpp index 0204cc6..56cb2ed 100644 --- a/control/src/drv/b15f.cpp +++ b/control/src/drv/b15f.cpp @@ -289,6 +289,47 @@ void B15F::analogSequence(uint8_t channel_a, uint16_t* buffer_a, uint32_t offset delay_us(10); } +uint8_t B15F::pwmSetFrequency(uint32_t freq) +{ + usart.clearInputBuffer(); + + uint8_t rq[] = + { + RQ_PWM_SET_FREQ, + static_cast((freq >> 0) & 0xFF), + static_cast((freq >> 8) & 0xFF), + static_cast((freq >> 16) & 0xFF), + static_cast((freq >> 24) & 0xFF) + }; + + int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000); + if(n_sent != sizeof(rq)) + abort("Sent failed"); + + uint8_t byte = usart.readByte(); + delay_us(10); + return byte; +} + +bool B15F::pwmSetValue(uint8_t value) +{ + usart.clearInputBuffer(); + + uint8_t rq[] = + { + RQ_PWM_SET_VALUE, + value + }; + + int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000); + if(n_sent != sizeof(rq)) + abort("Sent failed"); + + uint8_t aw = usart.readByte(); + delay_us(10); + return aw == MSG_OK; +} + void B15F::delay_ms(uint16_t ms) { std::this_thread::sleep_for(std::chrono::milliseconds(ms)); diff --git a/control/src/drv/b15f.h b/control/src/drv/b15f.h index 88172ba..1b011ea 100644 --- a/control/src/drv/b15f.h +++ b/control/src/drv/b15f.h @@ -194,6 +194,22 @@ public: */ 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); + /** + * Setzt die Register so, dass näherungsweise die gewünschte Frequenz erzeugt wird. + * Ist freq == 0 wird PWM deaktiviert. + * \param freq PWM Frequenz + * \return Top Wert des PWM Value für die gesetzte Frequenz + * \throws DriverException + */ + uint8_t pwmSetFrequency(uint32_t freq); + + /** + * Setzt den PWM Wert. + * \param value PWM Wert [0..0xFF] + * \throws DriverException + */ + bool pwmSetValue(uint8_t value); + /*************************/ @@ -233,6 +249,8 @@ private: constexpr static uint8_t RQ_AA1 = 11; constexpr static uint8_t RQ_ADC = 12; constexpr static uint8_t RQ_ADC_DAC_STROKE = 13; + constexpr static uint8_t RQ_PWM_SET_FREQ = 14; + constexpr static uint8_t RQ_PWM_SET_VALUE = 15; }; #endif // B15F_H diff --git a/control/src/drv/usart.cpp b/control/src/drv/usart.cpp index dcc7dd9..0717d41 100644 --- a/control/src/drv/usart.cpp +++ b/control/src/drv/usart.cpp @@ -85,7 +85,12 @@ void USART::writeInt(uint16_t d) throw USARTException("Fehler beim Senden: writeInt()"); } - +void USART::writeU32(uint32_t w) +{ + int sent = write(file_desc, reinterpret_cast(&w), 4); + if(sent != 4) + throw USARTException("Fehler beim Senden: writeU32()"); +} int USART::read_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout) { diff --git a/control/src/drv/usart.h b/control/src/drv/usart.h index de2719f..762bed6 100644 --- a/control/src/drv/usart.h +++ b/control/src/drv/usart.h @@ -76,11 +76,18 @@ public: /** * Sendet ein Integer über die USART Schnittstelle - * \param b das zu sendende Byte + * \param b das zu sendende Int * \throws USARTException */ void writeInt(uint16_t d); + /** + * Sendet ein uint32_t über die USART Schnittstelle + * \param b das zu sendende uint32_t + * \throws USARTException + */ + void writeU32(uint32_t d); + /** * Empfängt ein Byte über die USART Schnittstelle * \throws USARTException diff --git a/docs/html/annotated.html b/docs/html/annotated.html index e8fa8b6..709b184 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 5efca6f..dd5733f 100644 --- a/docs/html/b15f_8cpp_source.html +++ b/docs/html/b15f_8cpp_source.html @@ -70,46 +70,48 @@ $(function() {
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  {
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  {
132  str += static_cast<char>(usart.readByte());
133  }
134 
135  info.push_back(str);
136  }
137 
138  uint8_t aw = usart.readByte();
139  if(aw != MSG_OK)
140  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
141 
142  return info;
143 }
144 
146 {
147  usart.writeByte(RQ_ST);
148 
149  uint8_t aw = usart.readByte();
150  return aw == MSG_OK;
151 }
152 
153 bool B15F::digitalWrite0(uint8_t port)
154 {
155  usart.writeByte(RQ_BA0);
156  usart.writeByte(port);
157 
158  uint8_t aw = usart.readByte();
159  delay_us(10);
160  return aw == MSG_OK;
161 }
162 
163 bool B15F::digitalWrite1(uint8_t port)
164 {
165  usart.writeByte(RQ_BA1);
166  usart.writeByte(port);
167 
168  uint8_t aw = usart.readByte();
169  delay_us(10);
170  return aw == MSG_OK;
171 }
172 
174 {
175  usart.clearInputBuffer();
176  usart.writeByte(RQ_BE0);
177  uint8_t byte = usart.readByte();
178  delay_us(10);
179  return byte;
180 }
181 
183 {
184  usart.clearInputBuffer();
185  usart.writeByte(RQ_BE1);
186  uint8_t byte = usart.readByte();
187  delay_us(10);
188  return byte;
189 }
190 
192 {
193  usart.clearInputBuffer();
194  usart.writeByte(RQ_DSW);
195  uint8_t byte = usart.readByte();
196  delay_us(10);
197  return byte;
198 }
199 
200 bool B15F::analogWrite0(uint16_t value)
201 {
202  usart.writeByte(RQ_AA0);
203  usart.writeInt(value);
204 
205  uint8_t aw = usart.readByte();
206  delay_us(10);
207  return aw == MSG_OK;
208 }
209 
210 bool B15F::analogWrite1(uint16_t value)
211 {
212  usart.writeByte(RQ_AA1);
213  usart.writeInt(value);
214 
215  uint8_t aw = usart.readByte();
216  delay_us(10);
217  return aw == MSG_OK;
218 }
219 
220 uint16_t B15F::analogRead(uint8_t channel)
221 {
222  usart.clearInputBuffer();
223  if(channel > 7)
224  abort("Bad ADC channel: " + std::to_string(channel));
225 
226  uint8_t rq[] =
227  {
228  RQ_ADC,
229  channel
230  };
231 
232  int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000);
233  if(n_sent != sizeof(rq))
234  abort("Sent failed");
235 
236  uint16_t adc = usart.readInt();
237 
238  if(adc > 1023)
239  abort("Bad ADC data detected (1)");
240  return adc;
241 }
242 
243 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)
244 {
245  // check pointers
246  buffer_a += offset_a;
247  buffer_b += offset_b;
248 
249 
250  usart.clearInputBuffer();
251  usart.writeByte(RQ_ADC_DAC_STROKE);
252  usart.writeByte(channel_a);
253  usart.writeByte(channel_b);
254  usart.writeInt(start);
255  usart.writeInt(static_cast<uint16_t>(delta));
256  usart.writeInt(count);
257 
258  for(uint16_t i = 0; i < count; i++)
259  {
260  if(buffer_a)
261  {
262  buffer_a[i] = usart.readInt();
263 
264  if(buffer_a[i] > 1023) // check for broken usart connection
265  abort("Bad ADC data detected (2)");
266  }
267  else
268  {
269  usart.readInt();
270  }
271 
272  if(buffer_b)
273  {
274  buffer_b[i] = usart.readInt();
275 
276  if(buffer_b[i] > 1023) // check for broken usart connection
277  abort("Bad ADC data detected (3)");
278  }
279  else
280  {
281  usart.readInt();
282  }
283  }
284 
285  uint8_t aw = usart.readByte();
286  if(aw != MSG_OK)
287  abort("Sequenz unterbrochen");
288 
289  delay_us(10);
290 }
291 
292 void B15F::delay_ms(uint16_t ms)
293 {
294  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
295 }
296 
297 void B15F::delay_us(uint16_t us)
298 {
299  std::this_thread::sleep_for(std::chrono::microseconds(us));
300 }
301 
303 {
304  if(!instance)
305  instance = new B15F();
306 
307  return *instance;
308 }
309 
310 // https://stackoverflow.com/a/478960
311 std::string B15F::exec(std::string cmd)
312 {
313  std::array<char, 128> buffer;
314  std::string result;
315  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
316  if (!pipe)
317  {
318  throw std::runtime_error("popen() failed!");
319  }
320  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
321  {
322  result += buffer.data();
323  }
324  return result;
325 }
326 
327 void B15F::abort(std::string msg)
328 {
329  DriverException ex(msg);
330  abort(ex);
331 }
332 void B15F::abort(std::exception& ex)
333 {
334  if(errorhandler)
335  errorhandler(ex);
336  else
337  {
338  std::cerr << "NOTICE: B15F::errorhandler not set" << std::endl;
339  std::cout << ex.what() << std::endl;
340  throw DriverException(ex.what());
341  }
342 }
343 
344 void B15F::setAbortHandler(errorhandler_t func)
345 {
346  errorhandler = func;
347 }
-
static std::string exec(std::string cmd)
Definition: b15f.cpp:311
-
uint8_t readByte(void)
Definition: usart.cpp:211
-
void delay_us(uint16_t us)
Definition: b15f.cpp:297
+
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  {
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  {
132  str += static_cast<char>(usart.readByte());
133  }
134 
135  info.push_back(str);
136  }
137 
138  uint8_t aw = usart.readByte();
139  if(aw != MSG_OK)
140  abort("Board Info fehlerhalft: code " + std::to_string((int) aw));
141 
142  return info;
143 }
144 
146 {
147  usart.writeByte(RQ_ST);
148 
149  uint8_t aw = usart.readByte();
150  return aw == MSG_OK;
151 }
152 
153 bool B15F::digitalWrite0(uint8_t port)
154 {
155  usart.writeByte(RQ_BA0);
156  usart.writeByte(port);
157 
158  uint8_t aw = usart.readByte();
159  delay_us(10);
160  return aw == MSG_OK;
161 }
162 
163 bool B15F::digitalWrite1(uint8_t port)
164 {
165  usart.writeByte(RQ_BA1);
166  usart.writeByte(port);
167 
168  uint8_t aw = usart.readByte();
169  delay_us(10);
170  return aw == MSG_OK;
171 }
172 
174 {
175  usart.clearInputBuffer();
176  usart.writeByte(RQ_BE0);
177  uint8_t byte = usart.readByte();
178  delay_us(10);
179  return byte;
180 }
181 
183 {
184  usart.clearInputBuffer();
185  usart.writeByte(RQ_BE1);
186  uint8_t byte = usart.readByte();
187  delay_us(10);
188  return byte;
189 }
190 
192 {
193  usart.clearInputBuffer();
194  usart.writeByte(RQ_DSW);
195  uint8_t byte = usart.readByte();
196  delay_us(10);
197  return byte;
198 }
199 
200 bool B15F::analogWrite0(uint16_t value)
201 {
202  usart.writeByte(RQ_AA0);
203  usart.writeInt(value);
204 
205  uint8_t aw = usart.readByte();
206  delay_us(10);
207  return aw == MSG_OK;
208 }
209 
210 bool B15F::analogWrite1(uint16_t value)
211 {
212  usart.writeByte(RQ_AA1);
213  usart.writeInt(value);
214 
215  uint8_t aw = usart.readByte();
216  delay_us(10);
217  return aw == MSG_OK;
218 }
219 
220 uint16_t B15F::analogRead(uint8_t channel)
221 {
222  usart.clearInputBuffer();
223  if(channel > 7)
224  abort("Bad ADC channel: " + std::to_string(channel));
225 
226  uint8_t rq[] =
227  {
228  RQ_ADC,
229  channel
230  };
231 
232  int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000);
233  if(n_sent != sizeof(rq))
234  abort("Sent failed");
235 
236  uint16_t adc = usart.readInt();
237 
238  if(adc > 1023)
239  abort("Bad ADC data detected (1)");
240  return adc;
241 }
242 
243 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)
244 {
245  // check pointers
246  buffer_a += offset_a;
247  buffer_b += offset_b;
248 
249 
250  usart.clearInputBuffer();
251  usart.writeByte(RQ_ADC_DAC_STROKE);
252  usart.writeByte(channel_a);
253  usart.writeByte(channel_b);
254  usart.writeInt(start);
255  usart.writeInt(static_cast<uint16_t>(delta));
256  usart.writeInt(count);
257 
258  for(uint16_t i = 0; i < count; i++)
259  {
260  if(buffer_a)
261  {
262  buffer_a[i] = usart.readInt();
263 
264  if(buffer_a[i] > 1023) // check for broken usart connection
265  abort("Bad ADC data detected (2)");
266  }
267  else
268  {
269  usart.readInt();
270  }
271 
272  if(buffer_b)
273  {
274  buffer_b[i] = usart.readInt();
275 
276  if(buffer_b[i] > 1023) // check for broken usart connection
277  abort("Bad ADC data detected (3)");
278  }
279  else
280  {
281  usart.readInt();
282  }
283  }
284 
285  uint8_t aw = usart.readByte();
286  if(aw != MSG_OK)
287  abort("Sequenz unterbrochen");
288 
289  delay_us(10);
290 }
291 
292 uint8_t B15F::pwmSetFrequency(uint32_t freq)
293 {
294  usart.clearInputBuffer();
295 
296  uint8_t rq[] =
297  {
298  RQ_PWM_SET_FREQ,
299  static_cast<uint8_t>((freq >> 0) & 0xFF),
300  static_cast<uint8_t>((freq >> 8) & 0xFF),
301  static_cast<uint8_t>((freq >> 16) & 0xFF),
302  static_cast<uint8_t>((freq >> 24) & 0xFF)
303  };
304 
305  int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000);
306  if(n_sent != sizeof(rq))
307  abort("Sent failed");
308 
309  uint8_t byte = usart.readByte();
310  delay_us(10);
311  return byte;
312 }
313 
314 bool B15F::pwmSetValue(uint8_t value)
315 {
316  usart.clearInputBuffer();
317 
318  uint8_t rq[] =
319  {
320  RQ_PWM_SET_VALUE,
321  value
322  };
323 
324  int n_sent = usart.write_timeout(&rq[0], 0, sizeof(rq), 1000);
325  if(n_sent != sizeof(rq))
326  abort("Sent failed");
327 
328  uint8_t aw = usart.readByte();
329  delay_us(10);
330  return aw == MSG_OK;
331 }
332 
333 void B15F::delay_ms(uint16_t ms)
334 {
335  std::this_thread::sleep_for(std::chrono::milliseconds(ms));
336 }
337 
338 void B15F::delay_us(uint16_t us)
339 {
340  std::this_thread::sleep_for(std::chrono::microseconds(us));
341 }
342 
344 {
345  if(!instance)
346  instance = new B15F();
347 
348  return *instance;
349 }
350 
351 // https://stackoverflow.com/a/478960
352 std::string B15F::exec(std::string cmd)
353 {
354  std::array<char, 128> buffer;
355  std::string result;
356  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
357  if (!pipe)
358  {
359  throw std::runtime_error("popen() failed!");
360  }
361  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
362  {
363  result += buffer.data();
364  }
365  return result;
366 }
367 
368 void B15F::abort(std::string msg)
369 {
370  DriverException ex(msg);
371  abort(ex);
372 }
373 void B15F::abort(std::exception& ex)
374 {
375  if(errorhandler)
376  errorhandler(ex);
377  else
378  {
379  std::cerr << "NOTICE: B15F::errorhandler not set" << std::endl;
380  std::cout << ex.what() << std::endl;
381  throw DriverException(ex.what());
382  }
383 }
384 
385 void B15F::setAbortHandler(errorhandler_t func)
386 {
387  errorhandler = func;
388 }
+
static std::string exec(std::string cmd)
Definition: b15f.cpp:352
+
uint8_t readByte(void)
Definition: usart.cpp:216
+
void delay_us(uint16_t us)
Definition: b15f.cpp:338
uint8_t digitalRead0(void)
Definition: b15f.cpp:173
+
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:292
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:243
bool testConnection(void)
Definition: b15f.cpp:90
uint8_t readDipSwitch(void)
Definition: b15f.cpp:191
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:292
-
static B15F & getInstance(void)
Definition: b15f.cpp:302
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:333
+
static B15F & getInstance(void)
Definition: b15f.cpp:343
Definition: b15f.h:26
-
static void abort(std::string msg)
Definition: b15f.cpp:327
+
static void abort(std::string msg)
Definition: b15f.cpp:368
void clearInputBuffer(void)
Definition: usart.cpp:39
void clearOutputBuffer(void)
Definition: usart.cpp:46
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:220
bool digitalWrite0(uint8_t)
Definition: b15f.cpp:153
-
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:199
-
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:317
+
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:215
+
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:322
bool activateSelfTestMode(void)
Definition: b15f.cpp:145
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:118
-
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:202
+
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:218
bool analogWrite1(uint16_t port)
Definition: b15f.cpp:210
void writeByte(uint8_t b)
Definition: usart.cpp:67
bool digitalWrite1(uint8_t)
Definition: b15f.cpp:163
+
bool pwmSetValue(uint8_t value)
Definition: b15f.cpp:314
void discard(void)
Definition: b15f.cpp:72
-
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:200
+
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:216
void openDevice(std::string device)
Definition: usart.cpp:3
-
uint16_t readInt(void)
Definition: usart.cpp:230
+
uint16_t readInt(void)
Definition: usart.cpp:235
uint8_t digitalRead1(void)
Definition: b15f.cpp:182
void reconnect(void)
Definition: b15f.cpp:57
-
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:205
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:344
+
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:221
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:385
bool analogWrite0(uint16_t port)
Definition: b15f.cpp:200
-
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:204
+
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:220
void writeInt(uint16_t d)
Definition: usart.cpp:81
bool testIntConv(void)
Definition: b15f.cpp:105
diff --git a/docs/html/b15f_8h_source.html b/docs/html/b15f_8h_source.html index 0f9eff8..346c23c 100644 --- a/docs/html/b15f_8h_source.html +++ b/docs/html/b15f_8h_source.html @@ -70,40 +70,42 @@ $(function() {
b15f.h
-
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 #include "usart.h"
18 #include "driverexception.h"
19 #include "timeoutexception.h"
20 
21 typedef std::function<void(std::exception&)> errorhandler_t;
22 
23 
26 class B15F
27 {
28 private:
29  // privater Konstruktor
30  B15F(void);
31 public:
32 
33  /*************************************
34  * Grundfunktionen des B15F Treibers *
35  *************************************/
36 
41  void reconnect(void);
42 
47  void discard(void);
48 
53  bool testConnection(void);
54 
59  bool testIntConv(void);
60 
65  std::vector<std::string> getBoardInfo(void);
66 
71  void delay_ms(uint16_t ms);
72 
77  void delay_us(uint16_t us);
78 
83  static B15F& getInstance(void);
84 
89  static std::string exec(std::string cmd);
90 
95  static void abort(std::string msg);
96 
101  static void abort(std::exception& ex);
102 
107  static void setAbortHandler(errorhandler_t func);
108 
109  /*************************************/
110 
111 
112 
113  /*************************
114  * Steuerbefehle für B15 *
115  *************************/
116 
122  bool activateSelfTestMode(void);
123 
129  bool digitalWrite0(uint8_t);
130 
136  bool digitalWrite1(uint8_t);
137 
143  uint8_t digitalRead0(void);
144 
150  uint8_t digitalRead1(void);
151 
157  uint8_t readDipSwitch(void);
158 
164  bool analogWrite0(uint16_t port);
165 
171  bool analogWrite1(uint16_t port);
172 
178  uint16_t analogRead(uint8_t channel);
179 
195  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);
196 
197  /*************************/
198 
199 
200  // CONSTANTS
201  const std::string PRE = "[B15F] ";
202  constexpr static uint8_t MSG_OK = 0xFF;
203  constexpr static uint8_t MSG_FAIL = 0xFE;
204  constexpr static uint16_t RECONNECT_TIMEOUT = 64;
205  constexpr static uint16_t WDT_TIMEOUT = 15;
206  constexpr static uint8_t RECONNECT_TRIES = 3;
207  constexpr static uint32_t BAUDRATE = 57600;
208 
209 private:
210 
215  void init(void);
216 
217  USART usart;
218  static B15F* instance;
219  static errorhandler_t errorhandler;
220 
221  // REQUESTS
222  constexpr static uint8_t RQ_DISC = 0;
223  constexpr static uint8_t RQ_TEST = 1;
224  constexpr static uint8_t RQ_INFO = 2;
225  constexpr static uint8_t RQ_INT = 3;
226  constexpr static uint8_t RQ_ST = 4;
227  constexpr static uint8_t RQ_BA0 = 5;
228  constexpr static uint8_t RQ_BA1 = 6;
229  constexpr static uint8_t RQ_BE0 = 7;
230  constexpr static uint8_t RQ_BE1 = 8;
231  constexpr static uint8_t RQ_DSW = 9;
232  constexpr static uint8_t RQ_AA0 = 10;
233  constexpr static uint8_t RQ_AA1 = 11;
234  constexpr static uint8_t RQ_ADC = 12;
235  constexpr static uint8_t RQ_ADC_DAC_STROKE = 13;
236 };
237 
238 #endif // B15F_H
-
static std::string exec(std::string cmd)
Definition: b15f.cpp:311
-
constexpr static uint8_t MSG_FAIL
Value to reject a received command.
Definition: b15f.h:201
-
void delay_us(uint16_t us)
Definition: b15f.cpp:297
+
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 #include "usart.h"
18 #include "driverexception.h"
19 #include "timeoutexception.h"
20 
21 typedef std::function<void(std::exception&)> errorhandler_t;
22 
23 
26 class B15F
27 {
28 private:
29  // privater Konstruktor
30  B15F(void);
31 public:
32 
33  /*************************************
34  * Grundfunktionen des B15F Treibers *
35  *************************************/
36 
41  void reconnect(void);
42 
47  void discard(void);
48 
53  bool testConnection(void);
54 
59  bool testIntConv(void);
60 
65  std::vector<std::string> getBoardInfo(void);
66 
71  void delay_ms(uint16_t ms);
72 
77  void delay_us(uint16_t us);
78 
83  static B15F& getInstance(void);
84 
89  static std::string exec(std::string cmd);
90 
95  static void abort(std::string msg);
96 
101  static void abort(std::exception& ex);
102 
107  static void setAbortHandler(errorhandler_t func);
108 
109  /*************************************/
110 
111 
112 
113  /*************************
114  * Steuerbefehle für B15 *
115  *************************/
116 
122  bool activateSelfTestMode(void);
123 
129  bool digitalWrite0(uint8_t);
130 
136  bool digitalWrite1(uint8_t);
137 
143  uint8_t digitalRead0(void);
144 
150  uint8_t digitalRead1(void);
151 
157  uint8_t readDipSwitch(void);
158 
164  bool analogWrite0(uint16_t port);
165 
171  bool analogWrite1(uint16_t port);
172 
178  uint16_t analogRead(uint8_t channel);
179 
195  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);
196 
204  uint8_t pwmSetFrequency(uint32_t freq);
205 
211  bool pwmSetValue(uint8_t value);
212 
213  /*************************/
214 
215 
216  // CONSTANTS
217  const std::string PRE = "[B15F] ";
218  constexpr static uint8_t MSG_OK = 0xFF;
219  constexpr static uint8_t MSG_FAIL = 0xFE;
220  constexpr static uint16_t RECONNECT_TIMEOUT = 64;
221  constexpr static uint16_t WDT_TIMEOUT = 15;
222  constexpr static uint8_t RECONNECT_TRIES = 3;
223  constexpr static uint32_t BAUDRATE = 57600;
224 
225 private:
226 
231  void init(void);
232 
233  USART usart;
234  static B15F* instance;
235  static errorhandler_t errorhandler;
236 
237  // REQUESTS
238  constexpr static uint8_t RQ_DISC = 0;
239  constexpr static uint8_t RQ_TEST = 1;
240  constexpr static uint8_t RQ_INFO = 2;
241  constexpr static uint8_t RQ_INT = 3;
242  constexpr static uint8_t RQ_ST = 4;
243  constexpr static uint8_t RQ_BA0 = 5;
244  constexpr static uint8_t RQ_BA1 = 6;
245  constexpr static uint8_t RQ_BE0 = 7;
246  constexpr static uint8_t RQ_BE1 = 8;
247  constexpr static uint8_t RQ_DSW = 9;
248  constexpr static uint8_t RQ_AA0 = 10;
249  constexpr static uint8_t RQ_AA1 = 11;
250  constexpr static uint8_t RQ_ADC = 12;
251  constexpr static uint8_t RQ_ADC_DAC_STROKE = 13;
252  constexpr static uint8_t RQ_PWM_SET_FREQ = 14;
253  constexpr static uint8_t RQ_PWM_SET_VALUE = 15;
254 };
255 
256 #endif // B15F_H
+
static std::string exec(std::string cmd)
Definition: b15f.cpp:352
+
constexpr static uint8_t MSG_FAIL
Value to reject a received command.
Definition: b15f.h:217
+
void delay_us(uint16_t us)
Definition: b15f.cpp:338
uint8_t digitalRead0(void)
Definition: b15f.cpp:173
+
uint8_t pwmSetFrequency(uint32_t freq)
Definition: b15f.cpp:292
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:243
bool testConnection(void)
Definition: b15f.cpp:90
uint8_t readDipSwitch(void)
Definition: b15f.cpp:191
-
void delay_ms(uint16_t ms)
Definition: b15f.cpp:292
-
static B15F & getInstance(void)
Definition: b15f.cpp:302
+
void delay_ms(uint16_t ms)
Definition: b15f.cpp:333
+
static B15F & getInstance(void)
Definition: b15f.cpp:343
Definition: b15f.h:26
-
static void abort(std::string msg)
Definition: b15f.cpp:327
+
static void abort(std::string msg)
Definition: b15f.cpp:368
Definition: usart.h:18
uint16_t analogRead(uint8_t channel)
Definition: b15f.cpp:220
bool digitalWrite0(uint8_t)
Definition: b15f.cpp:153
-
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:199
+
const std::string PRE
B15F stdout prefix.
Definition: b15f.h:215
bool activateSelfTestMode(void)
Definition: b15f.cpp:145
std::vector< std::string > getBoardInfo(void)
Definition: b15f.cpp:118
-
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:202
+
constexpr static uint16_t RECONNECT_TIMEOUT
Time in ms after which a reconnect attempt aborts.
Definition: b15f.h:218
bool analogWrite1(uint16_t port)
Definition: b15f.cpp:210
bool digitalWrite1(uint8_t)
Definition: b15f.cpp:163
+
bool pwmSetValue(uint8_t value)
Definition: b15f.cpp:314
void discard(void)
Definition: b15f.cpp:72
-
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:200
+
constexpr static uint8_t MSG_OK
Value to acknowledge a received command.
Definition: b15f.h:216
uint8_t digitalRead1(void)
Definition: b15f.cpp:182
-
constexpr static uint16_t WDT_TIMEOUT
Time in ms after which the watch dog timer resets the MCU.
Definition: b15f.h:203
+
constexpr static uint16_t WDT_TIMEOUT
Time in ms after which the watch dog timer resets the MCU.
Definition: b15f.h:219
void reconnect(void)
Definition: b15f.cpp:57
-
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:205
-
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:344
+
constexpr static uint32_t BAUDRATE
USART baudrate for communication with the MCU.
Definition: b15f.h:221
+
static void setAbortHandler(errorhandler_t func)
Definition: b15f.cpp:385
bool analogWrite0(uint16_t port)
Definition: b15f.cpp:200
-
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:204
+
constexpr static uint8_t RECONNECT_TRIES
Maximum count of reconnect attempts after which the driver stops.
Definition: b15f.h:220
bool testIntConv(void)
Definition: b15f.cpp:105
diff --git a/docs/html/classB15F-members.html b/docs/html/classB15F-members.html index 1c32f74..119895f 100644 --- a/docs/html/classB15F-members.html +++ b/docs/html/classB15F-members.html @@ -90,6 +90,8 @@ $(function() { MSG_FAILB15Fstatic MSG_OKB15Fstatic PREB15F + pwmSetFrequency(uint32_t freq)B15F + pwmSetValue(uint8_t value)B15F readDipSwitch(void)B15F reconnect(void)B15F RECONNECT_TIMEOUTB15Fstatic @@ -101,7 +103,7 @@ $(function() { diff --git a/docs/html/classB15F.html b/docs/html/classB15F.html index 7271305..f22425d 100644 --- a/docs/html/classB15F.html +++ b/docs/html/classB15F.html @@ -111,6 +111,10 @@ Public Member Functions   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)   +uint8_t pwmSetFrequency (uint32_t freq) +  +bool pwmSetValue (uint8_t value) +  @@ -194,7 +198,7 @@ constexpr static uint32_t 

Static Public Member Functions

-

Definition at line 332 of file b15f.cpp.

+

Definition at line 373 of file b15f.cpp.

@@ -228,7 +232,7 @@ constexpr static uint32_t 
-

Definition at line 327 of file b15f.cpp.

+

Definition at line 368 of file b15f.cpp.

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

Definition at line 292 of file b15f.cpp.

+

Definition at line 333 of file b15f.cpp.

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

Definition at line 297 of file b15f.cpp.

+

Definition at line 338 of file b15f.cpp.

@@ -672,7 +676,7 @@ constexpr static uint32_t 
-

Definition at line 311 of file b15f.cpp.

+

Definition at line 352 of file b15f.cpp.

@@ -732,7 +736,72 @@ constexpr static uint32_t 
-

Definition at line 302 of file b15f.cpp.

+

Definition at line 343 of file b15f.cpp.

+ + + + +

◆ pwmSetFrequency()

+ +
+
+ + + + + + + + +
uint8_t B15F::pwmSetFrequency (uint32_t freq)
+
+

Setzt die Register so, dass näherungsweise die gewünschte Frequenz erzeugt wird. Ist freq == 0 wird PWM deaktiviert.

Parameters
+ + +
freqPWM Frequenz
+
+
+
Returns
Top Wert des PWM Value für die gesetzte Frequenz
+
Exceptions
+ + +
DriverException
+
+
+ +

Definition at line 292 of file b15f.cpp.

+ +
+
+ +

◆ pwmSetValue()

+ +
+
+ + + + + + + + +
bool B15F::pwmSetValue (uint8_t value)
+
+

Setzt den PWM Wert.

Parameters
+ + +
valuePWM Wert [0..0xFF]
+
+
+
Exceptions
+ + +
DriverException
+
+
+ +

Definition at line 314 of file b15f.cpp.

@@ -819,7 +888,7 @@ constexpr static uint32_t 
-

Definition at line 344 of file b15f.cpp.

+

Definition at line 385 of file b15f.cpp.

@@ -882,7 +951,7 @@ constexpr static uint32_t 
diff --git a/docs/html/classDot-members.html b/docs/html/classDot-members.html index c1464ba..fafd43d 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 318fa5d..b05a9bc 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 848c1ce..5f85cd6 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 5df8380..95ed51e 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 3e7bb5c..b38eece 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 d68ad8e..de9db48 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 a656c56..8c3285a 100644 --- a/docs/html/classTimeoutException-members.html +++ b/docs/html/classTimeoutException-members.html @@ -78,7 +78,7 @@ $(function() { diff --git a/docs/html/classTimeoutException.html b/docs/html/classTimeoutException.html index 77727db..6aa40b1 100644 --- a/docs/html/classTimeoutException.html +++ b/docs/html/classTimeoutException.html @@ -112,7 +112,7 @@ int m_timeout diff --git a/docs/html/classUSART-members.html b/docs/html/classUSART-members.html index 4dc25df..8d603c6 100644 --- a/docs/html/classUSART-members.html +++ b/docs/html/classUSART-members.html @@ -90,10 +90,11 @@ $(function() { writeBlock(uint8_t *buffer, uint16_t offset, uint8_t len) (defined in USART)USART writeByte(uint8_t b)USART writeInt(uint16_t d)USART + writeU32(uint32_t d)USART diff --git a/docs/html/classUSART.html b/docs/html/classUSART.html index 89274cc..aa16cc1 100644 --- a/docs/html/classUSART.html +++ b/docs/html/classUSART.html @@ -91,6 +91,8 @@ Public Member Functions   void writeInt (uint16_t d)   +void writeU32 (uint32_t d) +  uint8_t readByte (void)   uint16_t readInt (void) @@ -254,7 +256,7 @@ constexpr static uint8_t B

Liefert die eingestellte Baudrate Änderungen werden erst nach einem open() wirksam

-

Definition at line 307 of file usart.cpp.

+

Definition at line 312 of file usart.cpp.

@@ -275,7 +277,7 @@ constexpr static uint8_t B

Liefert den eingestellten Timeout (in Dezisekunden) Änderungen werden erst nach einem open() wirksam

-

Definition at line 312 of file usart.cpp.

+

Definition at line 317 of file usart.cpp.

@@ -354,7 +356,7 @@ constexpr static uint8_t B -

Definition at line 211 of file usart.cpp.

+

Definition at line 216 of file usart.cpp.

@@ -380,7 +382,7 @@ constexpr static uint8_t B -

Definition at line 230 of file usart.cpp.

+

Definition at line 235 of file usart.cpp.

@@ -401,7 +403,7 @@ constexpr static uint8_t B

Setzt die Baudrate Änderungen werden erst nach einem open() wirksam

-

Definition at line 317 of file usart.cpp.

+

Definition at line 322 of file usart.cpp.

@@ -422,7 +424,7 @@ constexpr static uint8_t B

Setzt den Timeout (in Dezisekunden) Änderungen werden erst nach einem open() wirksam

-

Definition at line 322 of file usart.cpp.

+

Definition at line 327 of file usart.cpp.

@@ -475,7 +477,7 @@ constexpr static uint8_t B

Sendet ein Integer über die USART Schnittstelle

Parameters
- +
bdas zu sendende Byte
bdas zu sendende Int
@@ -488,6 +490,38 @@ constexpr static uint8_t B

Definition at line 81 of file usart.cpp.

+
+ + +

◆ writeU32()

+ +
+
+ + + + + + + + +
void USART::writeU32 (uint32_t d)
+
+

Sendet ein uint32_t über die USART Schnittstelle

Parameters
+ + +
bdas zu sendende uint32_t
+
+
+
Exceptions
+ + +
USARTException
+
+
+ +

Definition at line 88 of file usart.cpp.

+

The documentation for this class was generated from the following files:
    @@ -497,7 +531,7 @@ constexpr static uint8_t B diff --git a/docs/html/classUSARTException-members.html b/docs/html/classUSARTException-members.html index 03df1bd..fb0f7cc 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 4b9bc80..96d050d 100644 --- a/docs/html/classUSARTException.html +++ b/docs/html/classUSARTException.html @@ -109,7 +109,7 @@ std::string msg diff --git a/docs/html/classView-members.html b/docs/html/classView-members.html index 94750c9..0816e70 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 5c420fa..ba64d4a 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 62d2103..11fecf3 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 c78f59d..090a6da 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 c2f4e01..f8b0248 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 9c59752..7566433 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 b0cafed..0620da4 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 22b82ad..e4f148d 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 595ba75..7eb9d49 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 e92f205..3983a76 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 8d0d0f8..54bd780 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 801fcb9..941591f 100644 --- a/docs/html/cli_8cpp_source.html +++ b/docs/html/cli_8cpp_source.html @@ -68,11 +68,11 @@ $(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 volatile int win_changed_cooldown = 0;
    23 volatile bool t_refresh_active = false;
    24 
    25 void signal_handler(int signal)
    26 {
    27  if(signal == SIGWINCH)
    28  {
    29  win_changed_cooldown = 10; // 100ms
    30 
    31  if (!t_refresh_active)
    32  {
    33  if(t_refresh.joinable())
    34  t_refresh.join();
    35  t_refresh_active = true;
    36  t_refresh = std::thread([]()
    37  {
    38 
    39  while(win_changed_cooldown--)
    40  std::this_thread::sleep_for(std::chrono::milliseconds(10));
    41 
    42  t_refresh_active = false;
    43 
    44  if(win_stack.size())
    45  win_stack.back()->repaint();
    46 
    47  });
    48  }
    49 
    50  }
    51  else if(signal == SIGINT)
    52  {
    53  cleanup();
    54  std::cout << "SIGINT - Abbruch." << std::endl;
    55  exit(EXIT_FAILURE);
    56  }
    57 }
    58 
    59 void abort_handler(std::exception& ex)
    60 {
    61  ViewInfo* view = new ViewInfo();
    62  view->setTitle("Fehler");
    63  std::string msg(ex.what());
    64  msg += "\n\nBeende in 5 Sekunden.";
    65  view->setText(msg.c_str());
    66  view->setLabelClose("");
    67  view->repaint();
    68 
    69  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    70 
    71  cleanup();
    72  std::cerr << std::endl << "*** EXCEPTION ***" << std::endl << ex.what() << std::endl;
    73  exit(EXIT_FAILURE);
    74 }
    75 
    76 void init()
    77 {
    78  // init b15 driver
    80 #ifndef B15F_CLI_DEBUG
    81  std::cout << std::endl << "Starte in 3s ..." << std::endl;
    82  sleep(3);
    83 #endif
    84  B15F::setAbortHandler(&abort_handler);
    85 
    86  // init all ncurses stuff
    87  initscr();
    88  start_color();
    89  curs_set(0); // 0: invisible, 1: normal, 2: very visible
    90  clear();
    91  noecho();
    92  cbreak(); // Line buffering disabled. pass on everything
    93  mousemask(ALL_MOUSE_EVENTS, NULL);
    94 
    95  // connect signals to handler
    96  signal(SIGWINCH, signal_handler);
    97  signal(SIGINT, signal_handler);
    98 
    99  // set view context
    100  View::setWinContext(newwin(25, 85, 0, 0));
    101 }
    102 
    103 
    104 int main()
    105 {
    106  init();
    107 
    108  int exit_code = EXIT_SUCCESS;
    109 
    110  show_main(0);
    111 
    112  cleanup();
    113 
    114  return exit_code;
    115 }
    -
    static B15F & getInstance(void)
    Definition: b15f.cpp:302
    -
    static void setAbortHandler(errorhandler_t func)
    Definition: b15f.cpp:344
    +
    static B15F & getInstance(void)
    Definition: b15f.cpp:343
    +
    static void setAbortHandler(errorhandler_t func)
    Definition: b15f.cpp:385
    diff --git a/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html b/docs/html/dir_1788f8309b1a812dcb800a185471cf6c.html index bebf28d..bd969af 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 52fcf49..9d8eb0a 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 853835b..dd83450 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 46b7ae7..9c0bd19 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 25897b6..015c2ad 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/files.html b/docs/html/files.html index 92b9ab6..e880b89 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -99,7 +99,7 @@ $(function() { diff --git a/docs/html/functions.html b/docs/html/functions.html index 1df7c12..26bae8d 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -236,6 +236,12 @@ $(function() {
  • printStatistics() : USART
  • +
  • pwmSetFrequency() +: B15F +
  • +
  • pwmSetValue() +: B15F +
@@ -336,11 +342,14 @@ $(function() {
  • writeToFile() : PlottyFile
  • +
  • writeU32() +: USART +
  • diff --git a/docs/html/functions_func.html b/docs/html/functions_func.html index 4fbff3f..1c2fd52 100644 --- a/docs/html/functions_func.html +++ b/docs/html/functions_func.html @@ -216,6 +216,12 @@ $(function() {
  • printStatistics() : USART
  • +
  • pwmSetFrequency() +: B15F +
  • +
  • pwmSetValue() +: B15F +
  • @@ -307,11 +313,14 @@ $(function() {
  • writeToFile() : PlottyFile
  • +
  • writeU32() +: USART +
  • diff --git a/docs/html/functions_vars.html b/docs/html/functions_vars.html index c646f33..3172ad7 100644 --- a/docs/html/functions_vars.html +++ b/docs/html/functions_vars.html @@ -88,7 +88,7 @@ $(function() { diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html index c8df567..bf24851 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 aa89bbd..50426bf 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -72,7 +72,7 @@ Dort befindet sich auch eine Übersicht der verfügbaren Befehle.

    diff --git a/docs/html/plottyfile_8cpp_source.html b/docs/html/plottyfile_8cpp_source.html index c31ae5e..abd1e0b 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 4fdc771..dd26e80 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/search/all_9.js b/docs/html/search/all_9.js index b1c5b0a..c3ed16c 100644 --- a/docs/html/search/all_9.js +++ b/docs/html/search/all_9.js @@ -2,5 +2,7 @@ var searchData= [ ['plottyfile',['PlottyFile',['../classPlottyFile.html',1,'']]], ['pre',['PRE',['../classB15F.html#a3b0fc1f85954b2d9c145af4a3af5b1ec',1,'B15F']]], - ['printstatistics',['printStatistics',['../classUSART.html#a33559bb8f0eda33a489d47b9c9227b59',1,'USART']]] + ['printstatistics',['printStatistics',['../classUSART.html#a33559bb8f0eda33a489d47b9c9227b59',1,'USART']]], + ['pwmsetfrequency',['pwmSetFrequency',['../classB15F.html#ac6f6532bb9550a0632c28b98c157d0a1',1,'B15F']]], + ['pwmsetvalue',['pwmSetValue',['../classB15F.html#af9aad3c0db5d5a8b37219d713e1977ee',1,'B15F']]] ]; diff --git a/docs/html/search/all_f.js b/docs/html/search/all_f.js index 021aad6..6a81098 100644 --- a/docs/html/search/all_f.js +++ b/docs/html/search/all_f.js @@ -3,5 +3,6 @@ var searchData= ['wdt_5ftimeout',['WDT_TIMEOUT',['../classB15F.html#a158d13bc84aed6430cdede1396384e06',1,'B15F']]], ['writebyte',['writeByte',['../classUSART.html#a60eadbe9956bab8144ee96d89eacd9f5',1,'USART']]], ['writeint',['writeInt',['../classUSART.html#a78b30d9aa863f38745e982860392599a',1,'USART']]], - ['writetofile',['writeToFile',['../classPlottyFile.html#a82c348e7fade2edcbc907e7c2bc2e305',1,'PlottyFile']]] + ['writetofile',['writeToFile',['../classPlottyFile.html#a82c348e7fade2edcbc907e7c2bc2e305',1,'PlottyFile']]], + ['writeu32',['writeU32',['../classUSART.html#a68c2d1cb7172813ae8ed61360fad47f6',1,'USART']]] ]; diff --git a/docs/html/search/functions_7.js b/docs/html/search/functions_7.js index cfb7a36..939b6a3 100644 --- a/docs/html/search/functions_7.js +++ b/docs/html/search/functions_7.js @@ -1,4 +1,6 @@ var searchData= [ - ['printstatistics',['printStatistics',['../classUSART.html#a33559bb8f0eda33a489d47b9c9227b59',1,'USART']]] + ['printstatistics',['printStatistics',['../classUSART.html#a33559bb8f0eda33a489d47b9c9227b59',1,'USART']]], + ['pwmsetfrequency',['pwmSetFrequency',['../classB15F.html#ac6f6532bb9550a0632c28b98c157d0a1',1,'B15F']]], + ['pwmsetvalue',['pwmSetValue',['../classB15F.html#af9aad3c0db5d5a8b37219d713e1977ee',1,'B15F']]] ]; diff --git a/docs/html/search/functions_b.js b/docs/html/search/functions_b.js index cbf06ef..59b6148 100644 --- a/docs/html/search/functions_b.js +++ b/docs/html/search/functions_b.js @@ -2,5 +2,6 @@ var searchData= [ ['writebyte',['writeByte',['../classUSART.html#a60eadbe9956bab8144ee96d89eacd9f5',1,'USART']]], ['writeint',['writeInt',['../classUSART.html#a78b30d9aa863f38745e982860392599a',1,'USART']]], - ['writetofile',['writeToFile',['../classPlottyFile.html#a82c348e7fade2edcbc907e7c2bc2e305',1,'PlottyFile']]] + ['writetofile',['writeToFile',['../classPlottyFile.html#a82c348e7fade2edcbc907e7c2bc2e305',1,'PlottyFile']]], + ['writeu32',['writeU32',['../classUSART.html#a68c2d1cb7172813ae8ed61360fad47f6',1,'USART']]] ]; diff --git a/docs/html/timeoutexception_8h_source.html b/docs/html/timeoutexception_8h_source.html index 84fffd2..9351c47 100644 --- a/docs/html/timeoutexception_8h_source.html +++ b/docs/html/timeoutexception_8h_source.html @@ -74,7 +74,7 @@ $(function() { diff --git a/docs/html/ui_8cpp_source.html b/docs/html/ui_8cpp_source.html index 760c88e..2012b32 100644 --- a/docs/html/ui_8cpp_source.html +++ b/docs/html/ui_8cpp_source.html @@ -73,8 +73,8 @@ $(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 BE0 ]", &show_digital_output0);
    13  view->addChoice("[ Digitale Ausgabe BE1 ]", &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\nEs war einmal...");
    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 bestaetigen\nmit 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 delay_ms(uint16_t ms)
    Definition: b15f.cpp:292
    -
    static B15F & getInstance(void)
    Definition: b15f.cpp:302
    +
    void delay_ms(uint16_t ms)
    Definition: b15f.cpp:333
    +
    static B15F & getInstance(void)
    Definition: b15f.cpp:343
    Definition: b15f.h:26
    bool digitalWrite0(uint8_t)
    Definition: b15f.cpp:153
    bool activateSelfTestMode(void)
    Definition: b15f.cpp:145
    @@ -83,12 +83,12 @@ $(function() {
    bool digitalWrite1(uint8_t)
    Definition: b15f.cpp:163
    void discard(void)
    Definition: b15f.cpp:72
    -
    constexpr static uint16_t WDT_TIMEOUT
    Time in ms after which the watch dog timer resets the MCU.
    Definition: b15f.h:203
    +
    constexpr static uint16_t WDT_TIMEOUT
    Time in ms after which the watch dog timer resets the MCU.
    Definition: b15f.h:219
    void reconnect(void)
    Definition: b15f.cpp:57
    bool analogWrite0(uint16_t port)
    Definition: b15f.cpp:200
    diff --git a/docs/html/ui_8h_source.html b/docs/html/ui_8h_source.html index 6b5ee6b..545b5cb 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 5456252..70b7d23 100644 --- a/docs/html/usart_8cpp_source.html +++ b/docs/html/usart_8cpp_source.html @@ -70,26 +70,27 @@ $(function() {
    usart.cpp
    -
    1 #include "usart.h"
    2 
    3 void USART::openDevice(std::string device)
    4 {
    5  file_desc = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY /* | O_NONBLOCK*/);
    6  if(file_desc <= 0)
    7  throw USARTException("Fehler beim Öffnen des Gerätes");
    8 
    9  struct termios options;
    10  int code = tcgetattr(file_desc, &options);
    11  if(code)
    12  throw USARTException("Fehler beim Lesen der Geräteparameter");
    13 
    14  options.c_cflag = CS8 | CLOCAL | CREAD;
    15  options.c_iflag = IGNPAR;
    16  options.c_oflag = 0;
    17  options.c_lflag = 0;
    18  options.c_cc[VMIN] = 0; // #bytes read returns at least
    19  options.c_cc[VTIME] = timeout;
    20  code = cfsetspeed(&options, baudrate);
    21  if(code)
    22  throw USARTException("Fehler beim Setzen der Baudrate");
    23 
    24  code = tcsetattr(file_desc, TCSANOW, &options);
    25  if(code)
    26  throw USARTException("Fehler beim Setzen der Geräteparameter");
    27 
    30 }
    31 
    33 {
    34  int code = close(file_desc);
    35  if(code)
    36  throw USARTException("Fehler beim Schließen des Gerätes");
    37 }
    38 
    40 {
    41  int code = tcflush(file_desc, TCIFLUSH);
    42  if(code)
    43  throw USARTException("Fehler beim Leeren des Eingangspuffers");
    44 }
    45 
    47 {
    48  int code = tcflush(file_desc, TCOFLUSH);
    49  if(code)
    50  throw USARTException("Fehler beim Leeren des Ausgangspuffers");
    51 }
    52 
    54 {
    55  int code = tcdrain(file_desc);
    56  if(code)
    57  throw USARTException("Fehler beim Versenden des Ausgangspuffers");
    58 }
    59 
    61 {
    62  double pz = 1e2 * n_blocks_failed / n_blocks_total;
    63  pz = std::round(pz * 1e2) / 1e2;
    64  std::cout << "blocks total: " << n_blocks_total << " ok: " << (n_blocks_total - n_blocks_failed) << " failed: " << n_blocks_failed << " (" << pz << "%)" << std::endl;
    65 }
    66 
    67 void USART::writeByte(uint8_t b)
    68 {
    69  int sent = write(file_desc, &b, 1);
    70  if(sent != 1)
    71  {
    72  std::cout << "WARNUNG: Fehler beim Senden (" << sent << "): writeByte(), wiederhole..." << std::endl;
    73  usleep(100000);
    74  sent = write(file_desc, &b, 1);
    75  if(sent != 1)
    76  throw USARTException("Fehler beim Senden: writeByte()");
    77  }
    78 
    79 }
    80 
    81 void USART::writeInt(uint16_t d)
    82 {
    83  int sent = write(file_desc, reinterpret_cast<char*>(&d), 2);
    84  if(sent != 2)
    85  throw USARTException("Fehler beim Senden: writeInt()");
    86 }
    87 
    88 
    89 
    90 int USART::read_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout)
    91 {
    92  uint32_t elapsed = 0;
    93  int n_read = -1;
    94  auto start = std::chrono::steady_clock::now();
    95  auto end = start;
    96  while(elapsed < timeout)
    97  {
    98  n_read = read(file_desc, buffer + offset, len);
    99  if (n_read == len)
    100  return n_read;
    101 
    102  end = std::chrono::steady_clock::now();
    103  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
    104  }
    105 
    106  return 0;
    107 }
    108 
    109 int USART::write_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout)
    110 {
    111  uint32_t elapsed = 0;
    112  int n_sent = -1;
    113  auto start = std::chrono::steady_clock::now();
    114  auto end = start;
    115  while(elapsed < timeout)
    116  {
    117  n_sent = write(file_desc, buffer + offset, len);
    119  if (n_sent == len)
    120  return n_sent;
    121 
    122  end = std::chrono::steady_clock::now();
    123  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
    124  }
    125 
    126  return n_sent;
    127 }
    128 
    129 void USART::writeBlock(uint8_t* buffer, uint16_t offset, uint8_t len)
    130 {
    131  uint8_t crc;
    132  uint8_t aw;
    133  const uint16_t us_per_bit = (1000000 / baudrate) * 16;
    134  const uint16_t n_total = len + 3;
    135 
    136  n_blocks_total++;
    137  bool failed = false;
    138 
    139  do
    140  {
    141  // calc crc
    142  crc = 0;
    143  for(uint8_t i = 0; i < len; i++)
    144  {
    145  crc ^= buffer[i];
    146  for (uint8_t k = 0; k < 8; k++)
    147  {
    148  if (crc & 1)
    149  crc ^= CRC7_POLY;
    150  crc >>= 1;
    151  }
    152  }
    153 
    154  // construct block
    155  block_buffer[0] = len;
    156  std::memcpy(&block_buffer[1], buffer + offset, len);
    157  block_buffer[len + 1] = crc;
    158  block_buffer[len + 2] = BLOCK_END;
    159 
    160  // send block
    163  int n_sent = write_timeout(&block_buffer[0], 0, len + 3, us_per_bit * n_total);
    164  if(n_sent != n_total)
    165  throw std::runtime_error("fatal (send): " + std::to_string(n_sent));
    166 
    167  /*for(uint8_t i = 0; i < len + 3; i++)
    168  {
    169  write_timeout(&block_buffer[i], 0, 1, us_per_bit * n_total);
    170  //tcdrain(file_desc);
    171  //usleep(1000);
    172  }*/
    173 
    174  // flush output data
    175  tcdrain(file_desc);
    176 
    177  //usleep(us_per_bit * n_total * 10);
    178 
    179  // check response
    180  int n_read = read_timeout(&aw, 0, 1, us_per_bit * n_blocks_total * 10);
    181  for(uint16_t i = 0; i < 255 && n_read != 1; i++)
    182  {
    183  writeByte(0x80); // Stoppzeichen für Block
    184  if(tcdrain(file_desc))
    185  {
    186  std::cout << "drain failed" << std::endl;
    187  }
    188  std::cout << "WARNING: read error (" << n_read << "), retry #" << (int) i << std::endl;
    189  usleep(us_per_bit*100);
    190  n_read = read_timeout(&aw, 0, 1, us_per_bit);
    191  }
    192 
    193  if(n_read != 1)
    194  throw std::runtime_error("fatal: " + std::to_string(n_read));
    195 
    196  //clearInputBuffer();
    197 
    198  if(aw != 0xFF)
    199  {
    200  if(!failed)
    201  n_blocks_failed++;
    202  failed = true;
    203  std::cout << "block failed, retry" << std::endl;
    204  }
    205  }
    206  while(aw != 0xFF);
    207 
    208  //std::cout << "OK" << std::endl;
    209 }
    210 
    211 uint8_t USART::readByte(void)
    212 {
    213  char b;
    214  auto start = std::chrono::steady_clock::now();
    215  auto end = start;
    216  uint16_t elapsed = 0;
    217  while(elapsed < timeout * 100)
    218  {
    219  int code = read(file_desc, &b, 1);
    220  if (code > 0)
    221  return static_cast<uint8_t>(b);
    222 
    223  end = std::chrono::steady_clock::now();
    224  elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    225  }
    226 
    227  throw TimeoutException("Verbindung unterbrochen.", timeout);
    228 }
    229 
    230 uint16_t USART::readInt(void)
    231 {
    232  return readByte() | readByte() << 8;
    233 }
    234 
    235 bool USART::readBlock(uint8_t* buffer, uint16_t offset)
    236 {
    237  uint8_t len = readByte();
    238  uint8_t crc = 0;
    239  buffer += offset;
    240 
    241  uint32_t block_timeout = timeout / 10;
    242 
    243  // wait for block
    244  int n_ready;
    245  uint16_t elapsed = 0;
    246  auto start = std::chrono::steady_clock::now();
    247  auto end = start;
    248  while(elapsed < block_timeout)
    249  {
    250  int code = ioctl(file_desc, FIONREAD, &n_ready);
    251  if(code != 0)
    252  {
    253  std::cout << "n_ready code: " << code << std::endl;
    254  return false;
    255  }
    256 
    257  if(n_ready >= len + 1)
    258  break;
    259 
    260  end = std::chrono::steady_clock::now();
    261  elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    262  }
    263  if(elapsed >= timeout)
    264  {
    265  std::cout << "block timeout: " << std::endl;
    266  return false;
    267  }
    268 
    269  while(len--)
    270  {
    271  *buffer = readByte();
    272 
    273  crc ^= *buffer++;
    274  for (uint8_t i = 0; i < 8; i++)
    275  {
    276  if (crc & 1)
    277  crc ^= CRC7_POLY;
    278  crc >>= 1;
    279  }
    280  }
    281 
    282  crc ^= readByte();
    283  for (uint8_t i = 0; i < 8; i++)
    284  {
    285  if (crc & 1)
    286  crc ^= CRC7_POLY;
    287  crc >>= 1;
    288  }
    289 
    290  if(TEST == 1)
    291  crc = 1;
    292  if(TEST > 100)
    293  TEST = 0;
    294 
    295  if (crc == 0)
    296  {
    297  writeByte(0xFF);
    298  return true;
    299  }
    300  else
    301  {
    302  writeByte(0xFE);
    303  return false;
    304  }
    305 }
    306 
    308 {
    309  return baudrate;
    310 }
    311 
    313 {
    314  return timeout;
    315 }
    316 
    317 void USART::setBaudrate(uint32_t baudrate)
    318 {
    319  this->baudrate = baudrate;
    320 }
    321 
    322 void USART::setTimeout(uint8_t timeout)
    323 {
    324  this->timeout = timeout;
    325 }
    -
    uint32_t getBaudrate(void)
    Definition: usart.cpp:307
    -
    uint8_t readByte(void)
    Definition: usart.cpp:211
    +
    1 #include "usart.h"
    2 
    3 void USART::openDevice(std::string device)
    4 {
    5  file_desc = open(device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY /* | O_NONBLOCK*/);
    6  if(file_desc <= 0)
    7  throw USARTException("Fehler beim Öffnen des Gerätes");
    8 
    9  struct termios options;
    10  int code = tcgetattr(file_desc, &options);
    11  if(code)
    12  throw USARTException("Fehler beim Lesen der Geräteparameter");
    13 
    14  options.c_cflag = CS8 | CLOCAL | CREAD;
    15  options.c_iflag = IGNPAR;
    16  options.c_oflag = 0;
    17  options.c_lflag = 0;
    18  options.c_cc[VMIN] = 0; // #bytes read returns at least
    19  options.c_cc[VTIME] = timeout;
    20  code = cfsetspeed(&options, baudrate);
    21  if(code)
    22  throw USARTException("Fehler beim Setzen der Baudrate");
    23 
    24  code = tcsetattr(file_desc, TCSANOW, &options);
    25  if(code)
    26  throw USARTException("Fehler beim Setzen der Geräteparameter");
    27 
    30 }
    31 
    33 {
    34  int code = close(file_desc);
    35  if(code)
    36  throw USARTException("Fehler beim Schließen des Gerätes");
    37 }
    38 
    40 {
    41  int code = tcflush(file_desc, TCIFLUSH);
    42  if(code)
    43  throw USARTException("Fehler beim Leeren des Eingangspuffers");
    44 }
    45 
    47 {
    48  int code = tcflush(file_desc, TCOFLUSH);
    49  if(code)
    50  throw USARTException("Fehler beim Leeren des Ausgangspuffers");
    51 }
    52 
    54 {
    55  int code = tcdrain(file_desc);
    56  if(code)
    57  throw USARTException("Fehler beim Versenden des Ausgangspuffers");
    58 }
    59 
    61 {
    62  double pz = 1e2 * n_blocks_failed / n_blocks_total;
    63  pz = std::round(pz * 1e2) / 1e2;
    64  std::cout << "blocks total: " << n_blocks_total << " ok: " << (n_blocks_total - n_blocks_failed) << " failed: " << n_blocks_failed << " (" << pz << "%)" << std::endl;
    65 }
    66 
    67 void USART::writeByte(uint8_t b)
    68 {
    69  int sent = write(file_desc, &b, 1);
    70  if(sent != 1)
    71  {
    72  std::cout << "WARNUNG: Fehler beim Senden (" << sent << "): writeByte(), wiederhole..." << std::endl;
    73  usleep(100000);
    74  sent = write(file_desc, &b, 1);
    75  if(sent != 1)
    76  throw USARTException("Fehler beim Senden: writeByte()");
    77  }
    78 
    79 }
    80 
    81 void USART::writeInt(uint16_t d)
    82 {
    83  int sent = write(file_desc, reinterpret_cast<char*>(&d), 2);
    84  if(sent != 2)
    85  throw USARTException("Fehler beim Senden: writeInt()");
    86 }
    87 
    88 void USART::writeU32(uint32_t w)
    89 {
    90  int sent = write(file_desc, reinterpret_cast<char*>(&w), 4);
    91  if(sent != 4)
    92  throw USARTException("Fehler beim Senden: writeU32()");
    93 }
    94 
    95 int USART::read_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout)
    96 {
    97  uint32_t elapsed = 0;
    98  int n_read = -1;
    99  auto start = std::chrono::steady_clock::now();
    100  auto end = start;
    101  while(elapsed < timeout)
    102  {
    103  n_read = read(file_desc, buffer + offset, len);
    104  if (n_read == len)
    105  return n_read;
    106 
    107  end = std::chrono::steady_clock::now();
    108  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
    109  }
    110 
    111  return 0;
    112 }
    113 
    114 int USART::write_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout)
    115 {
    116  uint32_t elapsed = 0;
    117  int n_sent = -1;
    118  auto start = std::chrono::steady_clock::now();
    119  auto end = start;
    120  while(elapsed < timeout)
    121  {
    122  n_sent = write(file_desc, buffer + offset, len);
    124  if (n_sent == len)
    125  return n_sent;
    126 
    127  end = std::chrono::steady_clock::now();
    128  elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
    129  }
    130 
    131  return n_sent;
    132 }
    133 
    134 void USART::writeBlock(uint8_t* buffer, uint16_t offset, uint8_t len)
    135 {
    136  uint8_t crc;
    137  uint8_t aw;
    138  const uint16_t us_per_bit = (1000000 / baudrate) * 16;
    139  const uint16_t n_total = len + 3;
    140 
    141  n_blocks_total++;
    142  bool failed = false;
    143 
    144  do
    145  {
    146  // calc crc
    147  crc = 0;
    148  for(uint8_t i = 0; i < len; i++)
    149  {
    150  crc ^= buffer[i];
    151  for (uint8_t k = 0; k < 8; k++)
    152  {
    153  if (crc & 1)
    154  crc ^= CRC7_POLY;
    155  crc >>= 1;
    156  }
    157  }
    158 
    159  // construct block
    160  block_buffer[0] = len;
    161  std::memcpy(&block_buffer[1], buffer + offset, len);
    162  block_buffer[len + 1] = crc;
    163  block_buffer[len + 2] = BLOCK_END;
    164 
    165  // send block
    168  int n_sent = write_timeout(&block_buffer[0], 0, len + 3, us_per_bit * n_total);
    169  if(n_sent != n_total)
    170  throw std::runtime_error("fatal (send): " + std::to_string(n_sent));
    171 
    172  /*for(uint8_t i = 0; i < len + 3; i++)
    173  {
    174  write_timeout(&block_buffer[i], 0, 1, us_per_bit * n_total);
    175  //tcdrain(file_desc);
    176  //usleep(1000);
    177  }*/
    178 
    179  // flush output data
    180  tcdrain(file_desc);
    181 
    182  //usleep(us_per_bit * n_total * 10);
    183 
    184  // check response
    185  int n_read = read_timeout(&aw, 0, 1, us_per_bit * n_blocks_total * 10);
    186  for(uint16_t i = 0; i < 255 && n_read != 1; i++)
    187  {
    188  writeByte(0x80); // Stoppzeichen für Block
    189  if(tcdrain(file_desc))
    190  {
    191  std::cout << "drain failed" << std::endl;
    192  }
    193  std::cout << "WARNING: read error (" << n_read << "), retry #" << (int) i << std::endl;
    194  usleep(us_per_bit*100);
    195  n_read = read_timeout(&aw, 0, 1, us_per_bit);
    196  }
    197 
    198  if(n_read != 1)
    199  throw std::runtime_error("fatal: " + std::to_string(n_read));
    200 
    201  //clearInputBuffer();
    202 
    203  if(aw != 0xFF)
    204  {
    205  if(!failed)
    206  n_blocks_failed++;
    207  failed = true;
    208  std::cout << "block failed, retry" << std::endl;
    209  }
    210  }
    211  while(aw != 0xFF);
    212 
    213  //std::cout << "OK" << std::endl;
    214 }
    215 
    216 uint8_t USART::readByte(void)
    217 {
    218  char b;
    219  auto start = std::chrono::steady_clock::now();
    220  auto end = start;
    221  uint16_t elapsed = 0;
    222  while(elapsed < timeout * 100)
    223  {
    224  int code = read(file_desc, &b, 1);
    225  if (code > 0)
    226  return static_cast<uint8_t>(b);
    227 
    228  end = std::chrono::steady_clock::now();
    229  elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    230  }
    231 
    232  throw TimeoutException("Verbindung unterbrochen.", timeout);
    233 }
    234 
    235 uint16_t USART::readInt(void)
    236 {
    237  return readByte() | readByte() << 8;
    238 }
    239 
    240 bool USART::readBlock(uint8_t* buffer, uint16_t offset)
    241 {
    242  uint8_t len = readByte();
    243  uint8_t crc = 0;
    244  buffer += offset;
    245 
    246  uint32_t block_timeout = timeout / 10;
    247 
    248  // wait for block
    249  int n_ready;
    250  uint16_t elapsed = 0;
    251  auto start = std::chrono::steady_clock::now();
    252  auto end = start;
    253  while(elapsed < block_timeout)
    254  {
    255  int code = ioctl(file_desc, FIONREAD, &n_ready);
    256  if(code != 0)
    257  {
    258  std::cout << "n_ready code: " << code << std::endl;
    259  return false;
    260  }
    261 
    262  if(n_ready >= len + 1)
    263  break;
    264 
    265  end = std::chrono::steady_clock::now();
    266  elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    267  }
    268  if(elapsed >= timeout)
    269  {
    270  std::cout << "block timeout: " << std::endl;
    271  return false;
    272  }
    273 
    274  while(len--)
    275  {
    276  *buffer = readByte();
    277 
    278  crc ^= *buffer++;
    279  for (uint8_t i = 0; i < 8; i++)
    280  {
    281  if (crc & 1)
    282  crc ^= CRC7_POLY;
    283  crc >>= 1;
    284  }
    285  }
    286 
    287  crc ^= readByte();
    288  for (uint8_t i = 0; i < 8; i++)
    289  {
    290  if (crc & 1)
    291  crc ^= CRC7_POLY;
    292  crc >>= 1;
    293  }
    294 
    295  if(TEST == 1)
    296  crc = 1;
    297  if(TEST > 100)
    298  TEST = 0;
    299 
    300  if (crc == 0)
    301  {
    302  writeByte(0xFF);
    303  return true;
    304  }
    305  else
    306  {
    307  writeByte(0xFE);
    308  return false;
    309  }
    310 }
    311 
    313 {
    314  return baudrate;
    315 }
    316 
    318 {
    319  return timeout;
    320 }
    321 
    322 void USART::setBaudrate(uint32_t baudrate)
    323 {
    324  this->baudrate = baudrate;
    325 }
    326 
    327 void USART::setTimeout(uint8_t timeout)
    328 {
    329  this->timeout = timeout;
    330 }
    +
    void writeU32(uint32_t d)
    Definition: usart.cpp:88
    +
    uint32_t getBaudrate(void)
    Definition: usart.cpp:312
    +
    uint8_t readByte(void)
    Definition: usart.cpp:216
    void printStatistics(void)
    Definition: usart.cpp:60
    void closeDevice(void)
    Definition: usart.cpp:32
    void clearInputBuffer(void)
    Definition: usart.cpp:39
    -
    uint8_t getTimeout(void)
    Definition: usart.cpp:312
    +
    uint8_t getTimeout(void)
    Definition: usart.cpp:317
    void clearOutputBuffer(void)
    Definition: usart.cpp:46
    -
    void setBaudrate(uint32_t baudrate)
    Definition: usart.cpp:317
    +
    void setBaudrate(uint32_t baudrate)
    Definition: usart.cpp:322
    void writeByte(uint8_t b)
    Definition: usart.cpp:67
    void openDevice(std::string device)
    Definition: usart.cpp:3
    -
    uint16_t readInt(void)
    Definition: usart.cpp:230
    -
    void setTimeout(uint8_t timeout)
    Definition: usart.cpp:322
    +
    uint16_t readInt(void)
    Definition: usart.cpp:235
    +
    void setTimeout(uint8_t timeout)
    Definition: usart.cpp:327
    void flushOutputBuffer(void)
    Definition: usart.cpp:53
    void writeInt(uint16_t d)
    Definition: usart.cpp:81
    diff --git a/docs/html/usart_8h_source.html b/docs/html/usart_8h_source.html index 31b8729..25eac7a 100644 --- a/docs/html/usart_8h_source.html +++ b/docs/html/usart_8h_source.html @@ -70,25 +70,26 @@ $(function() {
    usart.h
    -
    1 #ifndef USART_H
    2 #define USART_H
    3 
    4 #include <iostream>
    5 #include <cstdint>
    6 #include <chrono>
    7 #include <unistd.h>
    8 #include <cstring>
    9 #include <fcntl.h>
    10 #include <sys/ioctl.h>
    11 #include <termios.h>
    12 #include <cmath>
    13 #include "usartexception.h"
    14 #include "timeoutexception.h"
    15 
    18 class USART
    19 {
    20 public:
    21 
    22  /*************************************************
    23  * Methoden für die Verwaltung der Schnittstelle *
    24  *************************************************/
    25 
    31  void openDevice(std::string device);
    32 
    37  void closeDevice(void);
    38 
    43  void clearInputBuffer(void);
    44 
    49  void clearOutputBuffer(void);
    50 
    55  void flushOutputBuffer(void);
    56 
    60  void printStatistics(void);
    61 
    62  /*************************************************/
    63 
    64 
    65 
    66  /*************************************
    67  * Methoden für die Datenübertragung *
    68  *************************************/
    69 
    75  void writeByte(uint8_t b);
    76 
    82  void writeInt(uint16_t d);
    83 
    88  uint8_t readByte(void);
    89 
    94  uint16_t readInt(void);
    95 
    96  int read_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout);
    97  int write_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout);
    98  void writeBlock(uint8_t* buffer, uint16_t offset, uint8_t len);
    99  bool readBlock(uint8_t* buffer, uint16_t offset);
    100 
    101  /*************************************/
    102 
    103 
    104 
    105  /***************************************
    106  * Methoden für einstellbare Parameter *
    107  ***************************************/
    108 
    113  uint32_t getBaudrate(void);
    114 
    119  uint8_t getTimeout(void);
    120 
    125  void setBaudrate(uint32_t baudrate);
    126 
    131  void setTimeout(uint8_t timeout);
    132 
    133  /***************************************/
    134 
    135  constexpr static uint8_t CRC7_POLY = 0x91;
    136  constexpr static uint8_t MAX_BLOCK_SIZE = 64;
    137  constexpr static uint8_t BLOCK_END = 0x80;
    138 private:
    139 
    140  int file_desc = -1; // Linux Dateideskriptor
    141  uint32_t baudrate = 9600; // Standard-Baudrate, sollte mit setBaudrate() überschrieben werden!
    142  int TEST = 0;
    143  uint8_t timeout = 10; // in Dezisekunden
    144  uint8_t block_buffer[MAX_BLOCK_SIZE + 3];
    145 
    146  // debug statistics
    147  uint32_t n_blocks_total = 0;
    148  uint32_t n_blocks_failed = 0;
    149 };
    150 
    151 
    152 #endif // USART_H
    -
    uint32_t getBaudrate(void)
    Definition: usart.cpp:307
    -
    uint8_t readByte(void)
    Definition: usart.cpp:211
    +
    1 #ifndef USART_H
    2 #define USART_H
    3 
    4 #include <iostream>
    5 #include <cstdint>
    6 #include <chrono>
    7 #include <unistd.h>
    8 #include <cstring>
    9 #include <fcntl.h>
    10 #include <sys/ioctl.h>
    11 #include <termios.h>
    12 #include <cmath>
    13 #include "usartexception.h"
    14 #include "timeoutexception.h"
    15 
    18 class USART
    19 {
    20 public:
    21 
    22  /*************************************************
    23  * Methoden für die Verwaltung der Schnittstelle *
    24  *************************************************/
    25 
    31  void openDevice(std::string device);
    32 
    37  void closeDevice(void);
    38 
    43  void clearInputBuffer(void);
    44 
    49  void clearOutputBuffer(void);
    50 
    55  void flushOutputBuffer(void);
    56 
    60  void printStatistics(void);
    61 
    62  /*************************************************/
    63 
    64 
    65 
    66  /*************************************
    67  * Methoden für die Datenübertragung *
    68  *************************************/
    69 
    75  void writeByte(uint8_t b);
    76 
    82  void writeInt(uint16_t d);
    83 
    89  void writeU32(uint32_t d);
    90 
    95  uint8_t readByte(void);
    96 
    101  uint16_t readInt(void);
    102 
    103  int read_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout);
    104  int write_timeout(uint8_t* buffer, uint16_t offset, uint8_t len, uint32_t timeout);
    105  void writeBlock(uint8_t* buffer, uint16_t offset, uint8_t len);
    106  bool readBlock(uint8_t* buffer, uint16_t offset);
    107 
    108  /*************************************/
    109 
    110 
    111 
    112  /***************************************
    113  * Methoden für einstellbare Parameter *
    114  ***************************************/
    115 
    120  uint32_t getBaudrate(void);
    121 
    126  uint8_t getTimeout(void);
    127 
    132  void setBaudrate(uint32_t baudrate);
    133 
    138  void setTimeout(uint8_t timeout);
    139 
    140  /***************************************/
    141 
    142  constexpr static uint8_t CRC7_POLY = 0x91;
    143  constexpr static uint8_t MAX_BLOCK_SIZE = 64;
    144  constexpr static uint8_t BLOCK_END = 0x80;
    145 private:
    146 
    147  int file_desc = -1; // Linux Dateideskriptor
    148  uint32_t baudrate = 9600; // Standard-Baudrate, sollte mit setBaudrate() überschrieben werden!
    149  int TEST = 0;
    150  uint8_t timeout = 10; // in Dezisekunden
    151  uint8_t block_buffer[MAX_BLOCK_SIZE + 3];
    152 
    153  // debug statistics
    154  uint32_t n_blocks_total = 0;
    155  uint32_t n_blocks_failed = 0;
    156 };
    157 
    158 
    159 #endif // USART_H
    +
    void writeU32(uint32_t d)
    Definition: usart.cpp:88
    +
    uint32_t getBaudrate(void)
    Definition: usart.cpp:312
    +
    uint8_t readByte(void)
    Definition: usart.cpp:216
    void printStatistics(void)
    Definition: usart.cpp:60
    void closeDevice(void)
    Definition: usart.cpp:32
    void clearInputBuffer(void)
    Definition: usart.cpp:39
    -
    uint8_t getTimeout(void)
    Definition: usart.cpp:312
    +
    uint8_t getTimeout(void)
    Definition: usart.cpp:317
    Definition: usart.h:18
    void clearOutputBuffer(void)
    Definition: usart.cpp:46
    -
    void setBaudrate(uint32_t baudrate)
    Definition: usart.cpp:317
    +
    void setBaudrate(uint32_t baudrate)
    Definition: usart.cpp:322
    void writeByte(uint8_t b)
    Definition: usart.cpp:67
    void openDevice(std::string device)
    Definition: usart.cpp:3
    -
    uint16_t readInt(void)
    Definition: usart.cpp:230
    -
    void setTimeout(uint8_t timeout)
    Definition: usart.cpp:322
    +
    uint16_t readInt(void)
    Definition: usart.cpp:235
    +
    void setTimeout(uint8_t timeout)
    Definition: usart.cpp:327
    void flushOutputBuffer(void)
    Definition: usart.cpp:53
    void writeInt(uint16_t d)
    Definition: usart.cpp:81
    diff --git a/docs/html/usartexception_8h_source.html b/docs/html/usartexception_8h_source.html index c067c44..d037b79 100644 --- a/docs/html/usartexception_8h_source.html +++ b/docs/html/usartexception_8h_source.html @@ -74,7 +74,7 @@ $(function() { diff --git a/docs/html/view_8cpp_source.html b/docs/html/view_8cpp_source.html index 0de8167..030d2a5 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:327
    +
    static void abort(std::string msg)
    Definition: b15f.cpp:368
    diff --git a/docs/html/view_8h_source.html b/docs/html/view_8h_source.html index 92e566e..8978a3e 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 2370daf..c9d1a98 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 992f9d7..4aaf34e 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 5c600ac..fa3a723 100644 --- a/docs/html/view__monitor_8cpp_source.html +++ b/docs/html/view__monitor_8cpp_source.html @@ -74,17 +74,17 @@ $(function() {
    uint8_t digitalRead0(void)
    Definition: b15f.cpp:173
    uint8_t readDipSwitch(void)
    Definition: b15f.cpp:191
    -
    void delay_ms(uint16_t ms)
    Definition: b15f.cpp:292
    -
    static B15F & getInstance(void)
    Definition: b15f.cpp:302
    +
    void delay_ms(uint16_t ms)
    Definition: b15f.cpp:333
    +
    static B15F & getInstance(void)
    Definition: b15f.cpp:343
    Definition: b15f.h:26
    -
    static void abort(std::string msg)
    Definition: b15f.cpp:327
    +
    static void abort(std::string msg)
    Definition: b15f.cpp:368
    uint16_t analogRead(uint8_t channel)
    Definition: b15f.cpp:220
    uint8_t digitalRead1(void)
    Definition: b15f.cpp:182
    void reconnect(void)
    Definition: b15f.cpp:57
    diff --git a/docs/html/view__monitor_8h_source.html b/docs/html/view__monitor_8h_source.html index 0c48289..c050394 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 cef242a..0e91d6e 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 df2d726..6acbb7b 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 bd16c53..d78a6f9 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 ece3b9c..19bac8c 100644 --- a/docs/html/view__selection_8h_source.html +++ b/docs/html/view__selection_8h_source.html @@ -75,7 +75,7 @@ $(function() { diff --git a/firmware/global_vars.cpp b/firmware/global_vars.cpp index 1359c7e..7297949 100644 --- a/firmware/global_vars.cpp +++ b/firmware/global_vars.cpp @@ -8,4 +8,5 @@ volatile TLC5615 dac0(spi, SPIADR::AA0); volatile TLC5615 dac1(spi, SPIADR::AA1); volatile ADU adu; volatile USART usart; +volatile PWM pwm; volatile bool nextRequest = false; diff --git a/firmware/global_vars.h b/firmware/global_vars.h index 749948c..218f50e 100644 --- a/firmware/global_vars.h +++ b/firmware/global_vars.h @@ -5,6 +5,7 @@ #include "tlc5615.h" #include "adu.h" #include "usart.h" +#include "pwm.h" #define WDT_TIMEOUT WDTO_15MS @@ -17,6 +18,7 @@ extern volatile TLC5615 dac0; extern volatile TLC5615 dac1; extern volatile ADU adu; extern volatile USART usart; +extern volatile PWM pwm; extern volatile bool nextRequest; #endif // GLOBAL_VARS_H diff --git a/firmware/main.cpp b/firmware/main.cpp index 59cd64b..96f004f 100644 --- a/firmware/main.cpp +++ b/firmware/main.cpp @@ -28,6 +28,8 @@ int main() usart.init(); usart.initRX(); + + pwm.init(); // Hauptschleife, Verarbeitung der Requests while(1) diff --git a/firmware/pwm.cpp b/firmware/pwm.cpp index 0716236..f747725 100644 --- a/firmware/pwm.cpp +++ b/firmware/pwm.cpp @@ -1,18 +1,32 @@ #include "pwm.h" +const uint16_t PWM::PRESCALERS[] = {0, 1, 8, 64, 256, 1024}; +const uint8_t PWM::PRESCALER_COUNT = sizeof(PRESCALERS) / sizeof(uint16_t); -void pwmSetFrequency(uint32_t freq) +void PWM::init() const volatile { + // fast pwm mode, top = OCR0A, non inverting mode TCCR0A = _BV(COM0B1) | _BV(WGM00) | _BV(WGM01); - DDRB |= _BV(PB4); + TCCR0B = _BV(WGM02); - uint16_t p_ideal = ceil(float(F_CPU) / (freq * 0x100)); - for(int8_t i = PWM_PRESCALER_COUNT - 1; i >= 0 && PWM_PRESCALERS[i] >= p_ideal; i--) - TCCR0B = _BV(WGM02) | i; // set prescaler - if(p_ideal) - OCR0A = (uint8_t) (float(F_CPU) / (freq * PWM_PRESCALERS[TCCR0B & 0x07])); + // output signal on PB4 + DDRB |= _BV(PB4); } -void pwmSetValue(uint8_t value) +void PWM::setFrequency(uint32_t freq) const volatile +{ + uint16_t p_ideal = ceil(float(F_CPU) / (freq * 0x100)); + for(int8_t i = PRESCALER_COUNT - 1; i >= 0 && PRESCALERS[i] >= p_ideal; i--) + TCCR0B = (TCCR0B & 0xF8) | i; // set prescaler + if(p_ideal) + OCR0A = (uint8_t) (float(F_CPU) / (freq * PRESCALERS[TCCR0B & 0x07])); +} + +void PWM::setValue(uint8_t value) const volatile { OCR0B = value; } + +uint8_t PWM::getTop() const volatile +{ + return OCR0A; +} diff --git a/firmware/pwm.h b/firmware/pwm.h index a42e11b..dcf0d63 100644 --- a/firmware/pwm.h +++ b/firmware/pwm.h @@ -4,10 +4,17 @@ #include #include -const uint16_t PWM_PRESCALERS[] = {0, 1, 8, 64, 256, 1024}; -const uint8_t PWM_PRESCALER_COUNT = sizeof(PWM_PRESCALERS) / sizeof(uint16_t); - -void pwmSetFrequency(uint32_t); -void pwmSetValue(uint8_t); +class PWM +{ +public: + void init(void) const volatile; + void setFrequency(uint32_t) const volatile; + void setValue(uint8_t) const volatile; + uint8_t getTop(void) const volatile; + +private: + const static uint16_t PRESCALERS[]; + const static uint8_t PRESCALER_COUNT; +}; #endif // PWM_H diff --git a/firmware/requests.cpp b/firmware/requests.cpp index 0d11d3f..55f5cf6 100644 --- a/firmware/requests.cpp +++ b/firmware/requests.cpp @@ -62,6 +62,14 @@ void handleRequest() case RQ_ADC_DAC_STROKE: rqAdcDacStroke(); break; + + case RQ_PWM_SET_FREQ: + rqPwmSetFreq(); + break; + + case RQ_PWM_SET_VALUE: + rqPwmSetValue(); + break; default: break; @@ -217,11 +225,21 @@ void rqAdcDacStroke() usart.flush(); } -void rqSetPwm() +void rqPwmSetFreq() +{ + usart.initTX(); + uint32_t freq = usart.readU32(); + pwm.setFrequency(freq); + + usart.writeByte(pwm.getTop()); + usart.flush(); +} + +void rqPwmSetValue() { usart.initTX(); uint16_t value = usart.readByte(); - OCR0A = value; + pwm.setValue(value); usart.writeByte(USART::MSG_OK); usart.flush(); diff --git a/firmware/requests.h b/firmware/requests.h index 6fd3012..418b003 100644 --- a/firmware/requests.h +++ b/firmware/requests.h @@ -21,7 +21,8 @@ constexpr static uint8_t RQ_AA0 = 10; constexpr static uint8_t RQ_AA1 = 11; constexpr static uint8_t RQ_ADC = 12; constexpr static uint8_t RQ_ADC_DAC_STROKE = 13; -constexpr static uint8_t RQ_SET_PWM = 14; +constexpr static uint8_t RQ_PWM_SET_FREQ = 14; +constexpr static uint8_t RQ_PWM_SET_VALUE = 15; uint8_t const rq_len[] = { /* RQ_DISC */ 1, @@ -38,7 +39,8 @@ uint8_t const rq_len[] = { /* RQ_AA1 */ 3, /* RQ_ADC */ 2, /* RQ_ADC_DAC_STROKE */ 9, - /* RQ_SET_PWM */ 2 + /* RQ_PWM_SET_FREQ */ 5, + /* RQ_PWM_SET_VALUE */ 2 }; /** @@ -61,6 +63,7 @@ void rqAnalogWrite0(void); void rqAnalogWrite1(void); void rqAnalogRead(void); void rqAdcDacStroke(void); -void rqSetPwm(void); +void rqPwmSetFreq(void); +void rqPwmSetValue(void); #endif // REQUESTS_H diff --git a/firmware/usart.cpp b/firmware/usart.cpp index d039fcf..8be2392 100644 --- a/firmware/usart.cpp +++ b/firmware/usart.cpp @@ -130,3 +130,10 @@ uint16_t USART::readInt() volatile v |= readByte() << 8; return v; } + +uint32_t USART::readU32() volatile +{ + uint32_t v = readInt(); + v |= ((uint32_t) readInt()) << 16; + return v; +} diff --git a/firmware/usart.h b/firmware/usart.h index 5505a1b..a6cd610 100644 --- a/firmware/usart.h +++ b/firmware/usart.h @@ -102,6 +102,12 @@ public: * \return gelesenes Integer */ uint16_t readInt(void) volatile; + + /** + * Liest ein uint32_t aus dem Eingangspuffer + * \return gelesenes uint32_t + */ + uint32_t readU32(void) volatile; /**********************/