You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.2 KiB
148 lines
5.2 KiB
/* |
|
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); |
|
}
|
|
|