Added Kvaser hardware support, thanks to Giuseppe Massimo Bertani .
--- 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
--- /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
--- /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
--- /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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+
+/* includes Kvaser's CANLIB header */
+#include <canlib.h>
+
+#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;
+}
+
--- 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
--- /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:
+# <TAB> skips=4
+# <TAB> are replaced with blanks
+#
+#
+
+import sys
+import os
+import ConfigParser as cp
+
+if (len(sys.argv) != 2):
+ print "Usage:"
+ print
+ print "EDS2CSV.py <input file> "
+ 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
+
--- /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
+
+
--- /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
+
--- /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);
+
--- /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
--- /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 @@
+<?xml version="1.0"?>
+<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
+<PyObject module="node" class="Node" id="-1268630260">
+<attr name="Profile" type="dict" id="-1268626332" >
+</attr>
+<attr name="Description" type="string">Silly Slave example for CANfestival, (C)GMB 2008</attr>
+<attr name="Dictionary" type="dict" id="-1268621556" >
+ <entry>
+ <key type="numeric" value="4096" />
+ <val type="numeric" value="33554432" />
+ </entry>
+ <entry>
+ <key type="numeric" value="4097" />
+ <val type="numeric" value="0" />
+ </entry>
+ <entry>
+ <key type="numeric" value="6144" />
+ <val type="list" id="-1214451316" >
+ <item type="string" value="{True:"$NODEID+0x%X80"%(base+1),False:0}[base<4]" />
+ <item type="numeric" value="1" />
+ <item type="numeric" value="100" />
+ <item type="numeric" value="0" />
+ <item type="numeric" value="0" />
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="8193" />
+ <val type="numeric" value="0" />
+ </entry>
+ <entry>
+ <key type="numeric" value="4114" />
+ <val type="numeric" value="2147483904L" />
+ </entry>
+ <entry>
+ <key type="numeric" value="4115" />
+ <val type="numeric" value="0" />
+ </entry>
+ <entry>
+ <key type="numeric" value="6656" />
+ <val type="list" id="-1214450420" >
+ <item type="numeric" value="536936456" />
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="4120" />
+ <val type="list" id="-1214449748" >
+ <item type="numeric" value="17185" />
+ <item type="numeric" value="18" />
+ <item type="numeric" value="1" />
+ <item type="numeric" value="1" />
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="4608" />
+ <val type="list" id="-1214449460" >
+ <item type="string" value=""$NODEID+0x600"" />
+ <item type="string" value=""$NODEID+0x580"" />
+ </val>
+ </entry>
+</attr>
+<attr name="SpecificMenu" type="list" id="-1214449556" >
+</attr>
+<attr name="ParamsDictionary" type="dict" id="-1268617172" >
+ <entry>
+ <key type="numeric" value="4096" />
+ <val type="dict" id="-1268617036" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="fake nr" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="4608" />
+ <val type="dict" id="-1268616900" >
+ <entry>
+ <key type="string" value="callback" />
+ <val type="True" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="6144" />
+ <val type="dict" id="-1268616764" >
+ <entry>
+ <key type="numeric" value="2" />
+ <val type="dict" id="-1268616628" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="send PDO1 after each SYNC" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="3" />
+ <val type="dict" id="-1268616492" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="10mS" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="5" />
+ <val type="dict" id="-1268616356" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="not used with SYNC" />
+ </entry>
+ </val>
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="5120" />
+ <val type="dict" id="-1268616220" >
+ <entry>
+ <key type="numeric" value="1" />
+ <val type="dict" id="-1268616084" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="2" />
+ <val type="dict" id="-1268615948" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="3" />
+ <val type="dict" id="-1268615812" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="4" />
+ <val type="dict" id="-1268615676" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="5" />
+ <val type="dict" id="-1268615540" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="string" value="callback" />
+ <val type="False" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="6145" />
+ <val type="dict" id="-1268615404" >
+ <entry>
+ <key type="numeric" value="2" />
+ <val type="dict" id="-1268615268" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="Invio ogni 2 SYNC" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="3" />
+ <val type="dict" id="-1268615132" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="10 mS" />
+ </entry>
+ </val>
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="4114" />
+ <val type="dict" id="-1268614996" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="for timestamp" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="6657" />
+ <val type="dict" id="-1268614860" >
+ <entry>
+ <key type="numeric" value="1" />
+ <val type="dict" id="-1268614724" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="Rx dal punto di vista del master, MCA lo trasmette" />
+ </entry>
+ </val>
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="5632" />
+ <val type="dict" id="-1268614588" >
+ <entry>
+ <key type="numeric" value="1" />
+ <val type="dict" id="-1268614452" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="Tx dal punto di vista del master, MC lo riceve" />
+ </entry>
+ </val>
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="4120" />
+ <val type="dict" id="-1268614316" >
+ <entry>
+ <key type="numeric" value="0" />
+ <val type="dict" id="-1268614180" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="4 pseudorandomic numbers:" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="1" />
+ <val type="dict" id="-1268614044" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ <entry>
+ <key type="numeric" value="2" />
+ <val type="dict" id="-1268613908" >
+ <entry>
+ <key type="string" value="comment" />
+ <val type="string" value="" />
+ </entry>
+ </val>
+ </entry>
+ </val>
+ </entry>
+</attr>
+<attr name="UserMapping" type="dict" id="-1268613772" >
+ <entry>
+ <key type="numeric" value="8193" />
+ <val type="dict" id="-1268613636" >
+ <entry>
+ <key type="string" value="need" />
+ <val type="False" value="" />
+ </entry>
+ <entry>
+ <key type="string" value="values" />
+ <val type="list" id="-1214456756" >
+ <item type="dict" id="-1268613500" >
+ <entry>
+ <key type="string" value="access" />
+ <val type="string" value="ro" />
+ </entry>
+ <entry>
+ <key type="string" value="pdo" />
+ <val type="True" value="" />
+ </entry>
+ <entry>
+ <key type="string" value="type" />
+ <val type="numeric" value="5" />
+ </entry>
+ <entry>
+ <key type="string" value="name" />
+ <val type="string">LifeSignal</val>
+ </entry>
+ </item>
+ </val>
+ </entry>
+ <entry>
+ <key type="string" value="name" />
+ <val type="string">LifeSignal</val>
+ </entry>
+ <entry>
+ <key type="string" value="struct" />
+ <val type="numeric" value="1" />
+ </entry>
+ </val>
+ </entry>
+</attr>
+<attr name="DS302" type="dict" id="-1268613364" >
+</attr>
+<attr name="ProfileName" type="string" value="DS-301" />
+<attr name="Type" type="string">slave</attr>
+<attr name="ID" type="numeric" value="0" />
+<attr name="Name" type="string">SillySlave</attr>
+</PyObject>
--- /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;
+}
+
+
--- /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 <windows.h>
+#include "getopt.h"
+void pause(void)
+{
+ system("PAUSE");
+}
+#else
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+#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 */
+
+
--- /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);
+}
+
--- /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);
+