drivers/can_lincan/can_lincan.c
changeset 26 8340a591acf3
child 145 e747d2e26af0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_lincan/can_lincan.c	Tue May 30 23:13:59 2006 +0200
@@ -0,0 +1,176 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stddef.h> /* for NULL */
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "canmsg.h"
+#include "lincan.h"
+
+struct CANPort;
+#define CAN_HANDLE struct CANPort *
+
+#include <applicfg.h>
+
+#include "timer.h"
+#include "can_driver.h"
+#include "timers_driver.h"
+
+typedef struct CANPort {
+  char used;
+  HANDLE fd;
+  TASK_HANDLE receiveTask;
+  CO_Data* d;
+} CANPort;
+
+/*********functions which permit to communicate with the board****************/
+UNS8 canReceive(CAN_HANDLE fd0, Message *m)
+{
+  int res;
+  struct canmsg_t canmsg;
+
+  canmsg.flags = 0; /* Ensure standard receive, not required for LinCAN>=0.3.1 */
+
+  do{
+    res = read(fd0->fd,&canmsg,sizeof(canmsg_t));
+    if((res<0)&&(errno == -EAGAIN)) res = 0;
+  }while(res==0);
+
+  if(res != sizeof(canmsg_t)) // No new message
+    return 1;
+
+  if(canmsg.flags&MSG_EXT){
+    /* There is no mark for extended messages in CanFestival */;
+  }
+
+  m->cob_id.w = canmsg.id;
+  m->len = canmsg.length;
+  if(canmsg.flags&MSG_RTR){
+    m->rtr = 1;
+  }else{
+    m->rtr = 0;
+    memcpy(m->data,canmsg.data,8);
+  }
+
+  return 0;
+}
+
+void canReceiveLoop(CAN_HANDLE fd0)
+{
+	CO_Data* d = fd0->d;
+	Message m;
+	while (fd0->used) {
+		if(!canReceive(fd0, &m))
+		{
+			EnterMutex();
+			canDispatch(d, &m);
+			LeaveMutex();
+		}else{
+			printf("canReceive returned error\n");
+			break;
+		}
+	}
+}
+
+/***************************************************************************/
+UNS8 canSend(CAN_HANDLE fd0, Message *m)
+{
+  int res;
+  struct canmsg_t canmsg;
+
+
+  canmsg.flags = 0;
+  canmsg.id = m->cob_id.w;
+  canmsg.length = m->len;
+  if(m->rtr){
+    canmsg.flags |= MSG_RTR;
+  }else{
+    memcpy(canmsg.data,m->data,8);
+  }
+
+  if(canmsg.id >= 0x800){
+    canmsg.flags |= MSG_EXT;
+  }
+
+  res = write(fd0->fd,&canmsg,sizeof(canmsg_t));
+  if(res!=sizeof(canmsg_t))
+    return 1;
+
+  return 0;
+}
+
+/***************************************************************************/
+static const char lnx_can_dev_prefix[] = "/dev/can";
+
+CAN_HANDLE canOpen(s_BOARD *board)
+{
+  int name_len = strlen(board->busname);
+  int prefix_len = strlen(lnx_can_dev_prefix);
+  char dev_name[prefix_len+name_len+1];
+  int o_flags = 0;
+  CAN_HANDLE fd0;
+
+  fd0=malloc(sizeof(*fd0));
+  if(fd0==NULL)
+    return NULL;
+
+  /*o_flags = O_NONBLOCK;*/
+
+  memcpy(dev_name,lnx_can_dev_prefix,prefix_len);
+  memcpy(dev_name+prefix_len,board->busname,name_len);
+  dev_name[prefix_len+name_len] = 0;
+
+  fd0->fd = open(dev_name, O_RDWR|o_flags);
+  if(fd0->fd < 0){
+    fprintf(stderr,"!!! Board %s is unknown. See can_lincan.c\n", board->busname);
+    goto error_ret;
+  }
+
+  fd0->d = board->d;
+  fd0->used = 1;
+  CreateReceiveTask(fd0, &fd0->receiveTask);
+  return fd0;
+
+ error_ret:
+  free(fd0);
+  return NULL;
+}
+
+/***************************************************************************/
+int canClose(CAN_HANDLE fd0)
+{
+  if(!fd0)
+    return 0;
+  fd0->used = 0;
+  WaitReceiveTaskEnd(&fd0->receiveTask);
+  close(fd0->fd);
+  free(fd0);
+  return 0;
+}