Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
libxbee - a C library to aid the use of Digi's Series 1 XBee modules
running in API mode (AP=2).
Copyright (C) 2009 Attie Grande (attie@attie.co.uk)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ################################################################# */
/* ### Linux Code ################################################## */
/* ################################################################# */
/* this file contains code that is used by Linux ONLY */
#ifndef __GNUC__
#error "This file should only be used on a Linux system"
#endif
#include "linux.h"
int init_serial(xbee_hnd xbee, int baudrate) {
struct flock fl;
struct termios tc;
speed_t chosenbaud;
/* select the baud rate */
switch (baudrate) {
case 1200: chosenbaud = B1200; break;
case 2400: chosenbaud = B2400; break;
case 4800: chosenbaud = B4800; break;
case 9600: chosenbaud = B9600; break;
case 19200: chosenbaud = B19200; break;
case 38400: chosenbaud = B38400; break;
case 57600: chosenbaud = B57600; break;
case 115200:chosenbaud = B115200; break;
default:
fprintf(stderr,"%s(): Unknown or incompatiable baud rate specified... (%d)\n",__FUNCTION__,baudrate);
return -1;
};
/* open the serial port as a file descriptor */
if ((xbee->ttyfd = open(xbee->path,O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1) {
xbee_perror("xbee_setup():open()");
xbee_mutex_destroy(xbee->conmutex);
xbee_mutex_destroy(xbee->pktmutex);
xbee_mutex_destroy(xbee->sendmutex);
Xfree(xbee->path);
return -1;
}
/* lock the file */
fl.l_type = F_WRLCK | F_RDLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
if (fcntl(xbee->ttyfd, F_SETLK, &fl) == -1) {
xbee_perror("xbee_setup():fcntl()");
xbee_mutex_destroy(xbee->conmutex);
xbee_mutex_destroy(xbee->pktmutex);
xbee_mutex_destroy(xbee->sendmutex);
Xfree(xbee->path);
close(xbee->ttyfd);
return -1;
}
/* open the serial port as a FILE* */
if ((xbee->tty = fdopen(xbee->ttyfd,"r+")) == NULL) {
xbee_perror("xbee_setup():fdopen()");
xbee_mutex_destroy(xbee->conmutex);
xbee_mutex_destroy(xbee->pktmutex);
xbee_mutex_destroy(xbee->sendmutex);
Xfree(xbee->path);
close(xbee->ttyfd);
return -1;
}
/* flush the serial port */
fflush(xbee->tty);
/* disable buffering */
setvbuf(xbee->tty,NULL,_IONBF,BUFSIZ);
/* setup the baud rate and other io attributes */
tcgetattr(xbee->ttyfd, &tc);
/* input flags */
tc.c_iflag &= ~ IGNBRK; /* enable ignoring break */
tc.c_iflag &= ~(IGNPAR | PARMRK); /* disable parity checks */
tc.c_iflag &= ~ INPCK; /* disable parity checking */
tc.c_iflag &= ~ ISTRIP; /* disable stripping 8th bit */
tc.c_iflag &= ~(INLCR | ICRNL); /* disable translating NL <-> CR */
tc.c_iflag &= ~ IGNCR; /* disable ignoring CR */
tc.c_iflag &= ~(IXON | IXOFF); /* disable XON/XOFF flow control */
/* output flags */
tc.c_oflag &= ~ OPOST; /* disable output processing */
tc.c_oflag &= ~(ONLCR | OCRNL); /* disable translating NL <-> CR */
tc.c_oflag &= ~ OFILL; /* disable fill characters */
/* control flags */
tc.c_cflag |= CREAD; /* enable reciever */
tc.c_cflag &= ~ PARENB; /* disable parity */
tc.c_cflag &= ~ CSTOPB; /* disable 2 stop bits */
tc.c_cflag &= ~ CSIZE; /* remove size flag... */
tc.c_cflag |= CS8; /* ...enable 8 bit characters */
tc.c_cflag |= HUPCL; /* enable lower control lines on close - hang up */
/* local flags */
tc.c_lflag &= ~ ISIG; /* disable generating signals */
tc.c_lflag &= ~ ICANON; /* disable canonical mode - line by line */
tc.c_lflag &= ~ ECHO; /* disable echoing characters */
tc.c_lflag &= ~ ECHONL; /* ??? */
tc.c_lflag &= ~ NOFLSH; /* disable flushing on SIGINT */
tc.c_lflag &= ~ IEXTEN; /* disable input processing */
/* control characters */
memset(tc.c_cc,0,sizeof(tc.c_cc));
/* i/o rates */
cfsetspeed(&tc, chosenbaud); /* set i/o baud rate */
tcsetattr(xbee->ttyfd, TCSANOW, &tc);
tcflow(xbee->ttyfd, TCOON|TCION); /* enable input & output transmission */
return 0;
}
static int xbee_select(xbee_hnd xbee, struct timeval *timeout) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(xbee->ttyfd, &fds);
return select(xbee->ttyfd+1, &fds, NULL, NULL, timeout);
}
#define xbee_sem_wait1sec(a) xbee_sem_wait1sec2(&(a))
static inline int xbee_sem_wait1sec2(xbee_sem_t *sem) {
struct timespec to;
clock_gettime(CLOCK_REALTIME,&to);
to.tv_sec++;
return sem_timedwait(sem,&to);
}