B15F Board 15 Famulus Edition

usart.cpp
1 #include <stdexcept>
2 #include "usart.h"
3
4 USART::~USART()
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
39 clearOutputBuffer();
40 clearInputBuffer();
41 }
42
43 void USART::closeDevice()
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
54 void USART::clearInputBuffer()
55 {
56 int code = tcflush(file_desc, TCIFLUSH);
57 if (code)
58 throw USARTException("Fehler beim Leeren des Eingangspuffers");
59 }
60
61 void USART::clearOutputBuffer()
62 {
63 int code = tcflush(file_desc, TCOFLUSH);
64 if (code)
65 throw USARTException("Fehler beim Leeren des Ausgangspuffers");
66 }
67
68 void USART::flushOutputBuffer()
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
121 uint32_t USART::getBaudrate()
122 {
123 return baudrate;
124 }
125
126 uint8_t USART::getTimeout()
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