B15F
Board 15 Famulus Edition
usart.cpp
1 #include <stdexcept>
2 #include "usart.h"
3 
5 {
6  closeDevice();
7 }
8 
9 void USART::openDevice(std::string device)
10 {
11  // Benutze blockierenden Modus
12  file_desc = open(device.c_str(), O_RDWR | O_NOCTTY);// | O_NDELAY
13  if (file_desc <= 0)
14  throw USARTException("Fehler beim Öffnen des Gerätes");
15 
16  struct termios options;
17  int code = tcgetattr(file_desc, &options);
18  if (code)
19  throw USARTException("Fehler beim Lesen der Geräteparameter");
20 
21  options.c_cflag = CS8 | CLOCAL | CREAD;
22  options.c_iflag = IGNPAR;
23  options.c_oflag = 0;
24  options.c_lflag = 0;
25  options.c_cc[VMIN] = 0;
26  options.c_cc[VTIME] = timeout;
27  code = cfsetspeed(&options, baudrate);
28  if (code)
29  throw USARTException("Fehler beim Setzen der Baudrate");
30 
31  code = tcsetattr(file_desc, TCSANOW, &options);
32  if (code)
33  throw USARTException("Fehler beim Setzen der Geräteparameter");
34 
35  code = fcntl(file_desc, F_SETFL, 0); // blockierender Modus
36  if (code)
37  throw USARTException("Fehler beim Aktivieren des blockierenden Modus'");
38 
41 }
42 
44 {
45  if (file_desc > 0)
46  {
47  int code = close(file_desc);
48  if (code)
49  throw USARTException("Fehler beim Schließen des Gerätes");
50  file_desc = -1;
51  }
52 }
53 
55 {
56  int code = tcflush(file_desc, TCIFLUSH);
57  if (code)
58  throw USARTException("Fehler beim Leeren des Eingangspuffers");
59 }
60 
62 {
63  int code = tcflush(file_desc, TCOFLUSH);
64  if (code)
65  throw USARTException("Fehler beim Leeren des Ausgangspuffers");
66 }
67 
69 {
70  int code = tcdrain(file_desc);
71  if (code)
72  throw USARTException("Fehler beim Versenden des Ausgangspuffers");
73 }
74 
75 void USART::transmit(uint8_t *buffer, uint16_t offset, uint8_t len)
76 {
77  int code = write(file_desc, buffer + offset, len);
78  if (code != len)
79  throw USARTException(
80  std::string(__FUNCTION__) + " failed: " + std::string(__FILE__) + "#" + std::to_string(__LINE__) +
81  ", " + strerror(code) + " (code " + std::to_string(code) + " / " + std::to_string(len) + ")");
82 }
83 
84 void USART::receive(uint8_t *buffer, uint16_t offset, uint8_t len)
85 {
86  int bytes_avail, code;
87  auto start = std::chrono::steady_clock::now();
88  auto end = std::chrono::steady_clock::now();
89  do
90  {
91  code = ioctl(file_desc, FIONREAD, &bytes_avail);
92  if (code)
93  throw USARTException(
94  std::string(__FUNCTION__) + " failed: " + std::string(__FILE__) + "#" + std::to_string(__LINE__) +
95  ", " + strerror(code) + " (code " + std::to_string(code) + ")");
96 
97  end = std::chrono::steady_clock::now();
98  long elapsed =
99  std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() / 100; // in Dezisekunden
100  if (elapsed >= timeout)
101  throw TimeoutException(
102  std::string(__FUNCTION__) + " failed: " + std::string(__FILE__) + "#" + std::to_string(__LINE__) +
103  ", " + std::to_string(elapsed) + " / " + std::to_string(timeout) + " ds");
104  }
105  while (bytes_avail < len);
106 
107  code = read(file_desc, buffer + offset, len);
108  if (code != len)
109  throw USARTException(
110  std::string(__FUNCTION__) + " failed: " + std::string(__FILE__) + "#" + std::to_string(__LINE__) +
111  ", " + strerror(code) + " (code " + std::to_string(code) + " / " + std::to_string(len) + ")");
112 }
113 
114 void USART::drop(uint8_t len)
115 {
116  // Kann bestimmt noch eleganter gelöst werden
117  uint8_t dummy[len];
118  receive(&dummy[0], 0, len);
119 }
120 
122 {
123  return baudrate;
124 }
125 
127 {
128  return timeout;
129 }
130 
131 void USART::setBaudrate(uint32_t baudrate)
132 {
133  this->baudrate = baudrate;
134 }
135 
136 void USART::setTimeout(uint8_t timeout)
137 {
138  this->timeout = timeout;
139 }
USART::getBaudrate
uint32_t getBaudrate(void)
Definition: usart.cpp:121
USARTException
Definition: usartexception.h:9
USART::closeDevice
void closeDevice(void)
Definition: usart.cpp:43
USART::transmit
void transmit(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:75
USART::receive
void receive(uint8_t *buffer, uint16_t offset, uint8_t len)
Definition: usart.cpp:84
USART::clearInputBuffer
void clearInputBuffer(void)
Definition: usart.cpp:54
USART::getTimeout
uint8_t getTimeout(void)
Definition: usart.cpp:126
USART::clearOutputBuffer
void clearOutputBuffer(void)
Definition: usart.cpp:61
USART::setBaudrate
void setBaudrate(uint32_t baudrate)
Definition: usart.cpp:131
USART::~USART
virtual ~USART(void)
Definition: usart.cpp:4
USART::openDevice
void openDevice(std::string device)
Definition: usart.cpp:9
USART::drop
void drop(uint8_t len)
Definition: usart.cpp:114
USART::setTimeout
void setTimeout(uint8_t timeout)
Definition: usart.cpp:136
USART::flushOutputBuffer
void flushOutputBuffer(void)
Definition: usart.cpp:68
TimeoutException
Definition: timeoutexception.h:9