chiark / gitweb /
28ec598e5645874ce8af79c43ad8345d7d8d2ac9
[wiringPi.git] / wiringPi / wiringSerial.c
1 /*
2  * wiringSerial.c:
3  *      Handle a serial port
4  ***********************************************************************
5  * This file is part of wiringPi:
6  *      https://projects.drogon.net/raspberry-pi/wiringpi/
7  *
8  *    wiringPi is free software: you can redistribute it and/or modify
9  *    it under the terms of the GNU Lesser General Public License as published by
10  *    the Free Software Foundation, either version 3 of the License, or
11  *    (at your option) any later version.
12  *
13  *    wiringPi is distributed in the hope that it will be useful,
14  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *    GNU Lesser General Public License for more details.
17  *
18  *    You should have received a copy of the GNU Lesser General Public License
19  *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
20  ***********************************************************************
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdint.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <termios.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34
35 #include "wiringSerial.h"
36
37 /*
38  * serialOpen:
39  *      Open and initialise the serial port, setting all the right
40  *      port parameters - or as many as are required - hopefully!
41  *********************************************************************************
42  */
43
44 int serialOpen (char *device, int baud)
45 {
46   struct termios options ;
47   speed_t myBaud ;
48   int     status, fd ;
49
50   switch (baud)
51   {
52     case     50:        myBaud =     B50 ; break ;
53     case     75:        myBaud =     B75 ; break ;
54     case    110:        myBaud =    B110 ; break ;
55     case    134:        myBaud =    B134 ; break ;
56     case    150:        myBaud =    B150 ; break ;
57     case    200:        myBaud =    B200 ; break ;
58     case    300:        myBaud =    B300 ; break ;
59     case    600:        myBaud =    B600 ; break ;
60     case   1200:        myBaud =   B1200 ; break ;
61     case   1800:        myBaud =   B1800 ; break ;
62     case   2400:        myBaud =   B2400 ; break ;
63     case   9600:        myBaud =   B9600 ; break ;
64     case  19200:        myBaud =  B19200 ; break ;
65     case  38400:        myBaud =  B38400 ; break ;
66     case  57600:        myBaud =  B57600 ; break ;
67     case 115200:        myBaud = B115200 ; break ;
68     case 230400:        myBaud = B230400 ; break ;
69
70     default:
71       return -2 ;
72   }
73
74   if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
75     return -1 ;
76
77   fcntl (fd, F_SETFL, O_RDWR) ;
78
79 // Get and modify current options:
80
81   tcgetattr (fd, &options) ;
82
83     cfmakeraw   (&options) ;
84     cfsetispeed (&options, myBaud) ;
85     cfsetospeed (&options, myBaud) ;
86
87     options.c_cflag |= (CLOCAL | CREAD) ;
88     options.c_cflag &= ~PARENB ;
89     options.c_cflag &= ~CSTOPB ;
90     options.c_cflag &= ~CSIZE ;
91     options.c_cflag |= CS8 ;
92     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
93     options.c_oflag &= ~OPOST ;
94
95     options.c_cc [VMIN]  =   0 ;
96     options.c_cc [VTIME] = 100 ;        // Ten seconds (100 deciseconds)
97
98   tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ;
99
100   ioctl (fd, TIOCMGET, &status);
101
102   status |= TIOCM_DTR ;
103   status |= TIOCM_RTS ;
104
105   ioctl (fd, TIOCMSET, &status);
106
107   usleep (10000) ;      // 10mS
108
109   return fd ;
110 }
111
112
113 /*
114  * serialFlush:
115  *      Flush the serial buffers (both tx & rx)
116  *********************************************************************************
117  */
118
119 void serialFlush (int fd)
120 {
121   tcflush (fd, TCIOFLUSH) ;
122 }
123
124
125 /*
126  * serialClose:
127  *      Release the serial port
128  *********************************************************************************
129  */
130
131 void serialClose (int fd)
132 {
133   close (fd) ;
134 }
135
136
137 /*
138  * serialPutchar:
139  *      Send a single character to the serial port
140  *********************************************************************************
141  */
142
143 void serialPutchar (int fd, unsigned char c)
144 {
145   write (fd, &c, 1) ;
146 }
147
148
149 /*
150  * serialPuts:
151  *      Send a string to the serial port
152  *********************************************************************************
153  */
154
155 void serialPuts (int fd, char *s)
156 {
157   write (fd, s, strlen (s)) ;
158 }
159
160 /*
161  * serialPrintf:
162  *      Printf over Serial
163  *********************************************************************************
164  */
165
166 void serialPrintf (int fd, char *message, ...)
167 {
168   va_list argp ;
169   char buffer [1024] ;
170
171   va_start (argp, message) ;
172     vsnprintf (buffer, 1023, message, argp) ;
173   va_end (argp) ;
174
175   serialPuts (fd, buffer) ;
176 }
177
178
179 /*
180  * serialDataAvail:
181  *      Return the number of bytes of data avalable to be read in the serial port
182  *********************************************************************************
183  */
184
185 int serialDataAvail (int fd)
186 {
187   int result ;
188
189   if (ioctl (fd, FIONREAD, &result) == -1)
190     return -1 ;
191
192   return result ;
193 }
194
195
196 /*
197  * serialGetchar:
198  *      Get a single character from the serial device.
199  *      Note: Zero is a valid character and this function will time-out after
200  *      10 seconds.
201  *********************************************************************************
202  */
203
204 int serialGetchar (int fd)
205 {
206   uint8_t x ;
207
208   if (read (fd, &x, 1) != 1)
209     return -1 ;
210
211   return ((int)x) & 0xFF ;
212 }