groke6@364: /*
groke6@364: This file is part of CanFestival, a library implementing CanOpen Stack.
groke6@364: 
groke6@364: Copyright (C): Jorge BERZOSA
groke6@364: 
groke6@364: See COPYING file for copyrights details.
groke6@364: 
groke6@364: This library is free software; you can redistribute it and/or
groke6@364: modify it under the terms of the GNU Lesser General Public
groke6@364: License as published by the Free Software Foundation; either
groke6@364: version 2.1 of the License, or (at your option) any later version.
groke6@364: 
groke6@364: This library is distributed in the hope that it will be useful,
groke6@364: but WITHOUT ANY WARRANTY; without even the implied warranty of
groke6@364: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
groke6@364: Lesser General Public License for more details.
groke6@364: 
groke6@364: You should have received a copy of the GNU Lesser General Public
groke6@364: License along with this library; if not, write to the Free Software
groke6@364: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
groke6@364: */
groke6@364: 
groke6@364: /*
groke6@364: * can4linux driver
groke6@364: */
groke6@364: 
groke6@364: #include <stdio.h>
groke6@364: #include <string.h>
groke6@364: #include <errno.h>
groke6@364: #include <fcntl.h>
groke6@364: 
groke6@364: #include "can4linux.h" 
groke6@364: #include "can_driver.h"
groke6@364: 
groke6@384: //struct timeval init_time,current_time;
groke6@364: 
groke6@364: /*********functions which permit to communicate with the board****************/
groke6@364: UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
groke6@364: {
groke6@364:   int res,i;
groke6@364:   canmsg_t canmsg;
groke6@384:   //long int time_period;
groke6@364: 
groke6@364: 	canmsg.flags = 0; 
groke6@364: 	do{
groke6@364:    		res = read(fd0,&canmsg,1);
groke6@364:    		if((res<0)&&(errno == -EAGAIN)) res = 0;
groke6@364: 	}while(res==0);
groke6@364: 
groke6@364: 	if(res !=1) // No new message
groke6@364:    	return 1;
groke6@364: 
groke6@364: 	if(canmsg.flags&MSG_EXT){
groke6@364:    		/* There is no mark for extended messages in CanFestival */;
groke6@364: 	}
groke6@364:   		
etisserant@365: 	m->cob_id = canmsg.id;
groke6@364: 	m->len = canmsg.length;
groke6@364: 	if(canmsg.flags&MSG_RTR){
groke6@364:  		m->rtr = 1;
groke6@364: 	}else{
groke6@364:  		m->rtr = 0;
groke6@364:  		memcpy(m->data,canmsg.data,8);
groke6@364: 	}
groke6@364: 	
groke6@364: 	
groke6@364:  	/*gettimeofday(&current_time,NULL);
groke6@364:  	time_period=(current_time.tv_sec - init_time.tv_sec)* 1000000 + current_time.tv_usec - init_time.tv_usec;
etisserant@365:  	printf("%3ld.%3ld.%3ld - Receive ID: %lx ->",time_period/1000000,(time_period%1000000)/1000,time_period%1000,m->cob_id);
etisserant@365:  	printf("Receive ID: %lx ->",m->cob_id);
groke6@364:  	for(i=0; i<canmsg.length;i++)printf("%x, ", m->data[i]);
groke6@364:  	printf("\n");*/
groke6@364:  
groke6@364:   return 0;
groke6@364: }
groke6@364: 
groke6@364: /***************************************************************************/
groke6@364: UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
groke6@364: {
groke6@364:   int res;
groke6@364:   canmsg_t canmsg;
groke6@364: 
groke6@364:   canmsg.flags = 0;
etisserant@365:   canmsg.id = m->cob_id;
groke6@364:   canmsg.length = m->len;
groke6@364:   if(m->rtr){
groke6@364:     canmsg.flags |= MSG_RTR;
groke6@364:   }else{
groke6@364:     memcpy(canmsg.data,m->data,8);
groke6@364:   }
groke6@364:   
groke6@364:  /*printf("Send ID: %lx ->",canmsg.id); 
groke6@364:  for(i=0; i<canmsg.length;i++)printf("%x, ", canmsg.data[i]);
groke6@364:  printf("\n");*/
groke6@364: 
groke6@364:   if(canmsg.id >= 0x800){
groke6@364:     canmsg.flags |= MSG_EXT;
groke6@364:   }
groke6@364: 
groke6@364:   res = write(fd0,&canmsg,1);
groke6@364:   if(res!=1)
groke6@364:     return 1;
groke6@364: 
groke6@364:   return 0;
groke6@364: }
groke6@364: 
groke6@364: 
groke6@364: /***************************************************************************/
groke6@384: int TranslateBaudRate(char* optarg){
groke6@364: 	if(!strcmp( optarg, "1M")) return (int)1000;
groke6@364: 	if(!strcmp( optarg, "500K")) return (int)500;
groke6@364: 	if(!strcmp( optarg, "250K")) return (int)250;
groke6@364: 	if(!strcmp( optarg, "125K")) return (int)125;
groke6@364: 	if(!strcmp( optarg, "100K")) return (int)100;
groke6@364: 	if(!strcmp( optarg, "50K")) return (int)50;
groke6@364: 	if(!strcmp( optarg, "20K")) return (int)20;
groke6@364: 	if(!strcmp( optarg, "10K")) return (int)10;
groke6@364: 	if(!strcmp( optarg, "5K")) return (int)5;
groke6@384: 	return 0;
groke6@384: }
groke6@384: 
groke6@384: UNS8 _canChangeBaudRate( CAN_HANDLE fd, int baud)
groke6@384: {
groke6@384:     Config_par_t  cfg;	
groke6@384:     volatile Command_par_t cmd;
groke6@384:     
groke6@384:     cmd.cmd = CMD_STOP;
groke6@384:     ioctl(fd, COMMAND, &cmd);
groke6@384: 
groke6@384: 	cfg.target = CONF_TIMING; 
groke6@384:     cfg.val1  = baud;
groke6@384:     ioctl(fd, CONFIG, &cfg);
groke6@384: 
groke6@384:     cmd.cmd = CMD_START;
groke6@384:     ioctl(fd, COMMAND, &cmd);
groke6@384:     
groke6@384:     return 0;
groke6@384: }
groke6@384: 
groke6@384: UNS8 canChangeBaudRate_driver( CAN_HANDLE fd, char* baud)
groke6@384: {
groke6@384:     int temp=TranslateBaudRate(baud);
groke6@384: 
groke6@384:     if(temp==0)return 1;
groke6@384:     _canChangeBaudRate(fd, temp);
groke6@384:     printf("Baudrate changed to=>%s\n", baud);
groke6@384:     return 0;
groke6@364: }
groke6@364: 
groke6@364: /***************************************************************************/
groke6@364: static const char lnx_can_dev_prefix[] = "/dev/can";
groke6@364: 
groke6@364: CAN_HANDLE canOpen_driver(s_BOARD *board)
groke6@364: {
groke6@364:   int name_len = strlen(board->busname);
groke6@364:   int prefix_len = strlen(lnx_can_dev_prefix);
groke6@364:   char dev_name[prefix_len+name_len+1];
groke6@364:   int o_flags = 0;
groke6@384:   //int baud = TranslateBaudeRate(board->baudrate);
groke6@364:   int fd0;
groke6@384:   int res;
groke6@364: 
groke6@364:   
groke6@364:   /*o_flags = O_NONBLOCK;*/
groke6@364: 
groke6@364:   memcpy(dev_name,lnx_can_dev_prefix,prefix_len);
groke6@364:   memcpy(dev_name+prefix_len,board->busname,name_len);
groke6@364:   dev_name[prefix_len+name_len] = 0;
groke6@364: 
groke6@364:   fd0 = open(dev_name, O_RDWR|o_flags);
etisserant@471:   if(fd0 == -1){
groke6@364:     fprintf(stderr,"!!! %s is unknown. See can4linux.c\n", dev_name);
groke6@364:     goto error_ret;
groke6@364:   }
groke6@364:   
groke6@384:   res=TranslateBaudRate(board->baudrate);
groke6@384:   if(res == 0){
groke6@384:     fprintf(stderr,"!!! %s baudrate not supported. See can4linux.c\n", board->baudrate);
groke6@384:     goto error_ret;
groke6@384:   }
groke6@384: 	
groke6@384:   _canChangeBaudRate( (CAN_HANDLE)fd0, res);
groke6@364: 
groke6@364:   printf("CAN device dev/can%s opened. Baudrate=>%s\n",board->busname, board->baudrate);
groke6@364: 
groke6@364:   return (CAN_HANDLE)fd0;
groke6@364: 
groke6@364:  error_ret:
groke6@364:   return NULL;
groke6@364: }
groke6@364: 
groke6@364: /***************************************************************************/
groke6@364: int canClose_driver(CAN_HANDLE fd0)
groke6@364: {
etisserant@471:   if((int)fd0 != -1) {
etisserant@471:       return close((int)fd0);
etisserant@471:   }
etisserant@471: 
etisserant@471:   return -1;
etisserant@471: }
etisserant@471: 
etisserant@471: int canfd_driver(CAN_HANDLE fd0)
etisserant@471: {
etisserant@471:         return ((int)fd0);
etisserant@471: }
etisserant@471: 
etisserant@471: