]> git.tdb.fi Git - libs/core.git/blob - source/io/unix/serial.cpp
Add a class for monitoring changes in files
[libs/core.git] / source / io / unix / serial.cpp
1 #include <fcntl.h>
2 #include <termios.h>
3 #include <msp/core/systemerror.h>
4 #include <msp/strings/format.h>
5 #include "handle_private.h"
6 #include "serial.h"
7 #include "serial_private.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace IO {
13
14 void Serial::platform_init(const string &port)
15 {
16         string fn = port;
17         if(fn.compare(0, 5, "/dev/"))
18                 fn = "/dev/"+fn;
19
20         *handle = open(fn.c_str(), O_RDWR);
21         if(!handle)
22                 throw system_error(format("open(%s)", port));
23         mode = M_READ|M_WRITE;
24
25         termios t;
26         tcgetattr(*handle, &t);
27         t.c_iflag &= ~(ISTRIP|INLCR|IGNCR|ICRNL|IXON);
28         t.c_lflag &= ~(ECHO|ICANON|ISIG|IEXTEN);
29         t.c_oflag &= ~(OPOST|OCRNL|ONOCR|ONLRET);
30         t.c_cc[VMIN] = 1;
31         t.c_cc[VTIME] = 0;
32         tcsetattr(*handle, TCSADRAIN, &t);
33 }
34
35
36 void Serial::DeviceState::get_from(const Handle &h)
37 {
38         tcgetattr(*h, &state);
39 }
40
41 void Serial::DeviceState::apply_to(const Handle &h)
42 {
43         if(tcsetattr(*h, TCSADRAIN, &state)==-1)
44                 throw system_error("tcsetattr");
45 }
46
47 void Serial::DeviceState::set_baud_rate(unsigned baud)
48 {
49         speed_t speed;
50         switch(baud)
51         {
52         case 0:      speed = B0; break;
53         case 50:     speed = B50; break;
54         case 75:     speed = B75; break;
55         case 110:    speed = B110; break;
56         case 134:    speed = B134; break;
57         case 150:    speed = B150; break;
58         case 200:    speed = B200; break;
59         case 300:    speed = B300; break;
60         case 600:    speed = B600; break;
61         case 1200:   speed = B1200; break;
62         case 1800:   speed = B1800; break;
63         case 2400:   speed = B2400; break;
64         case 4800:   speed = B4800; break;
65         case 9600:   speed = B9600; break;
66         case 19200:  speed = B19200; break;
67         case 38400:  speed = B38400; break;
68         case 57600:  speed = 0010001; break;
69         case 115200: speed = 0010002; break;
70         case 230400: speed = 0010003; break;
71         case 460800: speed = 0010004; break;
72         case 500000: speed = 0010005; break;
73         case 576000: speed = 0010006; break;
74         case 921600: speed = 0010007; break;
75         case 1000000: speed = 0010010; break;
76         case 1152000: speed = 0010011; break;
77         case 1500000: speed = 0010012; break;
78         case 2000000: speed = 0010013; break;
79         case 2500000: speed = 0010014; break;
80         case 3000000: speed = 0010015; break;
81         case 3500000: speed = 0010016; break;
82         case 4000000: speed = 0010017; break;
83         default: throw invalid_argument("set_baud_rate");
84         }
85
86         int ret = cfsetospeed(&state, speed);
87         if(ret==0)
88                 ret = cfsetispeed(&state, speed);
89         if(ret<0)
90                 throw invalid_argument("set_baud_rate");
91 }
92
93 void Serial::DeviceState::set_data_bits(unsigned bits)
94 {
95         tcflag_t flag;
96         switch(bits)
97         {
98         case 5: flag = CS5; break;
99         case 6: flag = CS6; break;
100         case 7: flag = CS7; break;
101         case 8: flag = CS8; break;
102         default: throw invalid_argument("set_data_bits");
103         }
104
105         state.c_cflag = (state.c_cflag&~CSIZE)|flag;
106 }
107
108 void Serial::DeviceState::set_parity(Serial::Parity par)
109 {
110         tcflag_t flag;
111         switch(par)
112         {
113         case Serial::NONE: flag = 0; break;
114         case Serial::EVEN: flag = PARENB; break;
115         case Serial::ODD:  flag = PARENB|PARODD; break;
116         default: throw invalid_argument("set_parity");
117         }
118
119         state.c_cflag = (state.c_cflag&~(PARENB|PARODD))|flag;
120 }
121
122 void Serial::DeviceState::set_stop_bits(unsigned bits)
123 {
124         tcflag_t flag;
125         switch(bits)
126         {
127         case 1: flag = 0; break;
128         case 2: flag = CSTOPB; break;
129         default: throw invalid_argument("set_stop_bits");
130         }
131
132         state.c_cflag = (state.c_cflag&~CSTOPB)|flag;
133 }
134
135 } // namespace IO
136 } // namespace MSp