00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <sys/signal.h>
00013 #include <termios.h>
00014 #include <stdio.h>
00015 #include <unistd.h>
00016 #include <fcntl.h>
00017 #include <sys/types.h>
00018 #include <string.h>
00019 #include <stdlib.h>
00020 #include <asm-x86_64/types.h>
00021 #include "sercom.h"
00022
00023 unsigned char sercom_wait_flag = 1;
00024
00025 void sercom_sighandler(int status)
00026 {
00027
00028 sercom_wait_flag = 0;
00029 }
00030
00037 long sercom_get_baudrate(unsigned int baudrate)
00038 {
00039 long br;
00040 switch (baudrate) {
00041 case 38400:
00042 br = B38400;
00043 break;
00044 case 19200:
00045 br = B19200;
00046 break;
00047 case 9600:
00048 br = B9600;
00049 break;
00050 case 4800:
00051 br = B4800;
00052 break;
00053 case 2400:
00054 br = B2400;
00055 break;
00056 case 1800:
00057 br = B1800;
00058 break;
00059 case 1200:
00060 br = B1200;
00061 break;
00062 case 600:
00063 br = B600;
00064 break;
00065 case 300:
00066 br = B300;
00067 break;
00068 case 200:
00069 br = B200;
00070 break;
00071 case 150:
00072 br = B150;
00073 break;
00074 case 134:
00075 br = B134;
00076 break;
00077 case 110:
00078 br = B110;
00079 break;
00080 case 75:
00081 br = B75;
00082 break;
00083 case 50:
00084 br = B50;
00085 break;
00086 default:
00087 br = B19200;
00088 }
00089
00090 return br;
00091 }
00092
00099 long sercom_get_databits(int databits)
00100 {
00101 long db;
00102 switch (databits) {
00103 case 8:
00104 default:
00105 db = CS8;
00106 break;
00107 case 7:
00108 db = CS7;
00109 break;
00110 case 6:
00111 db = CS6;
00112 break;
00113 case 5:
00114 db = CS5;
00115 break;
00116 }
00117 return db;
00118 }
00119
00126 long sercom_get_stopbits(int stopbits)
00127 {
00128 long sb;
00129 switch (stopbits) {
00130 case 1:
00131 default:
00132 sb = 0;
00133 break;
00134 case 2:
00135 sb = CSTOPB;
00136 break;
00137 }
00138 return sb;
00139 }
00140
00147 long sercom_get_parity(int parity)
00148 {
00149 long par, paron;
00150 switch (parity) {
00151
00152 case 0:
00153 default:
00154 paron = 0;
00155 par = 0;
00156 break;
00157
00158 case 1:
00159 paron = PARENB;
00160 par = PARODD;
00161 break;
00162
00163 case 2:
00164 paron = PARENB;
00165 par = 0;
00166 break;
00167 }
00168 return (par|paron);
00169 }
00170
00176 void sercom_open(struct sercom_data *sercom)
00177 {
00178
00179
00180
00181 if (sercom->devname[0] == 0)
00182 strcpy((char *)&sercom->devname, SERCOM_DEFAULT_DEV);
00183 sercom->fd = open(sercom->devname, O_RDWR | O_NOCTTY | O_NONBLOCK);
00184 if (sercom->fd < 0) {
00185 perror(sercom->devname);
00186 exit(-1);
00187 }
00188
00189
00190 sercom->saio.sa_handler = sercom_sighandler;
00191 sercom->saio.sa_flags = 0;
00192 sercom->saio.sa_restorer = NULL;
00193 sigemptyset(&sercom->saio.sa_mask);
00194 sigaction(SIGIO, &sercom->saio, NULL);
00195
00196
00197 fcntl(sercom->fd, F_SETOWN, getpid());
00198
00199
00200 fcntl(sercom->fd, F_SETFL, FASYNC);
00201
00202 tcgetattr(sercom->fd, &sercom->oldtio);
00203 memset(&sercom->newtio, 0, sizeof(sercom->newtio));
00204
00205 sercom->newtio.c_cflag = sercom_get_baudrate(sercom->baudrate) |
00206 sercom_get_databits(sercom->databits) |
00207 sercom_get_stopbits(sercom->stopbits) |
00208 sercom_get_parity(sercom->parity) |
00209 CRTSCTS | CLOCAL | CREAD;
00210 sercom->newtio.c_iflag = IGNPAR | ICRNL;
00211 sercom->newtio.c_oflag = 0;
00212 sercom->newtio.c_lflag = ICANON;
00213
00214 sercom->newtio.c_cc[VMIN] = 1;
00215 sercom->newtio.c_cc[VTIME] = 0;
00216
00217 tcflush(sercom->fd, TCIFLUSH);
00218 tcsetattr(sercom->fd, TCSANOW, &sercom->newtio);
00219 }
00220
00229 ssize_t sercom_read(struct sercom_data *sercom, char *buf, ssize_t buflen)
00230 {
00231 ssize_t len = -1;
00232
00233 if (sercom_wait_flag == 0) {
00234 len = read(sercom->fd, buf, buflen);
00235 buf[len] = 0;
00236 sercom_wait_flag = 1;
00237 }
00238
00239 return len;
00240 }
00241
00247 void sercom_close(struct sercom_data *sercom)
00248 {
00249
00250 tcsetattr(sercom->fd, TCSANOW, &sercom->oldtio);
00251 close(sercom->fd);
00252 }