nico@215: nico@215:
nico@215:00001 /* nico@215: 00002 This file is part of CanFestival, a library implementing CanOpen Stack. nico@215: 00003 nico@215: 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN nico@215: 00005 nico@215: 00006 See COPYING file for copyrights details. nico@215: 00007 nico@215: 00008 This library is free software; you can redistribute it and/or nico@215: 00009 modify it under the terms of the GNU Lesser General Public nico@215: 00010 License as published by the Free Software Foundation; either nico@215: 00011 version 2.1 of the License, or (at your option) any later version. nico@215: 00012 nico@215: 00013 This library is distributed in the hope that it will be useful, nico@215: 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of nico@215: 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU nico@215: 00016 Lesser General Public License for more details. nico@215: 00017 nico@215: 00018 You should have received a copy of the GNU Lesser General Public nico@215: 00019 License along with this library; if not, write to the Free Software nico@215: 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA nico@215: 00021 */ nico@215: 00022 nico@215: 00023 #include <stdio.h> nico@215: 00024 #include <string.h> nico@215: 00025 #include <errno.h> nico@215: 00026 #include <fcntl.h> nico@215: 00027 nico@215: 00028 #include "canmsg.h" nico@215: 00029 #include "lincan.h" nico@215: 00030 nico@215: 00031 #include "can_driver.h" nico@215: 00032 nico@215: 00033 /*********functions which permit to communicate with the board****************/ etisserant@240: 00034 UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m) nico@215: 00035 { nico@215: 00036 int res; nico@215: 00037 struct canmsg_t canmsg; nico@215: 00038 etisserant@240: 00039 canmsg.flags = 0; /* Ensure standard receive, not required for LinCAN>=0.3.1 */ nico@215: 00040 nico@215: 00041 do{ nico@215: 00042 res = read(fd0,&canmsg,sizeof(canmsg_t)); nico@215: 00043 if((res<0)&&(errno == -EAGAIN)) res = 0; nico@215: 00044 }while(res==0); nico@215: 00045 nico@215: 00046 if(res != sizeof(canmsg_t)) // No new message nico@215: 00047 return 1; nico@215: 00048 etisserant@240: 00049 if(canmsg.flags&MSG_EXT){ nico@215: 00050 /* There is no mark for extended messages in CanFestival */; nico@215: 00051 } nico@215: 00052 etisserant@240: 00053 m->cob_id.w = canmsg.id; etisserant@240: 00054 m->len = canmsg.length; etisserant@240: 00055 if(canmsg.flags&MSG_RTR){ etisserant@240: 00056 m->rtr = 1; nico@215: 00057 }else{ etisserant@240: 00058 m->rtr = 0; etisserant@240: 00059 memcpy(m->data,canmsg.data,8); nico@215: 00060 } nico@215: 00061 nico@215: 00062 return 0; nico@215: 00063 } nico@215: 00064 nico@215: 00065 /***************************************************************************/ etisserant@240: 00066 UNS8 canSend_driver(CAN_HANDLE fd0, Message *m) nico@215: 00067 { nico@215: 00068 int res; nico@215: 00069 struct canmsg_t canmsg; nico@215: 00070 nico@215: 00071 etisserant@240: 00072 canmsg.flags = 0; etisserant@240: 00073 canmsg.id = m->cob_id.w; etisserant@240: 00074 canmsg.length = m->len; etisserant@240: 00075 if(m->rtr){ etisserant@240: 00076 canmsg.flags |= MSG_RTR; nico@215: 00077 }else{ etisserant@240: 00078 memcpy(canmsg.data,m->data,8); nico@215: 00079 } nico@215: 00080 etisserant@240: 00081 if(canmsg.id >= 0x800){ etisserant@240: 00082 canmsg.flags |= MSG_EXT; nico@215: 00083 } nico@215: 00084 nico@215: 00085 res = write(fd0,&canmsg,sizeof(canmsg_t)); nico@215: 00086 if(res!=sizeof(canmsg_t)) nico@215: 00087 return 1; nico@215: 00088 nico@215: 00089 return 0; nico@215: 00090 } nico@215: 00091 nico@215: 00092 /***************************************************************************/ nico@215: 00093 static const char lnx_can_dev_prefix[] = "/dev/can"; nico@215: 00094 etisserant@240: 00095 CAN_HANDLE canOpen_driver(s_BOARD *board) nico@215: 00096 { etisserant@240: 00097 int name_len = strlen(board->busname); nico@215: 00098 int prefix_len = strlen(lnx_can_dev_prefix); nico@215: 00099 char dev_name[prefix_len+name_len+1]; nico@215: 00100 int o_flags = 0; etisserant@240: 00101 CAN_HANDLE fd0; nico@215: 00102 nico@215: 00103 fd0=malloc(sizeof(*fd0)); nico@215: 00104 if(fd0==NULL) nico@215: 00105 return NULL; nico@215: 00106 nico@215: 00107 /*o_flags = O_NONBLOCK;*/ nico@215: 00108 nico@215: 00109 memcpy(dev_name,lnx_can_dev_prefix,prefix_len); etisserant@240: 00110 memcpy(dev_name+prefix_len,board->busname,name_len); nico@215: 00111 dev_name[prefix_len+name_len] = 0; nico@215: 00112 nico@215: 00113 fd0 = open(dev_name, O_RDWR|o_flags); nico@215: 00114 if(fd0 < 0){ etisserant@240: 00115 fprintf(stderr,"!!! Board %s is unknown. See can_lincan.c\n", board->busname); nico@215: 00116 goto error_ret; nico@215: 00117 } nico@215: 00118 nico@215: 00119 return fd0; nico@215: 00120 nico@215: 00121 error_ret: nico@215: 00122 free(fd0); nico@215: 00123 return NULL; nico@215: 00124 } nico@215: 00125 nico@215: 00126 /***************************************************************************/ etisserant@240: 00127 int canClose_driver(CAN_HANDLE fd0) nico@215: 00128 { nico@215: 00129 if(!fd0) nico@215: 00130 return 0; nico@215: 00131 close(fd0); nico@215: 00132 return 0; nico@215: 00133 } etisserant@240: