Gordons Projects

--> Projects Top-Level GIT

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