# HG changeset patch # User etisserant # Date 1203351262 -3600 # Node ID 7d845f5d730cc0051f06b13e53658e89e2451656 # Parent 8d22c323fe0fd7b588ea657194eb7ec371b70152 Added Kvaser hardware support, thanks to Giuseppe Massimo Bertani . diff -r 8d22c323fe0f -r 7d845f5d730c configure --- a/configure Mon Feb 18 14:12:19 2008 +0100 +++ b/configure Mon Feb 18 17:14:22 2008 +0100 @@ -257,7 +257,7 @@ ########################################################################### # DEFAULT TARGET/DRIVERS GUESSING # ########################################################################### -# If target not specified, try to gess one +# If target not specified, try to guess one if [ "$SUB_TARGET" = "" ]; then if [ "$SUB_OS_NAME" = "CYGWIN" ]; then echo "Choosing unix (cygwin) target" @@ -273,7 +273,7 @@ fi fi -# Try to gess can +# Try to guess can if [ "$SUB_CAN_DRIVER" = "" ]; then if [ "$SUB_TARGET" = "unix" ]; then if [ -e /usr/lib/libpcan.so ]; then @@ -282,6 +282,12 @@ elif [ "$SUB_OS_NAME" = "CYGWIN" -a "PCAN_LIB" != "" ]; then echo "Choosing installed Peak driver as CAN driver." SUB_CAN_DRIVER=peak_win32 + elif [ -e /usr/lib/libcanlib.so ]; then + echo "Choosing installed Kvaser driver as CAN driver. (unix)" + SUB_CAN_DRIVER=kvaser + elif [ "$SUB_OS_NAME" = "CYGWIN" -a "$KVASER_DLL_PATH" != "" ]; then + echo "Choosing installed Kvaser driver as CAN driver. (cygwin)" + SUB_CAN_DRIVER=kvaser else echo "Choosing virtual CAN driver." SUB_CAN_DRIVER=virtual @@ -309,6 +315,21 @@ fi fi +# Warn for unstalled kvaser driver if choosen +if [ "$SUB_CAN_DRIVER" = "kvaser" ]; then + if [ "$SUB_OS_NAME" = "CYGWIN" ]; then + if [ ! -e "$KVASER_DLL_PATH/canlib32.dll" ]; then + echo "Kvaser driver hasn't been installed (cygwin)" + exit -1 + fi + elif [ "$SUB_OS_NAME" = "LINUX" ]; then + if [ ! -e /usr/lib/libcanlib.so ]; then + echo "Kvaser driver hasn't been installed (unix)" + exit -1 + fi + fi +fi + ########################################################################### # TARGET/DRIVER SPECIFIC CFLAGS and OPTIONS # ########################################################################### @@ -336,13 +357,28 @@ #### CAN_DRIVER #### +if [ "$SUB_CAN_DRIVER" = "kvaser" ]; then + if [ "$SUB_TARGET" = "unix" ]; then + if [ "$SUB_OS_NAME" = "LINUX" ]; then + SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ -lcanlib + elif [ "$SUB_OS_NAME" = "CYGWIN" ]; then + if [ "$KVASER_INCLUDE_PATH" = "" -o "$KVASER_DLL_PATH" = "" ]; then + echo "!!! ERROR !!! Please set KVASER_DLL_PATH and KVASER_INCLUDE_PATH to appropriate paths ! " + else + SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ -L$KVASER_DLL_PATH\ -lcanlib32 + SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -I$KVASER_INCLUDE_PATH + fi + fi + fi +fi + if [ "$SUB_CAN_DRIVER" = "peak_linux" ]; then SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ -lpcan fi PW32DIR=drivers/can_peak_win32 if [ "$SUB_CAN_DRIVER" = "peak_win32" ]; then - if [ "$PCAN_HEADER" = "" -o "PCAN_LIB" = "" ]; then + if [ "$PCAN_HEADER" = "" -o "$PCAN_LIB" = "" ]; then echo "!!! ERROR !!! Please set PCAN_LIB PCAN_HEADER [PCAN_INCLUDE] to appropriate paths ! " fi SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ -liberty\ \'$PCAN_LIB\' @@ -693,6 +729,7 @@ MAKEFILES=$MAKEFILES\ \ examples/TestMasterSlave/Makefile.in\ \ examples/TestMasterSlaveLSS/Makefile.in\ +\ examples/SillySlave/Makefile.in\ \ examples/TestMasterMicroMod/Makefile.in fi @@ -700,6 +737,7 @@ MAKEFILES=$MAKEFILES\ \ examples/TestMasterSlave/Makefile.in\ \ examples/TestMasterSlaveLSS/Makefile.in\ +\ examples/SillySlave/Makefile.in\ \ examples/TestMasterMicroMod/Makefile.in fi diff -r 8d22c323fe0f -r 7d845f5d730c drivers/can_kvaser/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_kvaser/Makefile.in Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,77 @@ +#! gmake + +# +# Copyright (C) 2006 Giuseppe Massimo Bertani and 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 +ENABLE_DLL_DRIVERS = SUB_ENABLE_DLL_DRIVERS +CAN_DLL_CFLAGS = SUB_CAN_DLL_CFLAGS +OS_NAME = SUB_OS_NAME + +INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) + +OBJS = $(CAN_DRIVER).o + +#GMB: must detect if we are under cygwin (produces a DLL driver) +#or under a real unix machine (produces a .so driver) +ifeq ($(ENABLE_DLL_DRIVERS),1) + ifeq ($(OS_NAME),CYGWIN) + DRIVER = libcanfestival_$(CAN_DRIVER).dll + else + ifeq ($(TARGET),unix) + CFLAGS += -fPIC + DRIVER = libcanfestival_$(CAN_DRIVER).so + endif + endif +else +DRIVER = $(OBJS) +endif + +TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER) + +all: driver + +driver: $(DRIVER) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +$(DRIVER): $(OBJS) + $(CC) -shared -Wl,-soname,$(DRIVER) $(CAN_DLL_CFLAGS) -o $@ $< + +install: $(DRIVER) + mkdir -p $(PREFIX)/lib/ + cp $< $(PREFIX)/lib/ + +uninstall: + rm -f $(TARGET_SOFILES) + +clean: + rm -f $(OBJS) + +mrproper: clean diff -r 8d22c323fe0f -r 7d845f5d730c drivers/can_kvaser/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_kvaser/README Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,31 @@ +Kvaser driver for CANfestival, the open source CANopen stack. +(C)2008 Giuseppe Massimo Bertani + + +This driver should work with any Kvaser product compatible with Kvaser's CANLIB4. +I tested it with CAN Leaf Professional (USB-CAN adapter) on a Suse10.1 Linux box +and CANLIB 4.72 Beta (Oct 1,2007). + +In order to compile the driver, you should already be able to run the CANlib examples, +and tools, to be sure that CANLIB is able to detect and drive your device. + +------------------------------------------------------------------------------------------------- +NOTES ABOUT CANLIB4 + +Since the "Leaf" device was added recently to CANLIB, I had to download the latest linuxcan4 +library sources from http://www.kvaser.com instead of use the CD software shipped with the device. + +-------------------------------------------------------------------------------------------------- +NOTES ABOUT WINDOWS + +Sadly, Kvaser's Win32 CANLIB is not provided with sources, so CANLIB cannot be build with GNU +tools. LIB files for MSVC and BCC are provided with the DLL but the DLL itself is stripped and +I've tried an entire day to compile this driver under Cygwin without success, despite +Wu Yongwei's hints (http://www.geocities.com/yongweiwu/dllfaq.htm). + +This does not mean that it's an impossible task, but probably I left out something important. +Temporary KO. + +------------------------------------------------------------------------------------------------- + +GMB 23/1/08 diff -r 8d22c323fe0f -r 7d845f5d730c drivers/can_kvaser/can_kvaser.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_kvaser/can_kvaser.c Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,307 @@ + +/* +Copyright (C): Giuseppe Massimo BERTANI +gmbertani@users.sourceforge.net + + +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 +*/ + +/** + * @file can_kvaser.c + * @author GMB + * @date 17/1/08 + * + * This file is needed to interface Kvaser's CAN Leaf (USB-CAN adapter) + * and probably others Kvaser's products compatible with Kvaser's CANLIB, + * to CANfestival open source CANopen stack. + * + * It was tested under Linux 2.6 with "Leaf Professional" and CANLIB 4.72 Beta (Oct 1,2007) +*/ + +#include +#include +#include +#include +#include +#include + +/* includes Kvaser's CANLIB header */ +#include + +#include "can_driver.h" + + +/** + * CAN_HANDLES must have value >=1 while CANLIB wants handles >= 0 + * so fd0 needs to be decremented before use. + * + */ +UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m) +{ +canStatus retval = canOK; +unsigned flags = 0; +unsigned long timeStamp; + + fd0--; + + /* checking for input message (blocking) */ + retval = canReadWait((int)fd0, (long*)&m->cob_id, &m->data, (unsigned*)&m->len, &flags, &timeStamp, -1); + if (retval != canOK) + { + fprintf(stderr, "canReceive_driver (Kvaser) : canReadWait() error, cob_id=%08X, len=%u, flags=%08X, returned value = %d\n", + m->cob_id, m->len, flags, retval); + canClose((int)fd0); + return retval; + } + + m->rtr = 0; + if (flags & canMSG_RTR) + { + m->rtr = 1; + } + + if (flags & canMSG_EXT) + { + /* TODO: is it correct to set this info in cob_id? */ + m->cob_id |= 0x20000000; + } + + //fprintf(stderr, "canReceive_driver (Kvaser) : canReadWait() received packet, cob_id=%08X, len=%u, flags=%08X, timestamp=%d returned value = %d\n", + // m->cob_id, m->len, flags, timeStamp, retval); + + return retval; +} + +/** + * + * CAN_HANDLES must have value >=1 while CANLIB wants handles >= 0 + * so fd0 needs to be decremented before use. + * + */ +UNS8 canSend_driver(CAN_HANDLE fd0, Message *m) +{ +canStatus retval = canOK; +unsigned flags = 0; + + fd0--; + + flags |= canMSG_STD; + + if (m->cob_id & 0x20000000) + { + /* TODO: is it correct to desume this info from cob_id? */ + flags |= canMSG_EXT; + } + + if (m->cob_id & 0x40000000) + { + flags |= canMSG_RTR; + } + + /* + * TODO: when should I set canMSG_ERROR_FRAME? + */ + + retval = canWriteWait((int)fd0, m->cob_id, m->data, m->len, 10000, flags); + if (retval != canOK) + { + fprintf(stderr, "canSend_driver (Kvaser) : canWriteWait() error, cob_id=%08X, len=%u, flags=%08X, returned value = %d\n", + m->cob_id, m->len, flags, retval); + canClose((int)fd0); + return retval; + } + + //fprintf(stderr, "canSend_driver (Kvaser) : canWriteWait() send packet, cob_id=%08X, len=%u, flags=%08X, returned value = %d\n", + // m->cob_id, m->len, flags, retval); + return retval; + +} + + +/** + * + */ +int TranslateBaudRate(char* optarg) +{ + if(!strcmp( optarg, "1M")) + return BAUD_1M; + if(!strcmp( optarg, "500K")) + return BAUD_500K; + if(!strcmp( optarg, "250K")) + return BAUD_250K; + if(!strcmp( optarg, "125K")) + return BAUD_125K; + if(!strcmp( optarg, "100K")) + return BAUD_100K; + if(!strcmp( optarg, "62K")) + return BAUD_62K; + if(!strcmp( optarg, "50K")) + return BAUD_50K; + + return 0; +} + +/** + * Channels and their descriptors are numbered starting from zero. + * So I need to increment by 1 the handle returned by CANLIB because + * CANfestival CAN_HANDLEs with value zero are considered NOT VALID. + * + * The baud rate could be given directly as bit/s + * or using one of the BAUD_* constants defined + * in canlib.h + */ +CAN_HANDLE canOpen_driver(s_BOARD *board) +{ +int fd0 = -1; +int channel, baud; +canStatus retval = canOK; + + fd0--; + + sscanf(board->busname, "%d", &channel); + + baud = TranslateBaudRate(board->baudrate); + + if (baud == 0) + { + sscanf(board->baudrate, "%d", &baud); + } + + fd0 = canOpenChannel(channel, canWANT_EXCLUSIVE|canWANT_EXTENDED); + if (fd0 < 0) + { + fprintf(stderr, "canOpen_driver (Kvaser) : error opening channel %d\n", channel); + return (CAN_HANDLE)(fd0+1); + } + canBusOff(fd0); + + /* values for tseg1, tseg2, sjw, noSamp and syncmode + * come from canlib example "simplewrite.c". The doc + * says that default values will be taken if baud is one of + * the BAUD_* values + */ + retval = canSetBusParams(fd0, baud, 4, 3, 1, 1, 0); + if (retval != canOK) + { + fprintf(stderr, "canOpen_driver (Kvaser) : canSetBusParams() error, returned value = %d, baud=%d, \n", retval, baud); + canClose((int)fd0); + return (CAN_HANDLE)retval; + } + + canSetBusOutputControl(fd0, canDRIVER_NORMAL); + if (retval != canOK) + { + fprintf(stderr, "canOpen_driver (Kvaser) : canSetBusOutputControl() error, returned value = %d\n", retval); + canClose((int)fd0); + return (CAN_HANDLE)retval; + } + + + + + retval = canBusOn(fd0); + if (retval != canOK) + { + fprintf(stderr, "canOpen_driver (Kvaser) : canBusOn() error, returned value = %d\n", retval); + canClose((int)fd0); + return (CAN_HANDLE)retval; + } + + return (CAN_HANDLE)(fd0+1); + +} + +UNS8 canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud) +{ +int baudrate; +canStatus retval = canOK; + + + baudrate = TranslateBaudRate(baud); + if (baudrate == 0) + { + sscanf(baud, "%d", &baudrate); + } + + + fprintf(stderr, "%x-> changing to baud rate %s[%d]\n", (int)fd0, baud, baudrate); + + canBusOff((int)fd0); + + /* values for tseg1, tseg2, sjw, noSamp and syncmode + * come from canlib example "simplewrite.c". The doc + * says that default values will be taken if baud is one of + * the BAUD_* values + */ + retval = canSetBusParams((int)fd0, baudrate, 4, 3, 1, 1, 0); + if (retval != canOK) + { + fprintf(stderr, "canChangeBaudRate_driver (Kvaser) : canSetBusParams() error, returned value = %d, baud=%d, \n", retval, baud); + canClose((int)fd0); + return (UNS8)retval; + } + + canSetBusOutputControl((int)fd0, canDRIVER_NORMAL); + if (retval != canOK) + { + fprintf(stderr, "canChangeBaudRate_driver (Kvaser) : canSetBusOutputControl() error, returned value = %d\n", retval); + canClose((int)fd0); + return (UNS8)retval; + } + + retval = canBusOn((int)fd0); + if (retval != canOK) + { + fprintf(stderr, "canChangeBaudRate_driver (Kvaser) : canBusOn() error, returned value = %d\n", retval); + canClose((int)fd0); + return (UNS8)retval; + } + + return 0; +} + + +/** + * + * CAN_HANDLES must have value >=1 while CANLIB wants handles >= 0 + * so fd0 needs to be decremented before use. + */ +int canClose_driver(CAN_HANDLE fd0) +{ +canStatus retval = canOK; + + fd0--; + + retval = canBusOff((int)fd0); + if (retval != canOK) + { + fprintf(stderr, "canClose_driver (Kvaser) : canBusOff() error, returned value = %d\n", retval); + canClose((int)fd0); + return retval; + } + + retval = canClose((int)fd0); + if (retval != canOK) + { + fprintf(stderr, "canClose_driver (Kvaser) : canClose() error, returned value = %d\n", retval); + return retval; + } + + return retval; +} + diff -r 8d22c323fe0f -r 7d845f5d730c examples/Makefile.in --- a/examples/Makefile.in Mon Feb 18 14:12:19 2008 +0100 +++ b/examples/Makefile.in Mon Feb 18 17:14:22 2008 +0100 @@ -46,6 +46,7 @@ $(MAKE) -C TestMasterSlave $@ $(MAKE) -C TestMasterSlaveLSS $@ $(MAKE) -C TestMasterMicroMod $@ + $(MAKE) -C SillySlave $@ $(build_command_seq_wx) endef else diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/EDS2CSV.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/EDS2CSV.py Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# +# -*- coding: iso-8859-1 -*- +# +# +# FILE: EDS2CSV.py +# BEGIN: Nov 30,2007 +# AUTHOR: Giuseppe Massimo Bertani +# EMAIL gmbertani@users.sourceforge.net +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Coding style params: +# skips=4 +# are replaced with blanks +# +# + +import sys +import os +import ConfigParser as cp + +if (len(sys.argv) != 2): + print "Usage:" + print + print "EDS2CSV.py " + print + print + sys.exit(0) + +EDSname = os.path.abspath( os.path.dirname(sys.argv[1]) ) + '/' + sys.argv[1] + +if (os.path.exists(EDSname) is not True): + print + print "Input file ",EDS2CSV," not found." + print + print + sys.exit(0) + +eds = cp.ConfigParser() +eds.read(EDSname) + +ssorted = sorted(eds.sections()) + +# dump entire EDS file to stdout in CSV format comma separated +print "Object Dictionary,",sys.argv[1] +print +for section in ssorted: + print section + print ",", + osorted = sorted(eds.options(section)) + for option in osorted: + print option, ",", + print + print ",", + for option in osorted: + print eds.get(section, option), ",", + print + print + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/Makefile.in Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,79 @@ +#! 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 +CXX = SUB_CXX +LD = SUB_LD +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +EXE_CFLAGS = SUB_EXE_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +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) + +SILLYSLAVE_OBJS = SillySlave.o slave.o main.o + +OBJS = $(SILLYSLAVE_OBJS) ../../src/libcanfestival.a ../../drivers/$(TARGET)/libcanfestival_$(TARGET).a -lcanlib + +ifeq ($(TIMERS_DRIVER),timers_xeno) + PROGDEFINES = -DUSE_XENO +endif + +all: SillySlave + +../../drivers/$(TARGET)/libcanfestival_$(TARGET).a: + $(MAKE) -C ../../drivers/$(TARGET) libcanfestival_$(TARGET).a + + +SillySlave: SillySlave.c $(OBJS) + $(LD) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS) + + +SillySlave.c: SillySlave.od + $(MAKE) -C ../../objdictgen gnosis + python ../../objdictgen/objdictgen.py SillySlave.od SillySlave.c + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +clean: + rm -f $(SILLYSLAVE_OBJS) + rm -f SillySlave + +mrproper: clean + rm -f SillySlave.c + +install: SillySlave + mkdir -p $(PREFIX)/bin/ + cp $< $(PREFIX)/bin/ + +uninstall: + rm -f $(PREFIX)/bin/SillySlave + + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/README Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,16 @@ +SillySlave example for CANfestival + +Its purpose is only to check if the selected +driver works at least a minimum. The PC running this demo +must be connected through CAN bus to a working master that +recognizes the slave nodeId. The slave should be configured +by the master, then switched to operative. After that, when +the master sends a SYNC, the slave answers with PDO1, +containing an integer that increments each time it is sent. + +Please have a look to main.h to tune the master and slave node IDs + +It's all. Enjoy it. +GMB +jan 17,2008 + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/SillySlave.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/SillySlave.c Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,247 @@ + +/* File generated by gen_cfile.py. Should not be modified. */ + +#include "SillySlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ +UNS8 LifeSignal = 0x0; /* Mapped at index 0x2001, subindex 0x00 */ + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + +#define valueRange_EMC 0x9F /* Type for index 0x1003 subindex 0x00 (only set of value 0 is possible) */ +UNS32 SillySlave_valueRangeTest (UNS8 typeValue, void * value) +{ + switch (typeValue) { + case valueRange_EMC: + if (*(UNS8*)value != (UNS8)0) return OD_VALUE_RANGE_EXCEEDED; + break; + } + return 0; +} + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* node_id default value.*/ +UNS8 SillySlave_bDeviceNodeId = 0x00; + +/**************************************************************************/ +/* Array of message processing information */ + +const UNS8 SillySlave_iam_a_slave = 1; + +TIMER_HANDLE SillySlave_heartBeatTimers[1]; + +/* +$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + OBJECT DICTIONARY + +$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +*/ + +/* index 0x1000 : Device Type. */ + UNS32 SillySlave_obj1000 = 0x2000000; /* 33554432 */ + subindex SillySlave_Index1000[] = + { + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1000 } + }; + +/* index 0x1001 : Error Register. */ + UNS8 SillySlave_obj1001 = 0x0; /* 0 */ + subindex SillySlave_Index1001[] = + { + { RO, uint8, sizeof (UNS8), (void*)&SillySlave_obj1001 } + }; + +/* index 0x1003 : Pre-defined Error Field */ + UNS8 SillySlave_highestSubIndex_obj1003 = 0; /* number of subindex - 1*/ + UNS32 SillySlave_obj1003[] = + { + 0x0 /* 0 */ + }; + ODCallback_t SillySlave_Index1003_callbacks[] = + { + NULL, + NULL, + }; + subindex SillySlave_Index1003[] = + { + { RW, valueRange_EMC, sizeof (UNS8), (void*)&SillySlave_highestSubIndex_obj1003 }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1003[0] } + }; + +/* index 0x1005 : SYNC COB ID */ + UNS32 SillySlave_obj1005 = 0x0; /* 0 */ + +/* index 0x1006 : Communication / Cycle Period */ + UNS32 SillySlave_obj1006 = 0x0; /* 0 */ + +/* index 0x1012 : TIME COB ID. */ + UNS32 SillySlave_obj1012 = 0x80000100; /* 2147483904 */ + subindex SillySlave_Index1012[] = + { + { RW, uint32, sizeof (UNS32), (void*)&SillySlave_obj1012 } + }; + +/* index 0x1013 : High Resolution Timestamp. */ + UNS32 SillySlave_obj1013 = 0x0; /* 0 */ + subindex SillySlave_Index1013[] = + { + { RW, uint32, sizeof (UNS32), (void*)&SillySlave_obj1013 } + }; + +/* index 0x1014 : Emergency COB ID */ + UNS32 SillySlave_obj1014 = 0x0; /* 0 */ + +/* index 0x1016 : Consumer Heartbeat Time */ + UNS8 SillySlave_highestSubIndex_obj1016 = 0; + UNS32 SillySlave_obj1016[]={0}; + +/* index 0x1017 : Producer Heartbeat Time */ + UNS16 SillySlave_obj1017 = 0x0; /* 0 */ + +/* index 0x1018 : Identity. */ + UNS8 SillySlave_highestSubIndex_obj1018 = 4; /* number of subindex - 1*/ + UNS32 SillySlave_obj1018_Vendor_ID = 0x4321; /* 17185 */ + UNS32 SillySlave_obj1018_Product_Code = 0x12; /* 18 */ + UNS32 SillySlave_obj1018_Revision_Number = 0x1; /* 1 */ + UNS32 SillySlave_obj1018_Serial_Number = 0x1; /* 1 */ + subindex SillySlave_Index1018[] = + { + { RO, uint8, sizeof (UNS8), (void*)&SillySlave_highestSubIndex_obj1018 }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1018_Vendor_ID }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1018_Product_Code }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1018_Revision_Number }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1018_Serial_Number } + }; + +/* index 0x1200 : Server SDO Parameter. */ + UNS8 SillySlave_highestSubIndex_obj1200 = 2; /* number of subindex - 1*/ + UNS32 SillySlave_obj1200_COB_ID_Client_to_Server_Receive_SDO = 0x600; /* 1536 */ + UNS32 SillySlave_obj1200_COB_ID_Server_to_Client_Transmit_SDO = 0x580; /* 1408 */ + ODCallback_t SillySlave_Index1200_callbacks[] = + { + NULL, + NULL, + NULL, + }; + subindex SillySlave_Index1200[] = + { + { RO, uint8, sizeof (UNS8), (void*)&SillySlave_highestSubIndex_obj1200 }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1200_COB_ID_Client_to_Server_Receive_SDO }, + { RO, uint32, sizeof (UNS32), (void*)&SillySlave_obj1200_COB_ID_Server_to_Client_Transmit_SDO } + }; + +/* index 0x1800 : Transmit PDO 1 Parameter. */ + UNS8 SillySlave_highestSubIndex_obj1800 = 5; /* number of subindex - 1*/ + UNS32 SillySlave_obj1800_COB_ID_used_by_PDO = 0x180; /* 384 */ + UNS8 SillySlave_obj1800_Transmission_Type = 0x1; /* 1 */ + UNS16 SillySlave_obj1800_Inhibit_Time = 0x64; /* 100 */ + UNS8 SillySlave_obj1800_Compatibility_Entry = 0x0; /* 0 */ + UNS16 SillySlave_obj1800_Event_Timer = 0x0; /* 0 */ + ODCallback_t SillySlave_Index1800_callbacks[] = + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + subindex SillySlave_Index1800[] = + { + { RO, uint8, sizeof (UNS8), (void*)&SillySlave_highestSubIndex_obj1800 }, + { RW, uint32, sizeof (UNS32), (void*)&SillySlave_obj1800_COB_ID_used_by_PDO }, + { RW, uint8, sizeof (UNS8), (void*)&SillySlave_obj1800_Transmission_Type }, + { RW, uint16, sizeof (UNS16), (void*)&SillySlave_obj1800_Inhibit_Time }, + { RW, uint8, sizeof (UNS8), (void*)&SillySlave_obj1800_Compatibility_Entry }, + { RW, uint16, sizeof (UNS16), (void*)&SillySlave_obj1800_Event_Timer } + }; + +/* index 0x1A00 : Transmit PDO 1 Mapping. */ + UNS8 SillySlave_highestSubIndex_obj1A00 = 1; /* number of subindex - 1*/ + UNS32 SillySlave_obj1A00[] = + { + 0x20010008 /* 536936456 */ + }; + subindex SillySlave_Index1A00[] = + { + { RW, uint8, sizeof (UNS8), (void*)&SillySlave_highestSubIndex_obj1A00 }, + { RW, uint32, sizeof (UNS32), (void*)&SillySlave_obj1A00[0] } + }; + +/* index 0x2001 : Mapped variable LifeSignal */ + subindex SillySlave_Index2001[] = + { + { RO, uint8, sizeof (UNS8), (void*)&LifeSignal } + }; + +const indextable SillySlave_objdict[] = +{ + { (subindex*)SillySlave_Index1000,sizeof(SillySlave_Index1000)/sizeof(SillySlave_Index1000[0]), 0x1000}, + { (subindex*)SillySlave_Index1001,sizeof(SillySlave_Index1001)/sizeof(SillySlave_Index1001[0]), 0x1001}, + { (subindex*)SillySlave_Index1012,sizeof(SillySlave_Index1012)/sizeof(SillySlave_Index1012[0]), 0x1012}, + { (subindex*)SillySlave_Index1013,sizeof(SillySlave_Index1013)/sizeof(SillySlave_Index1013[0]), 0x1013}, + { (subindex*)SillySlave_Index1018,sizeof(SillySlave_Index1018)/sizeof(SillySlave_Index1018[0]), 0x1018}, + { (subindex*)SillySlave_Index1200,sizeof(SillySlave_Index1200)/sizeof(SillySlave_Index1200[0]), 0x1200}, + { (subindex*)SillySlave_Index1800,sizeof(SillySlave_Index1800)/sizeof(SillySlave_Index1800[0]), 0x1800}, + { (subindex*)SillySlave_Index1A00,sizeof(SillySlave_Index1A00)/sizeof(SillySlave_Index1A00[0]), 0x1A00}, + { (subindex*)SillySlave_Index2001,sizeof(SillySlave_Index2001)/sizeof(SillySlave_Index2001[0]), 0x2001}, +}; + +const indextable * SillySlave_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks) +{ + int i; + *callbacks = NULL; + switch(wIndex){ + case 0x1000: i = 0;break; + case 0x1001: i = 1;break; + case 0x1012: i = 2;break; + case 0x1013: i = 3;break; + case 0x1018: i = 4;break; + case 0x1200: i = 5;*callbacks = SillySlave_Index1200_callbacks; break; + case 0x1800: i = 6;*callbacks = SillySlave_Index1800_callbacks; break; + case 0x1A00: i = 7;break; + case 0x2001: i = 8;break; + default: + *errorCode = OD_NO_SUCH_OBJECT; + return NULL; + } + *errorCode = OD_SUCCESSFUL; + return &SillySlave_objdict[i]; +} + +/* + * To count at which received SYNC a PDO must be sent. + * Even if no pdoTransmit are defined, at least one entry is computed + * for compilations issues. + */ +s_PDO_status SillySlave_PDO_status[1] = {s_PDO_status_Initializer}; + +quick_index SillySlave_firstIndex = { + 5, /* SDO_SVR */ + 0, /* SDO_CLT */ + 0, /* PDO_RCV */ + 0, /* PDO_RCV_MAP */ + 6, /* PDO_TRS */ + 7 /* PDO_TRS_MAP */ +}; + +quick_index SillySlave_lastIndex = { + 5, /* SDO_SVR */ + 0, /* SDO_CLT */ + 0, /* PDO_RCV */ + 0, /* PDO_RCV_MAP */ + 6, /* PDO_TRS */ + 7 /* PDO_TRS_MAP */ +}; + +UNS16 SillySlave_ObjdictSize = sizeof(SillySlave_objdict)/sizeof(SillySlave_objdict[0]); + +CO_Data SillySlave_Data = CANOPEN_NODE_DATA_INITIALIZER(SillySlave); + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/SillySlave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/SillySlave.h Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,19 @@ + +/* File generated by gen_cfile.py. Should not be modified. */ + +#ifndef SILLYSLAVE_H +#define SILLYSLAVE_H + +#include "data.h" + +/* Prototypes of function provided by object dictionnary */ +UNS32 SillySlave_valueRangeTest (UNS8 typeValue, void * value); +const indextable * SillySlave_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks); + +/* Master node data struct */ +extern CO_Data SillySlave_Data; +extern ODCallback_t Server_SDO_Parameter_callbacks[]; /* Callbacks of index0x1200 */ +extern ODCallback_t Transmit_PDO_1_Parameter_callbacks[]; /* Callbacks of index0x1800 */ +extern UNS8 LifeSignal; /* Mapped at index 0x2001, subindex 0x00*/ + +#endif // SILLYSLAVE_H diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/SillySlave.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/SillySlave.od Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,309 @@ + + + + + +Silly Slave example for CANfestival, (C)GMB 2008 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LifeSignal + + + + + + + LifeSignal + + + + + + + + + + + +slave + +SillySlave + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/main.c Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,74 @@ +/* +Copyright (C): Giuseppe Massimo BERTANI +gmbertani@users.sourceforge.net + + +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 +*/ + +/** + * @file main.c + * @author GMB + * @date 17/1/08 + * + * This file is part of SillySlave demo for CANfestival + * open source CANopen stack. + */ + + +#include "main.h" +#include "slave.h" + +#if !defined(WIN32) || defined(__CYGWIN__) +void catch_signal(int sig) +{ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); + + printf("Got Signal %d\n",sig); +} +#endif + + +/** + * Please edit main.h defines before compiling + */ +int main(int argc,char **argv) +{ + char* LibraryPath= DRIVER_LIBRARY; + +#if !defined(WIN32) || defined(__CYGWIN__) + /* install signal handler for manual break */ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); +#endif + +#ifndef NOT_USE_DYNAMIC_LOADING + LoadCanDriver(LibraryPath); +#endif + + + if(InitCANdevice( BUS, BAUDRATE, NODE_SLAVE ) < 0) + { + printf("\nInitCANdevice() failed, exiting.\n"); + return -1; + } + + return 0; +} + + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/main.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/main.h Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,65 @@ +/* +Copyright (C): Giuseppe Massimo BERTANI +gmbertani@users.sourceforge.net + + +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 +*/ + +/** + * @file main.h + * @author GMB + * @date 17/1/08 + * + * This file is part of SillySlave demo for CANfestival + * open source CANopen stack. + */ + + + +#ifndef _MAIN_H + #define _MAIN_H + +#if defined(WIN32) && !defined(__CYGWIN__) +#include +#include "getopt.h" +void pause(void) +{ + system("PAUSE"); +} +#else +#include +#include +#include +#include +#include +#endif + +#include "canfestival.h" + +/* + * Please tune the following defines to suit your needs: + */ +#define NODE_MASTER 0x1 +#define NODE_SLAVE 0x12 +#define DRIVER_LIBRARY "libcanfestival_can_kvaser.so" +#define BAUDRATE 250000 +#define BUS 0 + +#endif /* _MAIN_H */ + + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/slave.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/slave.c Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,164 @@ +/* +Copyright (C): Giuseppe Massimo BERTANI +gmbertani@users.sourceforge.net + + +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 +*/ + +/** + * @file slave.c + * @author GMB + * @date 17/1/08 + * + * This file is part of SillySlave demo for CANfestival + * open source CANopen stack. + */ + +#include "SillySlave.h" +#include "slave.h" +#include "main.h" + + +static UNS8 slaveNode = 0; + +void InitNode(CO_Data* d, UNS32 id) +{ + /* Defining the node Id */ + setNodeId(&SillySlave_Data, slaveNode); + /* CAN init */ + setState(&SillySlave_Data, Initialisation); +} + +INTEGER8 InitCANdevice( UNS8 bus, UNS32 baudrate, UNS8 node ) +{ +char busName[2]; +char baudRate[7]; +s_BOARD board; + + sprintf(busName, "%u", bus); + sprintf(baudRate, "%u", baudrate); + board.busname = busName; + board.baudrate = baudRate; + + slaveNode = node; + + SillySlave_Data.heartbeatError = SillySlave_heartbeatError; + SillySlave_Data.initialisation = SillySlave_initialisation; + SillySlave_Data.preOperational = SillySlave_preOperational; + SillySlave_Data.operational = SillySlave_operational; + SillySlave_Data.stopped = SillySlave_stopped; + SillySlave_Data.post_sync = SillySlave_post_sync; + SillySlave_Data.post_TPDO = SillySlave_post_TPDO; + SillySlave_Data.storeODSubIndex = SillySlave_storeODSubIndex; + SillySlave_Data.post_emcy = SillySlave_post_emcy; + + if(!canOpen(&board, &SillySlave_Data)) + { + printf("\n\aInitCANdevice() CAN bus %s opening error, baudrate=%s\n",board.busname, board.baudrate); + return -1; + } + + + printf("\nInitCANdevice(), canOpen() OK, starting timer loop...\n"); + + /* Start timer thread */ + StartTimerLoop(&InitNode); + + /* wait Ctrl-C */ + pause(); + printf("\nFinishing.\n"); + + /* Stop slave */ + setState(&SillySlave_Data, Stopped); + + /* Stop timer thread */ + StopTimerLoop(); + return 0; +} + +void SillySlave_heartbeatError(CO_Data* d, UNS8 heartbeatID) +{ + printf("SillySlave_heartbeatError %d\n", heartbeatID); +} + +void SillySlave_initialisation(CO_Data* d ) +{ + UNS32 PDO1_COBID = 0x0180 + NODE_MASTER; + UNS8 size = sizeof(PDO1_COBID); + + printf("SillySlave_initialisation\n"); + + /* sets TXPDO1 COB-ID to match master node ID */ + writeLocalDict( + &SillySlave_Data, /*CO_Data* d*/ + 0x1800, /*UNS16 index*/ + 0x01, /*UNS8 subind*/ + &PDO1_COBID, /*void * pSourceData,*/ + &size, /* UNS8 * pExpectedSize*/ + RW); /* UNS8 checkAccess */ + + /* value sent to master at each SYNC received */ + LifeSignal = 0; +} + +void SillySlave_preOperational(CO_Data* d) +{ + printf("SillySlave_preOperational\n"); +} + +void SillySlave_operational(CO_Data* d) +{ + printf("SillySlave_operational\n"); +} + +void SillySlave_stopped(CO_Data* d) +{ + printf("SillySlave_stopped\n"); +} + +void SillySlave_post_sync(CO_Data* d) +{ + printf("SillySlave_post_sync: \n"); + LifeSignal++; +} + +void SillySlave_post_TPDO(CO_Data* d) +{ + printf("SillySlave_post_TPDO: \n"); + printf("LifeSignal = %u\n", LifeSignal); +} + +void SillySlave_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex) +{ + /*TODO : + * - call getODEntry for index and subindex, + * - save content to file, database, flash, nvram, ... + * + * To ease flash organisation, index of variable to store + * can be established by scanning d->objdict[d->ObjdictSize] + * for variables to store. + * + * */ + printf("SillySlave_storeODSubIndex : %4.4x %2.2xh\n", wIndex, bSubindex); +} + +void SillySlave_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg) +{ + printf("Slave received EMCY message. Node: %2.2xh ErrorCode: %4.4x ErrorRegister: %2.2xh\n", nodeID, errCode, errReg); +} + diff -r 8d22c323fe0f -r 7d845f5d730c examples/SillySlave/slave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/SillySlave/slave.h Mon Feb 18 17:14:22 2008 +0100 @@ -0,0 +1,51 @@ +/* +Copyright (C): Giuseppe Massimo BERTANI +gmbertani@users.sourceforge.net + + +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 +*/ + +/** + * @file slave.h + * @author GMB + * @date 17/1/08 + * + * This file is part of SillySlave demo for CANfestival + * open source CANopen stack. + */ + + + +#include "data.h" + +INTEGER8 InitCANdevice( UNS8 bus, UNS32 baudrate, UNS8 node ); + +void SillySlave_heartbeatError(CO_Data* d, UNS8); + +UNS8 SillySlave_canSend(Message *); + +void SillySlave_initialisation(CO_Data* d); +void SillySlave_preOperational(CO_Data* d); +void SillySlave_operational(CO_Data* d); +void SillySlave_stopped(CO_Data* d); + +void SillySlave_post_sync(CO_Data* d); +void SillySlave_post_TPDO(CO_Data* d); +void SillySlave_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex); +void SillySlave_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg); +