Gordons Projects

--> Projects Top-Level GIT

A new version of wiringPi. Added in more stuff and fixed it up
[wiringPi] / 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 (const char *device, const 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     case  460800:       myBaud =  B460800 ; break ;
70     case  500000:       myBaud =  B500000 ; break ;
71     case  576000:       myBaud =  B576000 ; break ;
72     case  921600:       myBaud =  B921600 ; break ;
73     case 1000000:       myBaud = B1000000 ; break ;
74     case 1152000:       myBaud = B1152000 ; break ;
75     case 1500000:       myBaud = B1500000 ; break ;
76     case 2000000:       myBaud = B2000000 ; break ;
77     case 2500000:       myBaud = B2500000 ; break ;
78     case 3000000:       myBaud = B3000000 ; break ;
79     case 3500000:       myBaud = B3500000 ; break ;
80     case 4000000:       myBaud = B4000000 ; break ;
81
82     default:
83       return -2 ;
84   }
85
86   if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
87     return -1 ;
88
89   fcntl (fd, F_SETFL, O_RDWR) ;
90
91 // Get and modify current options:
92
93   tcgetattr (fd, &options) ;
94
95     cfmakeraw   (&options) ;
96     cfsetispeed (&options, myBaud) ;
97     cfsetospeed (&options, myBaud) ;
98
99     options.c_cflag |= (CLOCAL | CREAD) ;
100     options.c_cflag &= ~PARENB ;
101     options.c_cflag &= ~CSTOPB ;
102     options.c_cflag &= ~CSIZE ;
103     options.c_cflag |= CS8 ;
104     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
105     options.c_oflag &= ~OPOST ;
106
107     options.c_cc [VMIN]  =   0 ;
108     options.c_cc [VTIME] = 100 ;        // Ten seconds (100 deciseconds)
109
110   tcsetattr (fd, TCSANOW, &options) ;
111
112   ioctl (fd, TIOCMGET, &status);
113
114   status |= TIOCM_DTR ;
115   status |= TIOCM_RTS ;
116
117   ioctl (fd, TIOCMSET, &status);
118
119   usleep (10000) ;      // 10mS
120
121   return fd ;
122 }
123
124
125 /*
126  * serialFlush:
127  *      Flush the serial buffers (both tx & rx)
128  *********************************************************************************
129  */
130
131 void serialFlush (const int fd)
132 {
133   tcflush (fd, TCIOFLUSH) ;
134 }
135
136
137 /*
138  * serialClose:
139  *      Release the serial port
140  *********************************************************************************
141  */
142
143 void serialClose (const int fd)
144 {
145   close (fd) ;
146 }
147
148
149 /*
150  * serialPutchar:
151  *      Send a single character to the serial port
152  *********************************************************************************
153  */
154
155 void serialPutchar (const int fd, const unsigned char c)
156 {
157   write (fd, &c, 1) ;
158 }
159
160
161 /*
162  * serialPuts:
163  *      Send a string to the serial port
164  *********************************************************************************
165  */
166
167 void serialPuts (const int fd, const char *s)
168 {
169   write (fd, s, strlen (s)) ;
170 }
171
172 /*
173  * serialPrintf:
174  *      Printf over Serial
175  *********************************************************************************
176  */
177
178 void serialPrintf (const int fd, const char *message, ...)
179 {
180   va_list argp ;
181   char buffer [1024] ;
182
183   va_start (argp, message) ;
184     vsnprintf (buffer, 1023, message, argp) ;
185   va_end (argp) ;
186
187   serialPuts (fd, buffer) ;
188 }
189
190
191 /*
192  * serialDataAvail:
193  *      Return the number of bytes of data avalable to be read in the serial port
194  *********************************************************************************
195  */
196
197 int serialDataAvail (const int fd)
198 {
199   int result ;
200
201   if (ioctl (fd, FIONREAD, &result) == -1)
202     return -1 ;
203
204   return result ;
205 }
206
207
208 /*
209  * serialGetchar:
210  *      Get a single character from the serial device.
211  *      Note: Zero is a valid character and this function will time-out after
212  *      10 seconds.
213  *********************************************************************************
214  */
215
216 int serialGetchar (const int fd)
217 {
218   uint8_t x ;
219
220   if (read (fd, &x, 1) != 1)
221     return -1 ;
222
223   return ((int)x) & 0xFF ;
224 }