drivers/can_serial/can_serial.c
changeset 448 732c33c2d8a7
child 631 08b6b903f84a
equal deleted inserted replaced
447:c9d01296d6d9 448:732c33c2d8a7
       
     1 /*
       
     2 This file is part of CanFestival, a library implementing CanOpen Stack. 
       
     3 
       
     4 Copyright (C): Edouard TISSERANT and Francis DUPIN
       
     5 
       
     6 Ruthlessly butchered by James Steward to produce a serial (tty) port
       
     7 driver.
       
     8 
       
     9 See COPYING file for copyrights details.
       
    10 
       
    11 This library is free software; you can redistribute it and/or
       
    12 modify it under the terms of the GNU Lesser General Public
       
    13 License as published by the Free Software Foundation; either
       
    14 version 2.1 of the License, or (at your option) any later version.
       
    15 
       
    16 This library is distributed in the hope that it will be useful,
       
    17 but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 Lesser General Public License for more details.
       
    20 
       
    21 You should have received a copy of the GNU Lesser General Public
       
    22 License along with this library; if not, write to the Free Software
       
    23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 */
       
    25 
       
    26 /*
       
    27 	Single serial port CAN driver.
       
    28 */
       
    29 
       
    30 #include <stdio.h>
       
    31 #include <unistd.h>
       
    32 #include <fcntl.h>
       
    33 #include <errno.h>
       
    34 #include <string.h>
       
    35 #include <termios.h>
       
    36 #include <stdlib.h>
       
    37 
       
    38 #define NEED_PRINT_MESSAGE
       
    39 #include "can_driver.h"
       
    40 #include "def.h"
       
    41 
       
    42 typedef struct {
       
    43 	int fd;
       
    44 	struct termios old_termio, new_termio;
       
    45 } CANPort;
       
    46 
       
    47 /*********functions which permit to communicate with the board****************/
       
    48 UNS8 canReceive_driver(CAN_HANDLE fd0, Message * m)
       
    49 {
       
    50 	int rv, N, n = 0;
       
    51 	fd_set rfds;
       
    52 	struct timeval tv;
       
    53 
       
    54 	N = 4; //initially try to read 4 bytes, including the length byte
       
    55 	
       
    56 retry:
       
    57 	rv = read(((CANPort *) fd0)->fd, &((char *)m)[n], N - n);
       
    58 
       
    59 	if (rv == -1) {
       
    60 		fprintf(stderr, "read: %s\n", strerror(errno));
       
    61 		return 1;
       
    62 	}
       
    63 
       
    64 	n += rv;
       
    65 
       
    66 	if (n == 4) {
       
    67 		N = (4 + m->len);
       
    68 		
       
    69 		if (m->len > 8) {
       
    70 			fprintf(stderr, "Warning: invalid message length %d\n", 
       
    71 					m->len);
       
    72 			
       
    73 			//try to resync
       
    74 			n = 0;
       
    75 			N = 4;
       
    76 		}
       
    77 
       
    78 	}
       
    79 
       
    80 	if (n < N) {
       
    81 
       
    82 		FD_ZERO(&rfds);
       
    83 		FD_SET(((CANPort *) fd0)->fd, &rfds);
       
    84 
       
    85 		tv.tv_sec = 0;
       
    86 		tv.tv_usec=100000;
       
    87 		
       
    88 		rv = select(((CANPort *) fd0)->fd + 1, &rfds, NULL, NULL, &tv);
       
    89 		if (rv == -1) {
       
    90 			fprintf(stderr, "select: %s\n", strerror(errno));
       
    91 			return 1;
       
    92 		} else if (rv == 0) {
       
    93 			n = 0;
       
    94 		}
       
    95 
       
    96 		goto retry;	
       
    97 	}
       
    98 
       
    99 	print_message(m);
       
   100 
       
   101 	return 0;
       
   102 }
       
   103 
       
   104 /***************************************************************************/
       
   105 UNS8 canSend_driver(CAN_HANDLE fd0, Message * m)
       
   106 {
       
   107 	int rv;
       
   108 
       
   109 	print_message(m);
       
   110 
       
   111 	// Send to serial port 
       
   112 	rv = write(((CANPort *) fd0)->fd, m, 4 + m->len);
       
   113 
       
   114 	if (rv != 4 + m->len) {
       
   115 		return 1;
       
   116 	}
       
   117 
       
   118 	return 0;
       
   119 }
       
   120 
       
   121 /***************************************************************************/
       
   122 int TranslateBaudRate(char *optarg)
       
   123 {
       
   124 	if (!strcmp(optarg, "1M"))
       
   125 		return (int) 1000;
       
   126 	if (!strcmp(optarg, "500K"))
       
   127 		return (int) 500;
       
   128 	if (!strcmp(optarg, "250K"))
       
   129 		return (int) 250;
       
   130 	if (!strcmp(optarg, "125K"))
       
   131 		return (int) 125;
       
   132 	if (!strcmp(optarg, "100K"))
       
   133 		return (int) 100;
       
   134 	if (!strcmp(optarg, "50K"))
       
   135 		return (int) 50;
       
   136 	if (!strcmp(optarg, "20K"))
       
   137 		return (int) 20;
       
   138 	if (!strcmp(optarg, "10K"))
       
   139 		return (int) 10;
       
   140 	if (!strcmp(optarg, "5K"))
       
   141 		return (int) 5;
       
   142 	if (!strcmp(optarg, "none"))
       
   143 		return 0;
       
   144 	return 0x0000;
       
   145 }
       
   146 
       
   147 UNS8 canChangeBaudRate_driver(CAN_HANDLE fd0, char *baud)
       
   148 {
       
   149 	printf("Faked changing to baud rate %s[%d]\n", 
       
   150 			baud, TranslateBaudRate(baud));
       
   151 	return 0;
       
   152 }
       
   153 
       
   154 /***************************************************************************/
       
   155 CAN_HANDLE canOpen_driver(s_BOARD * board)
       
   156 {
       
   157 	int rv;
       
   158 
       
   159 	CANPort *p;
       
   160 
       
   161 	p = (CANPort *)calloc(1, sizeof(CANPort));
       
   162 	
       
   163 	if (p == NULL) {
       
   164 		fprintf(stderr, "calloc: %s\n", strerror(errno));
       
   165 		return (CAN_HANDLE) NULL;
       
   166 	}
       
   167 
       
   168 	p->fd = open(board->busname, O_RDWR);
       
   169 	
       
   170 	if (p->fd < 0) {
       
   171 		fprintf(stderr, "open: %s, %s\n", 
       
   172 				board->busname, strerror(errno));
       
   173 		free(p);
       
   174 		return (CAN_HANDLE) NULL;
       
   175 	}
       
   176 
       
   177 	if (tcgetattr(p->fd, &p->old_termio) != 0) {
       
   178 		fprintf(stderr, "tcgetattr: %s, %s\n", 
       
   179 				board->busname, strerror(errno));
       
   180 		close(p->fd);
       
   181 		free(p);
       
   182 		return (CAN_HANDLE) NULL;
       
   183 	}
       
   184 
       
   185 	memcpy(&p->new_termio, &p->old_termio, 
       
   186 					sizeof(p->old_termio));
       
   187 	cfmakeraw(&p->new_termio);
       
   188 	cfsetispeed(&p->new_termio, B115200);
       
   189 	cfsetospeed(&p->new_termio, B115200);
       
   190 	tcsetattr(p->fd, TCSANOW, &p->new_termio);
       
   191 
       
   192 	return (CAN_HANDLE) p;
       
   193 }
       
   194 
       
   195 /***************************************************************************/
       
   196 int canClose_driver(CAN_HANDLE fd0)
       
   197 {
       
   198 	if ((CANPort *) fd0 && ((CANPort *) fd0)->fd >= 0) {
       
   199 		tcsetattr(((CANPort *) fd0)->fd, TCSANOW, 
       
   200 					&((CANPort *) fd0)->old_termio);
       
   201 		close(((CANPort *) fd0)->fd);
       
   202 		free((CANPort *) fd0);
       
   203 	}
       
   204 
       
   205 	return 0;
       
   206 }
       
   207 
       
   208 int canfd_driver(CAN_HANDLE fd0)
       
   209 {
       
   210 	if ((CANPort *) fd0) {
       
   211 		return ((CANPort *) fd0)->fd;
       
   212 	}
       
   213 
       
   214 	return -1;
       
   215 }
       
   216