2468c02238b85d7abbe9712981ad2e39795c9508
[platform/core/system/peripheral-bus.git] / src / interface / uart.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <termios.h>
24 #include <stdbool.h>
25 #include <sys/ioctl.h>
26
27 #include "uart.h"
28 #include "peripheral_common.h"
29
30 #define SYSFS_UART_PATH         "/dev/ttySAC"
31
32 #define PATH_BUF_MAX            64
33 #define UART_BUF_MAX            16
34
35 #define UART_BAUDRATE_SIZE      19
36
37 static const int peripheral_uart_br[UART_BAUDRATE_SIZE] = {
38         B0,                     B50,            B75,            B110,           B134,
39         B150,           B200,           B300,           B600,           B1200,
40         B1800,          B2400,          B4800,          B9600,          B19200,
41         B38400,         B57600,         B115200,        B230400
42 };
43
44 static const int byteinfo[4] = {CS5, CS6, CS7, CS8};
45
46 int uart_open(int port, int *file_hndl)
47 {
48         int fd;
49         char fName[PATH_BUF_MAX] = {0};
50
51         _D("port : %d", port);
52
53         snprintf(fName, PATH_BUF_MAX, SYSFS_UART_PATH "%d", port);
54         if ((fd = open(fName, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
55                 _E("Error[%d]: can't open %s, %s--[%d]\n", errno, fName, __FUNCTION__, __LINE__);
56                 return -ENXIO;
57         }
58         *file_hndl = fd;
59         return 0;
60 }
61
62 int uart_close(int file_hndl)
63 {
64         _D("file_hndl : %d", file_hndl);
65
66         if (!file_hndl) {
67                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
68                 return -EINVAL;
69         }
70         close(file_hndl);
71         return 0;
72 }
73
74 int uart_flush(int file_hndl)
75 {
76         int ret;
77
78         if (!file_hndl) {
79                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
80                 return -EINVAL;
81         }
82
83         ret = tcflush(file_hndl, TCIOFLUSH);
84         if (ret < 0) {
85                 _E("FAILED[%d]: tcflush, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
86                 return -1;
87         }
88
89         return 0;
90 }
91
92 int uart_set_baudrate(int file_hndl, uart_baudrate_e baud)
93 {
94         int ret;
95         struct termios tio;
96
97         _D("file_hndl : %d, baud : %d", file_hndl, baud);
98
99         memset(&tio, 0, sizeof(tio));
100         if (!file_hndl) {
101                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
102                 return -EINVAL;
103         }
104
105         if (baud > UART_BAUDRATE_230400) {
106                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
107                 return -EINVAL;
108         }
109
110         ret = tcgetattr(file_hndl, &tio);
111         if (ret) {
112                 _E("Error[%d]: tcgetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
113                 return -1;
114         }
115         tio.c_cflag = peripheral_uart_br[baud];
116         tio.c_iflag = IGNPAR;
117         tio.c_oflag = 0;
118         tio.c_lflag = 0;
119         tio.c_cc[VMIN] = 1;
120         tio.c_cc[VTIME] = 0;
121
122         uart_flush(file_hndl);
123         ret = tcsetattr(file_hndl, TCSANOW, &tio);
124         if (ret) {
125                 _E("Error[%d]: tcsetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
126                 return -1;
127         }
128
129         return 0;
130 }
131
132 int uart_set_mode(int file_hndl, uart_bytesize_e bytesize, uart_parity_e parity, uart_stopbits_e stopbits)
133 {
134         int ret;
135         struct termios tio;
136
137         _D("file_hndl : %d, bytesize : %d, parity : %d, stopbits : %d", file_hndl, bytesize, parity, stopbits);
138
139         if (!file_hndl) {
140                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
141                 return -EINVAL;
142         }
143
144         ret = tcgetattr(file_hndl, &tio);
145         if (ret) {
146                 _E("Error[%d]: tcgetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
147                 return -1;
148         }
149
150         /* set byte size */
151         if (bytesize < UART_BYTESIZE_5BIT || bytesize > UART_BYTESIZE_8BIT) {
152                 _E("Error[%d]: Invalid parameter bytesize, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
153                 return -EINVAL;
154         }
155         tio.c_cflag &= ~CSIZE;
156         tio.c_cflag |= byteinfo[bytesize];
157         tio.c_cflag |= (CLOCAL | CREAD);
158
159         /* set parity info */
160         switch (parity) {
161         case UART_PARITY_EVEN:
162                 tio.c_cflag |= PARENB;
163                 tio.c_cflag &= ~PARODD;
164                 break;
165         case UART_PARITY_ODD:
166                 tio.c_cflag |= PARENB;
167                 tio.c_cflag |= PARODD;
168                 break;
169         case UART_PARITY_NONE:
170         default:
171                 tio.c_cflag &= ~PARENB;
172                 tio.c_cflag &= ~PARODD;
173                 break;
174         }
175
176         /* set stop bit */
177         switch (stopbits) {
178         case UART_STOPBITS_1BIT:
179                 tio.c_cflag &= ~CSTOPB;
180                 break;
181         case UART_STOPBITS_2BIT:
182                 tio.c_cflag |= CSTOPB;
183                 break;
184         default:
185                 _E("Error[%d]: Invalid parameter stopbits, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
186                 return -EINVAL;
187         }
188
189         uart_flush(file_hndl);
190         ret = tcsetattr(file_hndl, TCSANOW, &tio);
191         if (ret) {
192                 _E("Error[%d]: tcsetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
193                 return -1;
194         }
195
196         return 0;
197 }
198
199 int uart_set_flowcontrol(int file_hndl, bool xonxoff, bool rtscts)
200 {
201         int ret;
202         struct termios tio;
203
204         _D("file_hndl : %d, xonxoff : %d, rtscts : %d", file_hndl, xonxoff, rtscts);
205
206         if (!file_hndl) {
207                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
208                 return -EINVAL;
209         }
210
211         ret = tcgetattr(file_hndl, &tio);
212         if (ret) {
213                 _E("Error[%d]: tcgetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
214                 return -1;
215         }
216
217         /* rtscts => 1: rts/cts on, 0: off */
218         if (rtscts)
219                 tio.c_cflag |= CRTSCTS;
220         else
221                 tio.c_cflag &= ~CRTSCTS;
222
223         /* xonxoff => 1: xon/xoff on, 0: off */
224         if (xonxoff)
225                 tio.c_iflag |= (IXON | IXOFF | IXANY);
226         else
227                 tio.c_iflag &= ~(IXON | IXOFF | IXANY);
228
229         ret = tcsetattr(file_hndl, TCSANOW, &tio);
230         if (ret) {
231                 _E("Error[%d]: tcsetattr, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
232                 return -1;
233         }
234
235         return 0;
236 }
237
238 int uart_read(int file_hndl, uint8_t *buf, unsigned int length)
239 {
240         int ret;
241         if (!file_hndl) {
242                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
243                 return -EINVAL;
244         }
245
246         ret = read(file_hndl, (void *)buf, length);
247         if ((errno != EAGAIN && errno != EINTR) && ret < 0) {
248                 _E("Error[%d]: read, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
249                 return -EIO;
250         }
251
252         return ret;
253 }
254
255 int uart_write(int file_hndl, uint8_t *buf, unsigned int length)
256 {
257         int ret;
258         if (!file_hndl) {
259                 _E("Error[%d]: Invalid parameter, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
260                 return -EINVAL;
261         }
262
263         ret = write(file_hndl, buf, length);
264         if (ret < 0) {
265                 _E("Error[%d]: write, %s--[%d]\n", errno, __FUNCTION__, __LINE__);
266                 return -EIO;
267         }
268
269         return ret;
270 }