# HG changeset patch # User ppavel # Date 1149023639 -7200 # Node ID 8340a591acf3901d0343747957ae4c72267f169d # Parent 3b40e2100d96a4f3c6fc2f1d041d44ba6af4262e Included interfacing code for LinCAN driver. The driver is selected at configure time by ./configure --can=lincan diff -r 3b40e2100d96 -r 8340a591acf3 drivers/can_lincan/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_lincan/Makefile.in Tue May 30 23:13:59 2006 +0200 @@ -0,0 +1,58 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# 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 +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET +CAN_DRIVER = SUB_CAN_DRIVER +TIMERS_DRIVER = SUB_TIMERS_DRIVER + +INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER) + +OBJS = $(CAN_DRIVER).o + +SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h + +TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h + +all: driver + +driver: $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: + mkdir -p $(PREFIX)/include/canfestival + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(TARGET_HFILES) + +clean: + -\rm $(OBJS) + +mrproper: clean diff -r 3b40e2100d96 -r 8340a591acf3 drivers/can_lincan/can_lincan.c --- /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 +#include +#include +#include +#include /* for NULL */ +#include +#include +#include +#include +#include + +#include "canmsg.h" +#include "lincan.h" + +struct CANPort; +#define CAN_HANDLE struct CANPort * + +#include + +#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; +} diff -r 3b40e2100d96 -r 8340a591acf3 include/can_lincan/cancfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can_lincan/cancfg.h Tue May 30 23:13:59 2006 +0200 @@ -0,0 +1,31 @@ +/* +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 +*/ + +#ifndef __CANCFG_H__ +#define __CANCFG_H__ + +#define HANDLE int +#ifndef CAN_HANDLE +#define CAN_HANDLE void* +#endif /*CAN_HANDLE*/ + +#endif diff -r 3b40e2100d96 -r 8340a591acf3 include/can_lincan/canmsg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can_lincan/canmsg.h Tue May 30 23:13:59 2006 +0200 @@ -0,0 +1,136 @@ +/* canmsg.h - common kernel-space and user-space CAN message structure + * Linux CAN-bus device driver. + * Written by Pavel Pisa - OCERA team member + * email:pisa@cmp.felk.cvut.cz + * This software is released under the GPL-License. + * Version lincan-0.3 17 Jun 2004 + */ + +#ifndef _CANMSG_T_H +#define _CANMSG_T_H + +#ifdef __KERNEL__ + +#include +#include + +#else /* __KERNEL__ */ + +#include +#include + +#endif /* __KERNEL__ */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * CAN_MSG_VERSION_2 enables new canmsg_t layout compatible with + * can4linux project from http://www.port.de/ + * + */ +#define CAN_MSG_VERSION_2 + +/* Number of data bytes in one CAN message */ +#define CAN_MSG_LENGTH 8 + +#ifdef CAN_MSG_VERSION_2 + +typedef struct timeval canmsg_tstamp_t ; + +typedef unsigned long canmsg_id_t; + +/** + * struct canmsg_t - structure representing CAN message + * @flags: message flags + * %MSG_RTR .. message is Remote Transmission Request, + * %MSG_EXT .. message with extended ID, + * %MSG_OVR .. indication of queue overflow condition, + * %MSG_LOCAL .. message originates from this node. + * @cob: communication object number (not used) + * @id: ID of CAN message + * @timestamp: not used + * @length: length of used data + * @data: data bytes buffer + * + * Header: canmsg.h + */ +struct canmsg_t { + int flags; + int cob; + canmsg_id_t id; + canmsg_tstamp_t timestamp; + unsigned short length; + unsigned char data[CAN_MSG_LENGTH]; +}; + +#else /*CAN_MSG_VERSION_2*/ +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif +/* Old, deprecated version of canmsg_t structure */ +struct canmsg_t { + short flags; + int cob; + canmsg_id_t id; + unsigned long timestamp; + unsigned int length; + unsigned char data[CAN_MSG_LENGTH]; +} PACKED; +#endif /*CAN_MSG_VERSION_2*/ + +typedef struct canmsg_t canmsg_t; + +/** + * struct canfilt_t - structure for acceptance filter setup + * @flags: message flags + * %MSG_RTR .. message is Remote Transmission Request, + * %MSG_EXT .. message with extended ID, + * %MSG_OVR .. indication of queue overflow condition, + * %MSG_LOCAL .. message originates from this node. + * there are corresponding mask bits + * %MSG_RTR_MASK, %MSG_EXT_MASK, %MSG_LOCAL_MASK. + * %MSG_PROCESSLOCAL enables local messages processing in the + * combination with global setting + * @queid: CAN queue identification in the case of the multiple + * queues per one user (open instance) + * @cob: communication object number (not used) + * @id: selected required value of cared ID id bits + * @mask: select bits significand for the comparation; + * 1 .. take care about corresponding ID bit, 0 .. don't care + * + * Header: canmsg.h + */ +struct canfilt_t { + int flags; + int queid; + int cob; + canmsg_id_t id; + canmsg_id_t mask; +}; + +typedef struct canfilt_t canfilt_t; + +/* Definitions to use for canmsg_t and canfilt_t flags */ +#define MSG_RTR (1<<0) +#define MSG_OVR (1<<1) +#define MSG_EXT (1<<2) +#define MSG_LOCAL (1<<3) +/* If you change above lines, check canque_filtid2internal function */ + +/* Additional definitions used for canfilt_t only */ +#define MSG_FILT_MASK_SHIFT 8 +#define MSG_RTR_MASK (MSG_RTR< +#include +#include + +#else /* __KERNEL__ */ + +#include +#include +#include + +#endif /* __KERNEL__ */ + +#include "./canmsg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* CAN ioctl magic number */ +#define CAN_IOC_MAGIC 'd' + +typedef unsigned long bittiming_t; +typedef unsigned short channel_t; + +/** + * struct can_baudparams_t - datatype for calling CONF_BAUDPARAMS IOCTL + * @flags: reserved for additional flags for chip configuration, should be written -1 or 0 + * @baudrate: baud rate in Hz + * @sjw: synchronization jump width (0-3) prescaled clock cycles + * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio + * + * The structure is used to configure new set of parameters into CAN controller chip. + * If default value of some field should be preserved, fill field by value -1. + */ +struct can_baudparams_t { + long flags; + long baudrate; + long sjw; + long sample_pt; +}; + +/* CAN ioctl functions */ +#define CAN_DRV_QUERY _IO(CAN_IOC_MAGIC, 0) +#define CAN_DRV_QRY_BRANCH 0 /* returns driver branch value - "LINC" for LinCAN driver */ +#define CAN_DRV_QRY_VERSION 1 /* returns driver version as (major<<16) | (minor<<8) | patch */ +#define CAN_DRV_QRY_MSGFORMAT 2 /* format of canmsg_t structure */ + +#define CMD_START _IOW(CAN_IOC_MAGIC, 1, channel_t) +#define CMD_STOP _IOW(CAN_IOC_MAGIC, 2, channel_t) +//#define CMD_RESET 3 + +#define CONF_BAUD _IOW(CAN_IOC_MAGIC, 4, bittiming_t) +//#define CONF_ACCM +//#define CONF_XTDACCM +//#define CONF_TIMING +//#define CONF_OMODE +#define CONF_FILTER _IOW(CAN_IOC_MAGIC, 8, unsigned char) + +//#define CONF_FENABLE +//#define CONF_FDISABLE + +#define STAT _IO(CAN_IOC_MAGIC, 9) +#define CANQUE_FILTER _IOW(CAN_IOC_MAGIC, 10, struct canfilt_t) +#define CANQUE_FLUSH _IO(CAN_IOC_MAGIC, 11) +#define CONF_BAUDPARAMS _IOW(CAN_IOC_MAGIC, 11, struct can_baudparams_t) +#define CANRTR_READ _IOWR(CAN_IOC_MAGIC, 12, struct canmsg_t) + +#ifdef __cplusplus +} /* extern "C"*/ +#endif + +#endif /*_CAN_DRVAPI_T_H*/