CosateQ contribution.
--- a/CanFestival-3.vc8.sln Fri Nov 12 22:02:32 2010 +0100
+++ b/CanFestival-3.vc8.sln Fri Nov 12 22:24:06 2010 +0100
@@ -1,18 +1,16 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CanFestival-3", "CanFestival-3.vc8.vcproj", "{50EF2507-9B87-4525-8B19-80EB42E67079}"
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CanFestival-3", "CanFestival-3.vc8.vcxproj", "{50EF2507-9B87-4525-8B19-80EB42E67079}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_uvccm_win32", "drivers\can_uvccm_win32\can_uvccm_win32.vcproj", "{39E3300A-29B4-4AA7-AF62-3B181FC26155}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_uvccm_win32", "drivers\can_uvccm_win32\can_uvccm_win32.vcxproj", "{782632D2-B467-DF90-C86E-D767972BAA59}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_peak_win32", "drivers\can_peak_win32\can_peak_win32.vcproj", "{732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_peak_win32", "drivers\can_peak_win32\can_peak_win32.vcxproj", "{C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestMasterSlave", "examples\TestMasterSlave\TestMasterSlave.vcproj", "{B51A176D-5320-4534-913B-3025CED5B27E}"
- ProjectSection(ProjectDependencies) = postProject
- {50EF2507-9B87-4525-8B19-80EB42E67079} = {50EF2507-9B87-4525-8B19-80EB42E67079}
- EndProjectSection
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestMasterSlave", "examples\TestMasterSlave\TestMasterSlave.vcxproj", "{B51A176D-5320-4534-913B-3025CED5B27E}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_ixxat_win32", "drivers\can_ixxat_win32\can_ixxat_win32.vc8.vcproj", "{8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_ixxat_win32", "drivers\can_ixxat_win32\can_ixxat_win32.vc8.vcxproj", "{8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_copcican_win32", "drivers\can_copcican_win32\can_copcican_win32.vcxproj", "{A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -30,22 +28,22 @@
{50EF2507-9B87-4525-8B19-80EB42E67079}.Release UNICODE|Win32.Build.0 = Release|Win32
{50EF2507-9B87-4525-8B19-80EB42E67079}.Release|Win32.ActiveCfg = Release|Win32
{50EF2507-9B87-4525-8B19-80EB42E67079}.Release|Win32.Build.0 = Release|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug|Win32.ActiveCfg = Debug|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug|Win32.Build.0 = Debug|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release|Win32.ActiveCfg = Release|Win32
- {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release|Win32.Build.0 = Release|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug|Win32.ActiveCfg = Debug|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug|Win32.Build.0 = Debug|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release|Win32.ActiveCfg = Release|Win32
- {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release|Win32.Build.0 = Release|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Debug|Win32.ActiveCfg = Debug|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Debug|Win32.Build.0 = Debug|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Release|Win32.ActiveCfg = Release|Win32
+ {782632D2-B467-DF90-C86E-D767972BAA59}.Release|Win32.Build.0 = Release|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Debug|Win32.Build.0 = Debug|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Release|Win32.ActiveCfg = Release|Win32
+ {C943EB26-ADEA-0DCD-E581-8BF52F0F20F5}.Release|Win32.Build.0 = Release|Win32
{B51A176D-5320-4534-913B-3025CED5B27E}.Debug UNICODE|Win32.ActiveCfg = Debug|Win32
{B51A176D-5320-4534-913B-3025CED5B27E}.Debug UNICODE|Win32.Build.0 = Debug|Win32
{B51A176D-5320-4534-913B-3025CED5B27E}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -62,6 +60,14 @@
{8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB}.Release UNICODE|Win32.Build.0 = Release|Win32
{8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB}.Release|Win32.ActiveCfg = Release|Win32
{8F57E7FF-1B73-4134-A2B2-9C0EADB2AEFB}.Release|Win32.Build.0 = Release|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Debug UNICODE|Win32.ActiveCfg = Debug|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Debug UNICODE|Win32.Build.0 = Debug|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Debug|Win32.Build.0 = Debug|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Release UNICODE|Win32.ActiveCfg = Release|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Release UNICODE|Win32.Build.0 = Release|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Release|Win32.ActiveCfg = Release|Win32
+ {A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
--- a/configure Fri Nov 12 22:02:32 2010 +0100
+++ b/configure Fri Nov 12 22:24:06 2010 +0100
@@ -2,41 +2,41 @@
#
# Copyright (C) 2004 Edouard TISSERRANT, Laurent BESSARD
-# Based on Gabriel Gerhardsson's cacheprobe configure script.
-#
-# This file is part of CanFestival, a library implementing CanOpen Stack.
-#
+# Based on Gabriel Gerhardsson's cacheprobe configure script.
+#
+# This file is part of CanFestival, a library implementing 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
-#
+#
###########################################################################
# DEFAULT CANFESTIVAL DEFINES #
###########################################################################
-# Number of can bus to use
+# Number of can bus to use
MAX_CAN_BUS_ID=1
# max bytes to transmit by SDO Put 4 if you only support expedited transfert.
#For a normal transfert, (usually for a string), put the maximum string size to transfer.
SDO_MAX_LENGTH_TRANSFERT=32
-# Number of SDO from differents nodes that the node can manage concurrently.
+# Number of SDO from differents nodes that the node can manage concurrently.
#for a slave node, usually put 1.
SDO_MAX_SIMULTANEOUS_TRANSFERTS=4
-# Used for NMTable[bus][nodeId]
+# Used for NMTable[bus][nodeId]
# You can put less of 128 if on the netwo
# are connected only smaller nodeId node.
NMT_MAX_NODE_ID=128
@@ -78,7 +78,7 @@
# Install prefix
SUB_PREFIX=
-# Used for C compiler test/detection
+# Used for C compiler test/detection
CFLAGS=
test=conftest
rm -f $test $test.c
@@ -96,7 +96,7 @@
###########################################################################
while [ $# -ge 1 ]; do
optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
-
+
case $1 in
--cc=*) CC=$optarg;;
--cxx=*) CXX=$optarg;;
@@ -145,11 +145,11 @@
echo " \"win32\" for win32 systems (native, mingw or VC++)"
echo " \"hcs12\" for HCS12 micro-controller"
echo " --can=foo Use 'foo' as CAN driver"
- echo " \"anagate_linux\" use AnaGate CAN(duo) driver for linux"
- echo " \"anagate_win32\" use AnaGate CAN(duo) driver for win32"
+ echo " \"anagate_linux\" use AnaGate CAN(duo) driver for linux"
+ echo " \"anagate_win32\" use AnaGate CAN(duo) driver for win32"
echo " \"peak_linux\" use Linux build host installed Peak driver and library"
echo " see http://www.peak-system.com/linux/"
- echo " \"peak_win32\" use win32 PcanLight Peak driver and library with Cygwin"
+ echo " \"peak_win32\" use win32 PcanLight Peak driver and library with Cygwin"
echo " see http://www.peak-system.com/themen/download_gb.html"
echo " \"virtual\" use unix pipe based virtual can driver"
echo " \"virtual_kernel\" use kernel module virtual can driver"
@@ -159,7 +159,11 @@
echo " see http://www.ocera.org/download/components/WP7/lincan-0.3.3.html"
echo " \"can4linux\" can4linux driver"
echo " see http://www.port.de/engl/canprod/hw_can4linux.html"
- echo " --timers=foo Use 'foo' as TIMERS driver (can be 'unix', 'xeno', 'rtai' or 'kernel')"
+ echo " \"copcican_linux\" user space driver interface for CO-PCICAN card"
+ echo " see http://www.cosateq.com/"
+ echo " \"copcican_comedi\" COMEDI driver interface for CO-PCICAN card"
+ echo " see http://www.cosateq.com/"
+ echo " --timers=foo Use 'foo' as TIMERS driver (can be 'unix', 'xeno', 'rtai', 'kernel' or 'kernel_xeno')"
echo " --wx=foo Force result of WxWidgets detection (0 or 1)"
echo " --binutils=path Override binutils path detection (as regards \$CC content)"
echo " --disable-dll Disable run-time dynamic linking of can, led and nvram drivers"
@@ -273,18 +277,24 @@
# Try to guess can
if [ "$SUB_CAN_DRIVER" = "" ]; then
if [ "$SUB_TARGET" = "unix" ]; then
- if [ -e /usr/lib/libpcan.so ]; then
+ if [ -e /usr/lib/libpcan.so ]; then
echo "Choosing installed Peak driver as CAN driver."
SUB_CAN_DRIVER=peak_linux
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
+ 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 [ -e /usr/local/lib/libAnaGateAPIDLL.so ]; then
+ elif [ -e /usr/local/lib/libAnaGateAPIDLL.so ]; then
echo "Choosing installed AnaGate driver as CAN driver. (unix)"
SUB_CAN_DRIVER=anagate_linux
+ elif [ -e /usr/local/lib/libcanfestival_can_copcican_linux.so ]; then
+ echo "Choosing installed CO-PCICAN driver as CAN driver. (unix)"
+ SUB_CAN_DRIVER=copcican_linux
+ elif [ -e /usr/local/lib/libcanfestival_can_copcican_comedi.so ]; then
+ echo "Choosing installed CO-PCICAN driver as CAN driver. (unix)"
+ SUB_CAN_DRIVER=copcican_comedi
elif [ "$SUB_OS_NAME" = "CYGWIN" -a "$KVASER_DLL_PATH" != "" ]; then
echo "Choosing installed Kvaser driver as CAN driver. (cygwin)"
SUB_CAN_DRIVER=kvaser
@@ -309,7 +319,7 @@
# Warn for unstalled peak driver if choosen
if [ "$SUB_CAN_DRIVER" = "peak" ]; then
- if [ ! -e /usr/lib/libpcan.so ]; then
+ if [ ! -e /usr/lib/libpcan.so ]; then
echo "Peak driver hasn't been installed !"
exit -1
fi
@@ -317,21 +327,29 @@
# Warn for unstalled peak driver if choosen
if [ "$SUB_CAN_DRIVER" = "anagate_linux" ]; then
- if [ ! -e /usr/local/lib/libAnaGateAPIDLL.so ]; then
+ if [ ! -e /usr/local/lib/libAnaGateAPIDLL.so ]; then
echo "AnaGateCAN driver hasn't been installed !"
exit -1
fi
fi
+# Warn for unstalled CO-PCICAN driver if choosen
+if [ "$SUB_CAN_DRIVER" = "copcican_linux" ]; then
+ if [ ! -e /usr/local/lib/libcanfestival_can_copcican_linux.so ]; then
+ echo "CO-PCICAN driver hasn't been installed !"
+ exit -1
+ 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
+ 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
+ if [ ! -e /usr/lib/libcanlib.so ]; then
echo "Kvaser driver hasn't been installed (unix)"
exit -1
fi
@@ -348,20 +366,20 @@
# search for gcc hcs12 compiler m6811-elf-gcc or m68hc12-gcc ?
if [ "$CC" = "" ]; then
which m6811-elf-gcc >/dev/null 2>&1
- if (( $? )); then
+ if (( $? )); then
which m68hc12-gcc >/dev/null 2>&1
- if (( $? )); then
+ if (( $? )); then
echo "Please use --cc flag to specify compiler"
exit 0
else
- CC=m68hc12-gcc
+ CC=m68hc12-gcc
fi
else
CC=m6811-elf-gcc
SUB_PROG_CFLAGS=-m68hc12
fi
fi
-fi
+fi
#### CAN_DRIVER ####
@@ -377,7 +395,7 @@
SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -I$KVASER_INCLUDE_PATH
fi
fi
- fi
+ fi
fi
if [ "$SUB_CAN_DRIVER" = "peak_linux" ]; then
@@ -469,6 +487,20 @@
fi
fi
+if [ "$SUB_TIMERS_DRIVER" = "kernel_xeno" ]; then
+ DISABLE_DLL=1
+ if [ "$SUB_KERNELDIR" = "" ]; then
+ # use directory of current kernel
+ SUB_KERNELDIR=/lib/modules/$(uname -r)/build
+ fi
+
+ # Also get the xenomai config
+ RT_LIB_DIR=`$XENO_CONFIG --library-dir`\ -Wl,-rpath\ `$XENO_CONFIG --library-dir`
+ SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ `$XENO_CONFIG --xeno-ldflags`\ -L$RT_LIB_DIR\ -lnative\ -lrtdm
+ SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -DUSE_XENO\ `$XENO_CONFIG --xeno-cflags`
+ RTCAN_SOCKET=1
+fi
+
if [ "$SUB_TIMERS_DRIVER" = "none" ]; then
SUB_TIMERS_DRIVER=
fi
@@ -489,7 +521,7 @@
echo "Checking for ${CC2}... No."
fi
rm -f $test.c $test.o
-
+
# Check for first compiler, CC1
cat > $test.c <<EOF
int main() { return 0; }
@@ -538,7 +570,7 @@
if [ "$SUB_OS_NAME" = "CYGWIN" ]; then
SUB_PROG_CFLAGS="-mno-cygwin"
fi
-fi
+fi
if [ "$SUB_TARGET" = "unix" ]; then
if [ "$LD" = "" ]; then
@@ -551,12 +583,12 @@
# Guess prefix as regard cross compiling target machine
if [ "$SUB_PREFIX" = "" ]; then
$CC -dumpspecs |grep -A 1 'cross_compile'|grep -q 1
- if (( $? )); then
+ if (( $? )); then
SUB_PREFIX=/usr/local
echo "Not cross-compiling. Will install in $SUB_PREFIX";
else
SUB_PREFIX=/usr/`$CC -dumpmachine | tr -d '\r\n'`
- echo "This is a cross-compiler. Will install in $SUB_PREFIX";
+ echo "This is a cross-compiler. Will install in $SUB_PREFIX";
fi
fi
@@ -642,7 +674,7 @@
else
echo "#define $i ${!i}" >> include/config.h
fi
-done
+done
echo "" >> include/config.h
for i in \
@@ -666,7 +698,7 @@
save_ifs="$IFS"; IFS=','
-for DEBUG_METHOD in $DEBUG;
+for DEBUG_METHOD in $DEBUG;
do
IFS="$save_ifs"
case $DEBUG_METHOD in
@@ -679,7 +711,7 @@
echo "Possible Debug's methods are : \"ERR\", \"WAR\", \"MSG\", \"PDO\""
exit -1
;;
- esac
+ esac
done
if [ $WAR ]; then
@@ -720,7 +752,7 @@
else
SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -ldl
fi
-
+
fi
@@ -767,7 +799,13 @@
if [ "$SUB_TARGET" = "unix" -a "$SUB_TIMERS_DRIVER" = "kernel" ]; then
MAKEFILES=$MAKEFILES\
-\ examples/kerneltest/Makefile.in
+\ examples/kerneltest/Makefile.in\
+\ examples/test_copcican_comedi/Makefile.in
+
+elif [ "$SUB_TARGET" = "unix" -a "$SUB_TIMERS_DRIVER" = "kernel_xeno" ]; then
+ MAKEFILES=$MAKEFILES\
+\ examples/kerneltest/Makefile.in\
+\ examples/test_copcican_comedi/Makefile.in
elif [ "$SUB_TARGET" = "unix" ]; then
MAKEFILES=$MAKEFILES\
@@ -775,7 +813,8 @@
\ examples/TestMasterSlave/Makefile.in\
\ examples/TestMasterSlaveLSS/Makefile.in\
\ examples/SillySlave/Makefile.in\
-\ examples/TestMasterMicroMod/Makefile.in
+\ examples/TestMasterMicroMod/Makefile.in\
+\ examples/test_copcican_linux/Makefile.in
fi
if [ "$SUB_TARGET" = "win32" ]; then
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/copcican_comedi_howto.txt Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,55 @@
+HOW TO configure CanFestival for a CO-PCICAN card for COMEDI in the kernel (optionally with Xenomai):
+
+
+
+pre-actions:
+- install the CO-PCICAN card
+- install and load COMEDI and the corresponding driver co_pcican.ko
+ (COMEDI sources are expected in /usr/src/comedi)
+
+- optionally: install the Xenomai package
+ (Xenomai sources are expected in /usr/xenomai)
+
+
+
+- unpack the package to your target (if not already done)
+
+- perform package configuration:
+ sh ./configure --can=copcican_comedi --timers=kernel --kerneldir='/lib/modules/$(shell uname -r)/build'
+
+ optionally: use --timers=kernel_xeno for the realtime Xenomai timer functions
+
+- patch the sed "s:-I:-I$(src)/:g" statement to
+ 's:-I../..:-I/canopeninstalldir:g' in drivers/unix/Makefile
+ 's:-I..:-I/canopeninstalldir:g' in src/Makefile
+ The original statement did not run on my computer !
+
+- build the CanFestival Unix library:
+ cd drivers/unix
+ make
+
+- build the CanFestival library:
+ cd src
+ make
+ make install
+
+- build the CO-PCICAN driver interface:
+ cd drivers/can_copcican_comedi
+ make
+ make install
+
+- build the example application (not for Xenomai):
+ cd examples/test_copcican_comedi
+ make
+ make install
+
+Run test_copcican_comedi with the insert.sh script to see it works...
+
+For Xenomai please use the example /usr/src/scale-rt-canopendemo of the SCALE-RT distribution.
+
+
+
+Copyright (C) 2010 Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/copcican_linux_howto.txt Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,49 @@
+HOW TO configure CanFestival for a CO-PCICAN card for linux:
+
+
+
+pre-actions:
+- install the CO-PCICAN card
+- install and load the user space driver co_pcicanext.ko
+
+
+
+- unpack the package to your target (if not already done)
+
+- create empty file:
+ touch /usr/local/lib/libcanfestival_can_copcican_linux.so
+
+- perform package configuration:
+ sh ./configure --can=copcican_linux
+
+- build the CanFestival library:
+ cd src
+ make
+ make install
+
+- build the CanFestival Unix library:
+ cd drivers/unix
+ make
+ make install
+
+BUGFIX:
+ copy library into build directory back:
+ cp /usr/local/lib/libcanfestival_unix.a drivers/unix
+
+- build the CO-PCICAN driver interface:
+ cd drivers/can_copcican_linux
+ make
+ make install
+
+- build the example application:
+ cd examples/test_copcican_linux
+ make
+
+Run test_copcican_linux to see it works...
+
+
+
+Copyright (C) 2010 Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_comedi/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,60 @@
+#! gmake
+
+#
+# Copyright (C) 2010 Cosateq GmbH & Co.KG
+# http://www.cosateq.com/
+# http://www.scale-rt.com/
+#
+# 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
+#
+
+#ifneq ($(KERNELRELEASE),)
+# Kbuild part of Makefile
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+
+EXTRA_CFLAGS := -I$(src)/../../include
+EXTRA_CFLAGS += -I$(src)/../../include/$(TARGET)
+EXTRA_CFLAGS += -I$(src)/../../include/$(CAN_DRIVER)
+EXTRA_CFLAGS += -I/usr/src/comedi/include
+EXTRA_CFLAGS += SUB_PROG_CFLAGS
+
+obj-m := can_copcican_comedi.o
+can_copcican_comediko-objs = $(CAN_DRIVER).o
+
+#else
+# Normal Makefile
+PREFIX = SUB_PREFIX
+KERNELDIR := SUB_KERNELDIR
+
+all: driver
+
+driver:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
+
+clean:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) clean
+ rm -f Module.symvers
+
+mrproper: clean
+
+install:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules_install
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_comedi/can_copcican_comedi.c Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,490 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ COMEDI interface for CO-PCICAN card.
+*/
+
+#include <linux/module.h>
+#include <linux/comedi.h>
+#include <linux/comedilib.h>
+
+#define NEED_PRINT_MESSAGE
+#include "can_driver.h"
+#include "def.h"
+#include "co_pcicanops.h"
+
+MODULE_LICENSE("GPL");
+
+/* at the moment not threadsafe :-( */
+static unsigned char selectedChannelRx = 0, selectedChannelTx = 0;
+
+static int rt_strcmp( const char *src, const char *dst )
+{
+ int ret = 0;
+
+ while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
+ {
+ src++;
+ dst++;
+ }
+
+ if( ret < 0 )
+ {
+ ret = -1 ;
+ }
+ else
+ {
+ if( ret > 0 )
+ ret = 1 ;
+ }
+
+ return ret;
+}
+
+static int TranslateBaudRate( char* optarg )
+{
+ /* values see documentation of CO-PCICAN */
+ if( !rt_strcmp( optarg, "1M" ) ) return 0;
+ if( !rt_strcmp( optarg, "800K" ) ) return 1;
+ if( !rt_strcmp( optarg, "500K" ) ) return 2;
+ if( !rt_strcmp( optarg, "250K" ) ) return 3;
+ if( !rt_strcmp( optarg, "125K" ) ) return 4;
+ if( !rt_strcmp( optarg, "100K" ) ) return 5;
+ if( !rt_strcmp( optarg, "83.3K" ) ) return 6;
+ if( !rt_strcmp( optarg, "10K" ) ) return 7;
+
+ return -1;
+}
+
+/*********CO-PCICAN specific functions to communicate with the board**********/
+typedef struct
+{
+ char used;
+ CAN_HANDLE fd;
+ void* receiveTask;
+ void* d;
+} CANPort; /* taken from drivers/unix.c */
+
+comedi_t* get_dev_of_port( CAN_PORT port )
+{
+ CANPort *thisPort = (CANPort*)port;
+ CAN_HANDLE thisHandle;
+ comedi_t *dev;
+
+ if( thisPort == NULL )
+ {
+ MSG("can_copcican_comedi: get_dev_of_port(): thisPort is NULL\n");
+ return NULL;
+ }
+
+ thisHandle = thisPort->fd;
+
+ if( thisHandle == NULL )
+ {
+ MSG("can_copcican_comedi: get_dev_of_port(): thisHandle is NULL\n");
+ return NULL;
+ }
+
+ dev = (comedi_t*)thisHandle;
+
+ /*MSG("can_copcican_comedi: get_dev_of_port(): handle is 0x%08x\n", (unsigned int)dev);*/
+
+ return dev;
+}
+
+int co_pcican_enter_run_mode( comedi_t *dev )
+{
+ unsigned int opcmd[15];
+ unsigned int opcode = CMDQ_OPC_ENTER_RUN_MODE;
+ comedi_insn insn;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: co_pcican_enter_run_mode(): dev is NULL\n");
+ return 1;
+ }
+
+ memset( opcmd, 0x00, sizeof(opcmd) );
+ opcmd[0] = 0;
+
+ memset( &insn, 0x00, sizeof(insn) );
+ insn.insn = INSN_CONFIG;
+ insn.n = 1;
+ insn.data = (void*)opcmd;
+ insn.subdev = 0;
+ insn.unused[0] = opcode; /* in use for CO-PCICAN */
+
+ comedi_do_insn( dev, &insn );
+
+ opcmd[0] = 2;
+ insn.subdev = 2;
+ insn.unused[0] = opcode; /* in use for CO-PCICAN */
+
+ return comedi_do_insn( dev, &insn );
+}
+
+int co_pcican_enter_config_mode( comedi_t *dev )
+{
+ unsigned int opcmd[15];
+ unsigned int opcode = CMDQ_OPC_ENTER_CONFIG_MODE;
+ comedi_insn insn;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: co_pcican_enter_config_mode(): dev is NULL\n");
+ return 1;
+ }
+
+ memset( opcmd, 0x00, sizeof(opcmd) );
+ opcmd[0] = 0;
+
+ memset( &insn, 0x00, sizeof(insn) );
+ insn.insn = INSN_CONFIG;
+ insn.n = 1;
+ insn.data = (void*)opcmd;
+ insn.subdev = 0;
+ insn.unused[0] = opcode; /* in use for CO-PCICAN */
+
+ comedi_do_insn( dev, &insn );
+
+ opcmd[0] = 2;
+ insn.subdev = 2;
+ insn.unused[0] = opcode; /* in use for CO-PCICAN */
+
+ return comedi_do_insn( dev, &insn );
+}
+
+int co_pcican_select_channel( const unsigned char channel, const unsigned int direction )
+{
+ if( channel >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_comedi: co_pcican_select_channel(): invalid channel\n");
+ return -1;
+ }
+
+ /* at the moment not threadsafe :-( */
+ switch( direction )
+ {
+ case RX: selectedChannelRx = channel;
+ break;
+ case TX: selectedChannelTx = channel;
+ break;
+ default: return -1;
+ }
+
+ return 0;
+}
+
+int co_pcican_configure_selected_channel( comedi_t *dev, s_BOARD *board, const unsigned int direction )
+{
+ unsigned int opcmd[15];
+ unsigned int opcode = CMDQ_OPC_SET_CONFIG_CHANNEL;
+ unsigned int selectedChannel;
+ comedi_insn insn;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: co_pcican_configure_selected_channel(): dev is NULL\n");
+ return -1;
+ }
+
+ if( board == NULL )
+ {
+ MSG("can_copcican_comedi: co_pcican_configure_selected_channel(): board is NULL\n");
+ return -1;
+ }
+
+ if( board->baudrate == NULL )
+ {
+ MSG("can_copcican_comedi: co_pcican_configure_selected_channel(): baudrate is NULL\n");
+ return -1;
+ }
+
+ switch( direction )
+ {
+ case RX: selectedChannel = selectedChannelRx;
+ break;
+ case TX: selectedChannel = selectedChannelTx;
+ break;
+ default: selectedChannel = 0xff;
+ }
+
+ if( selectedChannel >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_comedi: co_pcican_configure_selected_channel(): invalid channel selected\n");
+ return -1;
+ }
+
+ memset( opcmd, 0x00, sizeof(opcmd) );
+ opcmd[0] = selectedChannel;
+ opcmd[1] = TranslateBaudRate( board->baudrate );
+
+ memset( &insn, 0x00, sizeof(insn) );
+ insn.insn = INSN_CONFIG;
+ insn.n = 1;
+ insn.data = (void*)opcmd;
+
+ if( selectedChannel < 2 )
+ insn.subdev = 0;
+ else
+ insn.subdev = 2;
+
+ insn.unused[0] = opcode; /* in use for CO-PCICAN */
+
+ return comedi_do_insn( dev, &insn );
+}
+
+/*********functions which permit to communicate with the board****************/
+UNS8 canReceive_driver( CAN_HANDLE fd0, Message *m )
+{
+ MESSAGE_T canmsg;
+ comedi_insn insn;
+ UNS8 ret = 0;
+ comedi_t *dev = (comedi_t*)fd0;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: canReceive_driver(): dev is NULL\n");
+ return 1;
+ }
+
+ if( selectedChannelRx >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_comedi: canReceive_driver(): invalid channel selected\n");
+ return 1;
+ }
+
+ if( m == NULL )
+ {
+ MSG("can_copcican_comedi: canReceive_driver(): message is NULL\n");
+ return 1;
+ }
+
+ memset( &canmsg, 0x00, sizeof(MESSAGE_T) );
+
+ memset( &insn, 0x00, sizeof(insn) );
+ insn.insn = INSN_READ;
+ insn.n = 1;
+ insn.data = (void*)&canmsg;
+
+ if( selectedChannelRx < 2 )
+ insn.subdev = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_DI, 0);
+ else
+ insn.subdev = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_DI, 2);
+
+ insn.unused[1] = selectedChannelRx; /* in use for CO-PCICAN */
+ insn.unused[2] = sizeof(MESSAGE_T); /* in use for CO-PCICAN */
+
+ comedi_do_insn( dev, &insn );
+
+ if( canmsg.timestamp_lo == 0 )
+ {
+ memset( m, 0x00, sizeof(Message) );
+
+ m->cob_id = 0xffff; /* set to invalid so nothing happens */
+ }
+ else
+ {
+ m->len = canmsg.size;
+ m->cob_id = canmsg.id;
+ m->rtr = canmsg.type & MSG_RTR;
+
+ if( !m->rtr )
+ {
+ /* this is for safety */
+ if( m->len > 8 )
+ m->len = 8;
+
+ memcpy( m->data, canmsg.data, m->len);
+ }
+ }
+
+ return ret;
+}
+
+/***************************************************************************/
+UNS8 canSend_driver( CAN_HANDLE fd0, Message *m )
+{
+ MESSAGE_T canmsg;
+ comedi_insn insn;
+ UNS8 ret = 0;
+ comedi_t *dev = (comedi_t*)fd0;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: canSend_driver(): dev is NULL\n");
+ return 1;
+ }
+
+ if( selectedChannelTx >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_comedi: canSend_driver(): invalid channel selected\n");
+ return 1;
+ }
+
+ if( m == NULL )
+ {
+ MSG("can_copcican_comedi: canSend_driver(): message is NULL\n");
+ return 1;
+ }
+
+ memset( &canmsg, 0x00, sizeof(MESSAGE_T) );
+ canmsg.size = m->len;
+ canmsg.id = m->cob_id;
+
+ if( canmsg.id >= 0x800 )
+ canmsg.type |= MSG_EXT;
+
+ if( m->rtr )
+ {
+ canmsg.type |= MSG_RTR;
+ }
+ else
+ {
+ /* this is for safety */
+ if( canmsg.size > 8 )
+ canmsg.size = 8;
+
+ memcpy( canmsg.data, m->data, canmsg.size);
+ }
+
+ memset( &insn, 0x00, sizeof(insn) );
+ insn.insn = INSN_WRITE;
+ insn.n = 1;
+ insn.data = (void*)&canmsg;
+
+ if( selectedChannelTx < 2 )
+ insn.subdev = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_DO, 0);
+ else
+ insn.subdev = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_DO, 2);
+
+ insn.unused[1] = selectedChannelTx; /* in use for CO-PCICAN */
+ insn.unused[2] = sizeof(MESSAGE_T) - sizeof(unsigned long); /* in use for CO-PCICAN, no timestamp for tx */
+
+ if( comedi_do_insn( dev, &insn ) < 0 )
+ ret = 1;
+
+ return ret;
+}
+
+/***************************************************************************/
+CAN_HANDLE canOpen_driver( s_BOARD *board )
+{
+ comedi_t *dev;
+
+ if( board == NULL )
+ {
+ MSG("can_copcican_comedi: canOpen_driver(): board is NULL\n");
+ return NULL;
+ }
+
+ if( board->busname == NULL )
+ {
+ MSG("can_copcican_comedi: canOpen_driver(): busname is NULL\n");
+ return NULL;
+ }
+
+ dev = comedi_open( board->busname );
+
+ /*MSG("can_copcican_comedi: canOpen_driver(): handle is 0x%08x\n", (unsigned int)dev);*/
+
+ return dev;
+}
+
+/***************************************************************************/
+int canClose_driver( CAN_HANDLE fd0 )
+{
+ comedi_t *dev = (comedi_t*)fd0;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: canClose_driver(): dev is NULL\n");
+ return 1;
+ }
+
+ comedi_close( dev );
+
+ selectedChannelRx = 0;
+ selectedChannelTx = 0;
+
+ return 0;
+}
+
+/***************************************************************************/
+UNS8 canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud )
+{
+ s_BOARD board;
+ UNS8 ret = 0;
+ comedi_t *dev = (comedi_t*)fd0;
+
+ if( dev == NULL )
+ {
+ MSG("can_copcican_comedi: canChangeBaudRate_driver(): dev is NULL\n");
+ return 1;
+ }
+
+ if( baud == NULL )
+ {
+ MSG("can_copcican_comedi: canChangeBaudRate_driver(): baud is NULL\n");
+ return 1;
+ }
+
+ memset( &board, 0x00, sizeof(s_BOARD) );
+ board.baudrate = baud;
+
+ if( co_pcican_configure_selected_channel( dev, &board, RX ) < 0 )
+ ret = 1;
+
+ if( co_pcican_configure_selected_channel( dev, &board, TX ) < 0 )
+ ret = 1;
+
+ return ret;
+}
+
+static int init(void)
+{
+ printk("can_copcican_comedi for CanFestival loaded\n");
+
+ return 0;
+}
+
+static void exit(void)
+{
+ printk("can_copcican_comedi unloaded\n");
+}
+
+module_init(init);
+module_exit(exit);
+
+EXPORT_SYMBOL(get_dev_of_port);
+EXPORT_SYMBOL(co_pcican_enter_run_mode);
+EXPORT_SYMBOL(co_pcican_enter_config_mode);
+EXPORT_SYMBOL(co_pcican_select_channel);
+EXPORT_SYMBOL(co_pcican_configure_selected_channel);
+EXPORT_SYMBOL(canOpen_driver);
+EXPORT_SYMBOL(canClose_driver);
+EXPORT_SYMBOL(canSend_driver);
+EXPORT_SYMBOL(canReceive_driver);
+EXPORT_SYMBOL(canChangeBaudRate_driver);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_comedi/co_pcicanops.h Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,63 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ COMEDI interface for CO-PCICAN card.
+*/
+
+#ifndef _CO_PCICANOPS_
+#define _CO_PCICANOPS_
+
+#define NUM_CAN_CHANNELS 4
+
+#define CMDQ_OPC_ENTER_RUN_MODE 0x01
+#define CMDQ_OPC_ENTER_CONFIG_MODE 0x02
+#define CMDQ_OPC_SET_CONFIG_CHANNEL 0xA2
+
+typedef struct message_t
+{
+ unsigned long type;
+ unsigned long size;
+ unsigned long id;
+ unsigned char data[8];
+ unsigned long timestamp_lo;
+ unsigned long timestamp_hi;
+} MESSAGE_T;
+
+/*=============================================================================
+ directions
+ ===========================================================================*/
+#define RX 0
+#define TX 1
+
+/*=============================================================================
+ supported types
+ ===========================================================================*/
+#define MSG_EXT 0x00000001
+#define MSG_RTR 0x00000002
+
+
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_linux/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,70 @@
+#! gmake
+
+#
+# Copyright (C) 2010 Cosateq GmbH & Co.KG
+# http://www.cosateq.com/
+# http://www.scale-rt.com/
+#
+# 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
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER)
+
+OBJS = $(CAN_DRIVER).o
+
+ifeq ($(ENABLE_DLL_DRIVERS),1)
+CFLAGS += -fPIC
+DRIVER = libcanfestival_$(CAN_DRIVER).so
+else
+DRIVER = $(OBJS)
+endif
+
+TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER)
+
+all: driver
+
+driver: $(DRIVER)
+
+%o: %c
+ $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+libcanfestival_$(CAN_DRIVER).so: $(OBJS)
+ $(CC) -shared -Wl,-soname,libcanfestival_$(CAN_DRIVER).so $(CAN_DLL_CFLAGS) -o $@ $<
+
+install: libcanfestival_$(CAN_DRIVER).so
+ 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_copcican_linux/can_copcican_linux.c Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,415 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ CAN driver interface for CO-PCICAN card.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define NEED_PRINT_MESSAGE
+#include "can_driver.h"
+#include "def.h"
+#include "co_pcicanops.h"
+
+/* at the moment not threadsafe :-( */
+static unsigned char selectedChannelRx = 0, selectedChannelTx = 0;
+
+static int TranslateBaudRate( char* optarg )
+{
+ /* values see documentation of CO-PCICAN */
+ if( !strcmp( optarg, "1M" ) ) return 0;
+ if( !strcmp( optarg, "800K" ) ) return 1;
+ if( !strcmp( optarg, "500K" ) ) return 2;
+ if( !strcmp( optarg, "250K" ) ) return 3;
+ if( !strcmp( optarg, "125K" ) ) return 4;
+ if( !strcmp( optarg, "100K" ) ) return 5;
+ if( !strcmp( optarg, "83.3K" ) ) return 6;
+ if( !strcmp( optarg, "10K" ) ) return 7;
+
+ return -1;
+}
+
+/*********CO-PCICAN specific functions to communicate with the board**********/
+typedef struct
+{
+ char used;
+ CAN_HANDLE fd;
+ void* receiveTask;
+ void* d;
+} CANPort; /* taken from drivers/unix.c */
+
+int get_fd_of_port( CAN_PORT port )
+{
+ CANPort *thisPort = (CANPort*)port;
+ CAN_HANDLE thisHandle;
+ int *pfd;
+
+ if( thisPort == NULL )
+ {
+ MSG("can_copcican_linux: get_fd_of_port(): thisPort is NULL\n");
+ return -1;
+ }
+
+ thisHandle = thisPort->fd;
+
+ if( thisHandle == NULL )
+ {
+ MSG("can_copcican_linux: get_fd_of_port(): thisHandle is NULL\n");
+ return -1;
+ }
+
+ pfd = (int*)thisHandle;
+
+ /*MSG("can_copcican_linux: get_fd_of_port(): handle is %d\n", *pfd);*/
+
+ return *pfd;
+}
+
+int co_pcican_enter_run_mode( const int fd )
+{
+ co_pcican_config_t board_config;
+
+ if( fd < 0 )
+ {
+ MSG("can_copcican_linux: co_pcican_enter_run_mode(): invalid file descriptor\n");
+ return -1;
+ }
+
+ memset( &board_config, 0x00, sizeof(co_pcican_config_t) );
+ board_config.opcode = CMDQ_OPC_ENTER_RUN_MODE;
+
+ return ioctl( fd, CAN_CONFIG, &board_config );
+}
+
+int co_pcican_enter_config_mode( const int fd )
+{
+ co_pcican_config_t board_config;
+
+ if( fd < 0 )
+ {
+ MSG("can_copcican_linux: co_pcican_enter_config_mode(): invalid file descriptor\n");
+ return -1;
+ }
+
+ memset( &board_config, 0x00, sizeof(co_pcican_config_t) );
+ board_config.opcode = CMDQ_OPC_ENTER_CONFIG_MODE;
+
+ return ioctl( fd, CAN_CONFIG, &board_config );
+}
+
+int co_pcican_select_channel( const unsigned char channel, const unsigned int direction )
+{
+ if( channel >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_linux: co_pcican_select_channel(): invalid channel\n");
+ return -1;
+ }
+
+ /* at the moment not threadsafe :-( */
+ switch( direction )
+ {
+ case RX: selectedChannelRx = channel;
+ break;
+ case TX: selectedChannelTx = channel;
+ break;
+ default: return -1;
+ }
+
+ return 0;
+}
+
+int co_pcican_configure_selected_channel( const int fd, s_BOARD *board, const unsigned int direction )
+{
+ co_pcican_config_t board_config;
+ unsigned int selectedChannel;
+
+ if( fd < 0 )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): invalid file descriptor\n");
+ return -1;
+ }
+
+ if( board == NULL )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): board is NULL\n");
+ return -1;
+ }
+
+ if( board->baudrate == NULL )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): baudrate is NULL\n");
+ return -1;
+ }
+
+ switch( direction )
+ {
+ case RX: selectedChannel = selectedChannelRx;
+ break;
+ case TX: selectedChannel = selectedChannelTx;
+ break;
+ default: selectedChannel = 0xff;
+ }
+
+ if( selectedChannel >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): invalid channel selected\n");
+ return -1;
+ }
+
+ memset( &board_config, 0x00, sizeof(co_pcican_config_t) );
+ board_config.opcode = CMDQ_OPC_SET_CONFIG_CHANNEL;
+ board_config.param[0] = selectedChannel;
+ board_config.param[1] = TranslateBaudRate( board->baudrate );
+
+ return ioctl( fd, CAN_CONFIG, &board_config );
+}
+
+/*********functions which permit to communicate with the board****************/
+UNS8 canReceive_driver( CAN_HANDLE fd0, Message *m )
+{
+ co_pcican_message_t canmsg;
+ UNS8 ret = 0;
+ int *pfd = (int*)fd0;
+
+ if( pfd == NULL )
+ {
+ MSG("can_copcican_linux: canReceive_driver(): file descriptor is NULL\n");
+ return 1;
+ }
+
+ if( *pfd < 0 )
+ {
+ MSG("can_copcican_linux: canReceive_driver(): invalid file descriptor\n");
+ return 1;
+ }
+
+ if( selectedChannelRx >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_linux: canReceive_driver(): invalid channel selected\n");
+ return 1;
+ }
+
+ if( m == NULL )
+ {
+ MSG("can_copcican_linux: canReceive_driver(): message is NULL\n");
+ return 1;
+ }
+
+ memset( &canmsg, 0x00, sizeof(co_pcican_message_t) );
+ canmsg.channelnum = selectedChannelRx;
+
+ ioctl( *pfd, CAN_READ, &canmsg );
+
+ if( canmsg.timestamp_lo == 0 )
+ {
+ memset( m, 0x00, sizeof(Message) );
+
+ m->cob_id = 0xffff; /* set to invalid so nothing happens */
+ }
+ else
+ {
+ m->len = canmsg.size;
+ m->cob_id = canmsg.id;
+ m->rtr = canmsg.type & MSG_RTR;
+
+ if( !m->rtr )
+ {
+ /* this is for safety */
+ if( m->len > 8 )
+ m->len = 8;
+
+ memcpy( m->data, canmsg.data, m->len);
+ }
+ }
+
+ return ret;
+}
+
+/***************************************************************************/
+UNS8 canSend_driver( CAN_HANDLE fd0, Message *m )
+{
+ co_pcican_message_t canmsg;
+ UNS8 ret = 0;
+ int *pfd = (int*)fd0;
+
+ if( pfd == NULL )
+ {
+ MSG("can_copcican_linux: canSend_driver(): file descriptor is NULL\n");
+ return 1;
+ }
+
+ if( *pfd < 0 )
+ {
+ MSG("can_copcican_linux: canSend_driver(): invalid file descriptor\n");
+ return 1;
+ }
+
+ if( selectedChannelTx >= NUM_CAN_CHANNELS )
+ {
+ MSG("can_copcican_linux: canSend_driver(): invalid channel selected\n");
+ return 1;
+ }
+
+ if( m == NULL )
+ {
+ MSG("can_copcican_linux: canSend_driver(): message is NULL\n");
+ return 1;
+ }
+
+ memset( &canmsg, 0x00, sizeof(co_pcican_message_t) );
+ canmsg.channelnum = selectedChannelTx;
+ canmsg.size = m->len;
+ canmsg.id = m->cob_id;
+
+ if( canmsg.id >= 0x800 )
+ canmsg.type |= MSG_EXT;
+
+ if( m->rtr )
+ {
+ canmsg.type |= MSG_RTR;
+ }
+ else
+ {
+ /* this is for safety */
+ if( canmsg.size > 8 )
+ canmsg.size = 8;
+
+ memcpy( canmsg.data, m->data, canmsg.size);
+ }
+
+ if( ioctl( *pfd, CAN_WRITE, &canmsg ) < 0 )
+ ret = 1;
+
+ return ret;
+}
+
+/***************************************************************************/
+CAN_HANDLE canOpen_driver( s_BOARD *board )
+{
+ int *pfd;
+
+ if( board == NULL )
+ {
+ MSG("can_copcican_linux: canOpen_driver(): board is NULL\n");
+ return NULL;
+ }
+
+ if( board->busname == NULL )
+ {
+ MSG("can_copcican_linux: canOpen_driver(): busname is NULL\n");
+ return NULL;
+ }
+
+ /* create dynamically to avoid global variable */
+ pfd = (int*)malloc( sizeof(int) );
+
+ if( pfd == NULL )
+ {
+ MSG("can_copcican_linux: canOpen_driver(): file descriptor is NULL\n");
+ return NULL;
+ }
+
+ *pfd = open( board->busname, O_RDWR, 0 );
+
+ if( *pfd < 0 )
+ {
+ MSG("can_copcican_linux: canOpen_driver(): invalid file descriptor\n");
+
+ /* clear resources if open failed */
+ free( pfd );
+ pfd = NULL;
+ }
+
+ /*MSG("can_copcican_linux: canOpen_driver(): handle is %d\n", *pfd);*/
+
+ return (CAN_HANDLE)pfd;
+}
+
+/***************************************************************************/
+int canClose_driver( CAN_HANDLE fd0 )
+{
+ int *pfd = (int*)fd0;
+
+ if( pfd == NULL )
+ {
+ MSG("can_copcican_linux: canClose_driver(): file descriptor is NULL\n");
+ return -1;
+ }
+
+ if( *pfd < 0 )
+ {
+ MSG("can_copcican_linux: canClose_driver(): invalid file descriptor\n");
+ return -1;
+ }
+
+ close( *pfd );
+ free( pfd );
+ pfd = NULL;
+
+ selectedChannelRx = 0;
+ selectedChannelTx = 0;
+
+ return 0;
+}
+
+/***************************************************************************/
+UNS8 canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud )
+{
+ s_BOARD board;
+ UNS8 ret = 0;
+ int *pfd = (int*)fd0;
+
+ if( pfd == NULL )
+ {
+ MSG("can_copcican_linux: canChangeBaudRate_driver(): file descriptor is NULL\n");
+ return 1;
+ }
+
+ if( *pfd < 0 )
+ {
+ MSG("can_copcican_linux: canChangeBaudRate_driver(): invalid file descriptor\n");
+ return 1;
+ }
+
+ if( baud == NULL )
+ {
+ MSG("can_copcican_linux: canChangeBaudRate_driver(): baud is NULL\n");
+ return 1;
+ }
+
+ memset( &board, 0x00, sizeof(s_BOARD) );
+ board.baudrate = baud;
+
+ if( co_pcican_configure_selected_channel( *pfd, &board, RX ) < 0 )
+ ret = 1;
+
+ if( co_pcican_configure_selected_channel( *pfd, &board, TX ) < 0 )
+ ret = 1;
+
+ return ret;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_linux/co_pcicanops.h Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,77 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ CAN driver interface for CO-PCICAN card.
+*/
+
+#ifndef _CO_PCICANOPS_
+#define _CO_PCICANOPS_
+
+#define NUM_CAN_CHANNELS 4
+
+#define CMDQ_OPC_ENTER_RUN_MODE 0x01
+#define CMDQ_OPC_ENTER_CONFIG_MODE 0x02
+#define CMDQ_OPC_SET_CONFIG_CHANNEL 0xA2
+
+typedef struct
+{
+ unsigned char opcode;
+ unsigned long param[15];
+} co_pcican_config_t;
+
+typedef struct
+{
+ unsigned char channelnum;
+ unsigned long type;
+ unsigned long size;
+ unsigned long id;
+ unsigned char data[8];
+ unsigned long timestamp_lo;
+ unsigned long timestamp_hi;
+} co_pcican_message_t;
+
+/*=============================================================================
+ supported operations
+ ===========================================================================*/
+#define CAN_CONFIG 2
+#define CAN_WRITE 3
+#define CAN_READ 4
+
+/*=============================================================================
+ directions
+ ===========================================================================*/
+#define RX 0
+#define TX 1
+
+/*=============================================================================
+ supported types
+ ===========================================================================*/
+#define MSG_EXT 0x00000001
+#define MSG_RTR 0x00000002
+
+
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/ReadMe.txt Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,48 @@
+========================================================================
+ DYNAMIC LINK LIBRARY : can_copcican_win32 Project Overview
+========================================================================
+
+AppWizard has created this can_copcican_win32 DLL for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your can_copcican_win32 application.
+
+
+can_copcican_win32.vcxproj
+ This is the main project file for VC++ projects generated using an Application Wizard.
+ It contains information about the version of Visual C++ that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+can_copcican_win32.vcxproj.filters
+ This is the filters file for VC++ projects generated using an Application Wizard.
+ It contains information about the association between the files in your project
+ and the filters. This association is used in the IDE to show grouping of files with
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+ "Source Files" filter).
+
+can_copcican_win32.cpp
+ This is the main DLL source file.
+
+ When created, this DLL does not export any symbols. As a result, it
+ will not produce a .lib file when it is built. If you wish this project
+ to be a project dependency of some other project, you will either need to
+ add code to export some symbols from the DLL so that an export library
+ will be produced, or you can set the Ignore Input Library property to Yes
+ on the General propert page of the Linker folder in the project's Property
+ Pages dialog box.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named can_copcican_win32.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/can_copcican_win32.cpp Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,249 @@
+// can_copcican_win32.cpp : Defines the exported functions for the DLL application.
+//
+
+
+#include "stdafx.h"
+
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ CAN driver interface for CO-PCICAN card.
+*/
+
+#include <stdio.h>
+//#include <unistd.h>
+#include <fcntl.h>
+
+//#define NEED_PRINT_MESSAGE
+static int initdone = 0;
+
+inline void * maskDevID(int devId){ return ((void*)( (devId & 0x0000000F) | 0xC05A0000)); }
+inline int unmaskDevID(void * Ptr){ return ((int)((int)Ptr & 0x0000000F)); }
+
+/* at the moment not threadsafe :-( */
+static unsigned char selectedChannelRx = 1, selectedChannelTx = 1;
+
+static cosateq::devices::can::co_baudrate_t TranslateBaudRate( char* optarg )
+{
+ /* values see documentation of CO-PCICAN */
+ if( !strcmp( optarg, "1M" ) ) return cosateq::devices::can::CO_BAUD_1M;
+ if( !strcmp( optarg, "800K" ) ) return cosateq::devices::can::CO_BAUD_800k;
+ if( !strcmp( optarg, "500K" ) ) return cosateq::devices::can::CO_BAUD_500k;
+ if( !strcmp( optarg, "250K" ) ) return cosateq::devices::can::CO_BAUD_250k;
+ if( !strcmp( optarg, "125K" ) ) return cosateq::devices::can::CO_BAUD_125k;
+ if( !strcmp( optarg, "100K" ) ) return cosateq::devices::can::CO_BAUD_100k;
+ if( !strcmp( optarg, "83.3K" ) ) return cosateq::devices::can::CO_BAUD_83k;
+ if( !strcmp( optarg, "10K" ) ) return cosateq::devices::can::CO_BAUD_10k;
+
+ return (cosateq::devices::can::co_baudrate_t)-1;
+}
+
+int co_pcican_select_channel( const unsigned char channel, const unsigned int direction )
+{
+ if( channel >= CHANNELS )
+ {
+ MSG("can_copcican_linux: co_pcican_select_channel(): invalid channel\n");
+ return -1;
+ }
+
+ /* at the moment not threadsafe :-( */
+ switch( direction )
+ {
+ case cosateq::devices::can::CO_CAN_RX: selectedChannelRx = channel;
+ break;
+ case cosateq::devices::can::CO_CAN_TX: selectedChannelTx = channel;
+ break;
+ default: return -1;
+ }
+
+ return 0;
+}
+
+int co_pcican_configure_selected_channel( const int fd, s_BOARD *board, const unsigned int direction )
+{
+ unsigned int selectedChannel;
+ int ret = 0;
+
+ if( fd < 0 )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): invalid file descriptor\n");
+ return -1;
+ }
+
+ if( board == NULL )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): board is NULL\n");
+ return -1;
+ }
+
+ if( board->baudrate == NULL )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): baudrate is NULL\n");
+ return -1;
+ }
+
+ switch( direction )
+ {
+ case cosateq::devices::can::CO_CAN_RX: selectedChannel = selectedChannelRx;
+ break;
+ case cosateq::devices::can::CO_CAN_TX: selectedChannel = selectedChannelTx;
+ break;
+ default: selectedChannel = 0xff;
+ }
+
+ if( selectedChannel >= CHANNELS )
+ {
+ MSG("can_copcican_linux: co_pcican_configure_selected_channel(): invalid channel selected\n");
+ return -1;
+ }
+
+ ret = can_setChannelConfig( TranslateBaudRate( board->baudrate ),0x0,unmaskDevID((void*)fd),selectedChannel);
+ if ( ret != 0 ) {
+ can_enterRunMode(unmaskDevID((void*)fd),selectedChannel/2);
+ return -ret;
+ }else{
+ ret = can_setIrqMode(unmaskDevID((void*)fd),selectedChannel);
+ can_enterRunMode(unmaskDevID((void*)fd),selectedChannel/2);
+ }
+ return ret;
+}
+
+/*********functions which permit to communicate with the board****************/
+
+UNS8 __stdcall canReceive_driver( CAN_HANDLE fd0, Message *m )
+{
+ cosateq::devices::can::co_can_packet_t p;
+ int ret = 0;
+
+ if ( !m )
+ return 0;
+
+ memset(&p,0,sizeof(cosateq::devices::can::co_can_packet_t));
+ ret = can_receive(&p,unmaskDevID(fd0),selectedChannelRx);
+ //printf("rec: %d\n",ret);
+ if ( ret != 0 )
+ return 1;
+
+ //printf("rec2: %d\n",ret);
+ if ( p.size > 8 )
+ p.size = 8;
+
+ if ( !(p.type & MSG_RTR ) )
+ memcpy(m->data,p.data,p.size);
+
+ m->cob_id = p.id;
+ m->len = p.size;
+ m->rtr = p.type & MSG_RTR;
+
+ return 0;
+}
+
+/***************************************************************************/
+
+UNS8 __stdcall canSend_driver( CAN_HANDLE fd0, Message *m )
+{
+ cosateq::devices::can::co_can_packet_t p;
+
+ if ( !m )
+ return 0;
+ memset(&p,0,sizeof(cosateq::devices::can::co_can_packet_t));
+ p.id = m->cob_id;
+ p.size = (m->len > 8) ? 8 : m->len;
+ p.type = ( m->rtr ) ? 0x2:0x0;
+ if ( p.id > 0x800 )
+ p.type |= MSG_EXT;
+ memcpy(p.data,m->data,p.size);
+
+ return can_send(&p,unmaskDevID(fd0),selectedChannelTx);
+}
+
+
+
+/***************************************************************************/
+
+UNS8 __stdcall canChangeBaudRate_driver( CAN_HANDLE fd0, char* baud )
+{
+ UNS8 ret = 0;
+
+ ret = can_enterCfgMode(unmaskDevID(fd0),0);
+ if ( ret != 0)
+ MSG("Enter config mode for Channelpair 0 failed in Function %s! Error: %d\n",__FUNCTION__,ret);
+ ret = can_enterCfgMode(unmaskDevID(fd0),1);
+ if ( ret != 0)
+ MSG("Enter config mode for Channelpair 1 failed in Function %s! Error: %d\n",__FUNCTION__,ret);
+
+ for ( int i = 0; i < 4; i++ ) {
+ ret = can_setChannelConfig(TranslateBaudRate(baud),0x0,unmaskDevID(fd0),i);
+ if ( ret != 0)
+ MSG("Set config for channel %d failed in Function %s! Error: %d\n",i,__FUNCTION__,ret);
+ can_setIrqMode(unmaskDevID(fd0),i);
+ }
+ ret = can_enterRunMode(unmaskDevID(fd0),0);
+ if ( ret != 0)
+ MSG("Enter run mode for Channelpair 1 failed in Function %s! Error: %d\n",__FUNCTION__,ret);
+
+ ret = can_enterRunMode(unmaskDevID(fd0),1);
+ if ( ret != 0)
+ MSG("Enter run mode for Channelpair 1 failed in Function %s! Error: %d\n",__FUNCTION__,ret);
+
+ return ret;
+}
+
+CAN_HANDLE __stdcall canOpen_driver( s_BOARD *board )
+{
+ int ret = 0;
+ int devId = 0;
+ if ( !board )
+ return NULL;
+ if ( !board->busname )
+ return NULL;
+ //TODO find out how boardname resolves
+
+ //printf("BOARD: 0x%x %s\n",board,board->busname);
+ //sscanf_s(board->busname,"%d",&devId);
+
+ if ( devId < 0 || devId > 15 )
+ return NULL;
+
+ //return (can_HANDLE)NULL;
+ if ( !initdone ) {
+ can_init();
+ initdone = 1;
+ }
+
+ ret = can_open(devId);
+ if ( ret < 0 )
+ return (CAN_HANDLE)NULL;
+
+ canChangeBaudRate_driver( maskDevID(devId),board->baudrate );
+
+ return maskDevID(devId);
+}
+
+int __stdcall canClose_driver(CAN_HANDLE fd0 )
+{
+ return can_close(unmaskDevID(fd0));
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/can_copcican_win32.def Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,28 @@
+; This file is part of CanFestival, a library implementing CanOpen Stack.
+;
+; CanFestival Copyright (C): Edouard TISSERANT and Francis DUPIN
+; CanFestival Win32 port Copyright (C) 2007 Leonid Tochinski, ChattenAssociates, Inc.
+;
+; 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
+
+LIBRARY can_copcican_win32
+
+EXPORTS
+ canReceive_driver
+ canSend_driver
+ canOpen_driver
+ canClose_driver
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/can_copcican_win32.vcxproj Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A18C416F-3CBB-4744-BA24-FA5C5F3CBE0D}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>can_copcican_win32</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CAN_COPCICAN_WIN32_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)\include\win32;$(SolutionDir)\..\driver_windows\Cosateq_4Port_CAN_SDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>$(SolutionDir)\..\driver_windows\Cosateq_4Port_CAN_SDK\lib\co_can_lib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ModuleDefinitionFile>can_copcican_win32.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CAN_COPCICAN_WIN32_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <ModuleDefinitionFile>can_copcican_win32.def</ModuleDefinitionFile>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="can_copcican_win32.def" />
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="can_copcican_win32.cpp" />
+ <ClCompile Include="dllmain.cpp">
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ </PrecompiledHeader>
+ <CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ </PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="stdafx.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ </ClCompile>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/can_copcican_win32.vcxproj.filters Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ <None Include="can_copcican_win32.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="targetver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="can_copcican_win32.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="dllmain.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/can_copcican_win32.vcxproj.user Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+</Project>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/dllmain.cpp Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,22 @@
+// dllmain.cpp : Defines the entry point for the DLL application.
+#include "stdafx.h"
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ case DLL_THREAD_ATTACH:
+
+ break;
+ case DLL_THREAD_DETACH:
+ case DLL_PROCESS_DETACH:
+
+ break;
+ }
+ return TRUE;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/stdafx.cpp Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// can_copcican_win32.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/stdafx.h Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,20 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+
+//#include "co_can.h"
+#include "public.h"
+#include "can_driver.h"
+#include "co_can_cinterface.h"
+
+// TODO: reference additional headers your program requires here
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_copcican_win32/targetver.h Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>
--- a/drivers/timers_kernel/timers_kernel.c Fri Nov 12 22:02:32 2010 +0100
+++ b/drivers/timers_kernel/timers_kernel.c Fri Nov 12 22:24:06 2010 +0100
@@ -1,5 +1,5 @@
/*
-This file is part of CanFestival, a library implementing CanOpen Stack.
+This file is part of CanFestival, a library implementing CanOpen Stack.
Copyright (C): Edouard TISSERANT and Francis DUPIN
@@ -111,5 +111,9 @@
void WaitReceiveTaskEnd(TASK_HANDLE *Thread)
{
- force_sig (SIGTERM, *Thread);
+ /* join thread here because force_sig() does not work */
+ while((*Thread)->state <= 0)
+ {
+ ; /* >0 means stopped */
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/timers_kernel_xeno/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,59 @@
+#! gmake
+
+#
+# Copyright (C) 2010 Cosateq GmbH & Co.KG
+# http://www.cosateq.com/
+# http://www.scale-rt.com/
+#
+# 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
+#
+
+#ifneq ($(KERNELRELEASE),)
+# Kbuild part of Makefile
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+
+EXTRA_CFLAGS := -I$(src)/../../include
+EXTRA_CFLAGS += -I$(src)/../../include/$(TARGET)
+EXTRA_CFLAGS += -I$(src)/../../include/$(CAN_DRIVER)
+EXTRA_CFLAGS += -I$(src)/../../include/$(TIMERS_DRIVER)
+EXTRA_CFLAGS += SUB_PROG_CFLAGS
+
+obj-m := $(TIMERS_DRIVER).o
+
+#else
+# Normal Makefile
+PREFIX = SUB_PREFIX
+KERNELDIR := SUB_KERNELDIR
+
+all: driver
+
+driver:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
+
+clean:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) clean
+ rm -f Module.symvers
+
+mrproper: clean
+
+install:
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/timers_kernel_xeno/timers_kernel_xeno.c Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,288 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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 <asm/current.h>
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/sem.h>
+#include <native/mutex.h>
+#include <native/cond.h>
+#include <native/alarm.h>
+
+#include "applicfg.h"
+#include "can_driver.h"
+#include "timer.h"
+
+#define TIMERLOOP_TASK_CREATED 1
+
+TimerCallback_t exitall;
+
+RT_MUTEX condition_mutex;
+RT_SEM CanFestival_mutex;
+RT_SEM control_task;
+RT_COND timer_set;
+RT_TASK timerloop_task;
+
+RTIME last_time_read;
+RTIME last_occured_alarm;
+RTIME last_timeout_set;
+
+int stop_timer = 0;
+
+/**
+ * Init Mutex, Semaphores and Condition variable
+ */
+void TimerInit(void)
+{
+ int ret = 0;
+ char taskname[32];
+
+ // lock process in to RAM
+ //mlockall(MCL_CURRENT | MCL_FUTURE);
+
+ snprintf(taskname, sizeof(taskname), "S1-%d", current->pid);
+ rt_sem_create(&CanFestival_mutex, taskname, 1, S_FIFO);
+
+ snprintf(taskname, sizeof(taskname), "S2-%d", current->pid);
+ rt_sem_create(&control_task, taskname, 0, S_FIFO);
+
+ snprintf(taskname, sizeof(taskname), "M1-%d", current->pid);
+ rt_mutex_create(&condition_mutex, taskname);
+
+ snprintf(taskname, sizeof(taskname), "C1-%d", current->pid);
+ rt_cond_create(&timer_set, taskname);
+}
+
+/**
+ * Stop Timer Task
+ * @param exitfunction
+ */
+void StopTimerLoop(TimerCallback_t exitfunction)
+{
+ exitall = exitfunction;
+ stop_timer = 1;
+ rt_cond_signal(&timer_set);
+}
+
+void cleanup_all(void)
+{
+ /* normally this will fail with a non-periodic task that has already ended at this time */
+ if (rt_task_suspend(&timerloop_task) != 0){
+ printk("Failed to join with Timerloop task\n");
+ }
+ rt_task_delete(&timerloop_task);
+}
+
+/**
+ * Clean all Semaphores, mutex, condition variable and main task
+ */
+void TimerCleanup(void)
+{
+ rt_sem_delete(&CanFestival_mutex);
+ rt_mutex_delete(&condition_mutex);
+ rt_cond_delete(&timer_set);
+ rt_sem_delete(&control_task);
+
+ /* normally this will fail with a non-periodic task that has already ended at this time */
+ if (rt_task_suspend(&timerloop_task) != 0){
+ printk("Failed to join with Timerloop task\n");
+ }
+ rt_task_delete(&timerloop_task);
+}
+
+/**
+ * Take a semaphore
+ */
+void EnterMutex(void)
+{
+ rt_sem_p(&CanFestival_mutex, TM_INFINITE);
+}
+
+/**
+ * Signaling a semaphore
+ */
+void LeaveMutex(void)
+{
+ rt_sem_v(&CanFestival_mutex);
+}
+
+static TimerCallback_t init_callback;
+
+/**
+ * Timer Task
+ */
+void timerloop_task_proc(void *arg)
+{
+ int ret = 0;
+
+ getElapsedTime();
+ last_timeout_set = 0;
+ last_occured_alarm = last_time_read;
+
+ /* trigger first alarm */
+ SetAlarm(NULL, 0, init_callback, 0, 0);
+ RTIME current_time;
+ RTIME real_alarm;
+ do{
+
+ rt_mutex_acquire(&condition_mutex, TM_INFINITE);
+ if(last_timeout_set == TIMEVAL_MAX)
+ {
+ ret = rt_cond_wait(
+ &timer_set,
+ &condition_mutex,
+ TM_INFINITE
+ ); /* Then sleep until next message*/
+ rt_mutex_release(&condition_mutex);
+ }else{
+ current_time = rt_timer_read();
+ real_alarm = last_time_read + last_timeout_set;
+ ret = rt_cond_wait( /* sleep until next deadline */
+ &timer_set,
+ &condition_mutex,
+ (real_alarm - current_time)); /* else alarm consider expired */
+ if(ret == -ETIMEDOUT){
+ last_occured_alarm = real_alarm;
+ rt_mutex_release(&condition_mutex);
+ EnterMutex();
+ TimeDispatch();
+ LeaveMutex();
+ }else{
+ rt_mutex_release(&condition_mutex);
+ }
+ }
+ }while ((ret == 0 || ret == -EINTR || ret == -ETIMEDOUT) && !stop_timer);
+
+ if(exitall){
+ EnterMutex();
+ exitall(NULL,0);
+ LeaveMutex();
+ }
+}
+
+/**
+ * Create the Timer Task
+ * @param _init_callback
+ */
+void StartTimerLoop(TimerCallback_t _init_callback)
+{
+ int ret = 0;
+ stop_timer = 0;
+ init_callback = _init_callback;
+
+ char taskname[32];
+ snprintf(taskname, sizeof(taskname), "timerloop-%d", current->pid);
+
+ /* create timerloop_task */
+ ret = rt_task_create(&timerloop_task, taskname, 0, 50, 0); /* T_JOINABLE only in user space */
+ if (ret) {
+ printk("Failed to create timerloop_task, code %d\n",ret);
+ return;
+ }
+
+ /* start timerloop_task */
+ ret = rt_task_start(&timerloop_task,&timerloop_task_proc,NULL);
+ if (ret) {
+ printk("Failed to start timerloop_task, code %u\n",ret);
+ goto error;
+ }
+
+ return;
+
+error:
+ cleanup_all();
+}
+
+/**
+ * Create the CAN Receiver Task
+ * @param fd0 CAN port
+ * @param *ReceiveLoop_task CAN receiver task
+ * @param *ReceiveLoop_task_proc CAN receiver function
+ */
+void CreateReceiveTask(CAN_PORT fd0, TASK_HANDLE *ReceiveLoop_task, void* ReceiveLoop_task_proc)
+{
+ int ret;
+ static int id = 0;
+ char taskname[32];
+ snprintf(taskname, sizeof(taskname), "canloop%d-%d", id, current->pid);
+ id++;
+
+ /* create ReceiveLoop_task */
+ ret = rt_task_create(ReceiveLoop_task,taskname,0,50,0); /* T_JOINABLE only in user space */
+ if (ret) {
+ printk("Failed to create ReceiveLoop_task number %d, code %d\n", id, ret);
+ return;
+ }
+
+ /* periodic task for Xenomai kernel realtime */
+ rt_task_set_periodic(ReceiveLoop_task, 0, 1 * 1000 * 1000); /* 1ms */
+
+ /* start ReceiveLoop_task */
+ ret = rt_task_start(ReceiveLoop_task, ReceiveLoop_task_proc,(void*)fd0);
+ if (ret) {
+ printk("Failed to start ReceiveLoop_task number %d, code %d\n", id, ret);
+ return;
+ }
+ rt_sem_v(&control_task);
+}
+
+/**
+ * Wait for the CAN Receiver Task end
+ * @param *ReceiveLoop_task CAN receiver thread
+ */
+void WaitReceiveTaskEnd(TASK_HANDLE *ReceiveLoop_task)
+{
+ /* normally this will fail with a non-periodic task that has already ended at this time */
+ if (rt_task_suspend(ReceiveLoop_task) != 0){
+ printk("Failed to join with Receive task\n");
+ }
+ rt_task_delete(ReceiveLoop_task);
+}
+
+/**
+ * Set timer for the next wakeup
+ * @param value
+ */
+void setTimer(TIMEVAL value)
+{
+ rt_mutex_acquire(&condition_mutex, TM_INFINITE);
+ last_timeout_set = value;
+ rt_mutex_release(&condition_mutex);
+ rt_cond_signal(&timer_set);
+}
+
+/**
+ * Get the elapsed time since the last alarm
+ * @return a time in nanoseconds
+ */
+TIMEVAL getElapsedTime(void)
+{
+ RTIME res;
+ rt_mutex_acquire(&condition_mutex, TM_INFINITE);
+ last_time_read = rt_timer_read();
+ res = last_time_read - last_occured_alarm;
+ rt_mutex_release(&condition_mutex);
+ return res;
+}
--- a/drivers/timers_win32/timers_win32.c Fri Nov 12 22:02:32 2010 +0100
+++ b/drivers/timers_win32/timers_win32.c Fri Nov 12 22:24:06 2010 +0100
@@ -77,7 +77,11 @@
CloseHandle(*Thread);
}
+#if !defined(WIN32) || defined(__CYGWIN__)
int TimerThreadLoop(void)
+#else
+DWORD TimerThreadLoop(LPVOID arg)
+#endif
{
--- a/drivers/unix/Makefile.in Fri Nov 12 22:02:32 2010 +0100
+++ b/drivers/unix/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -2,24 +2,24 @@
#
# 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
-#
+#
#ifneq ($(KERNELRELEASE),)
# Kbuild part of Makefile
@@ -56,6 +56,13 @@
all: driver
ifeq ($(TIMERS_DRIVER), timers_kernel)
+USE_KERNEL_TIMER = true
+endif
+ifeq ($(TIMERS_DRIVER), timers_kernel_xeno)
+USE_KERNEL_TIMER = true
+endif
+
+ifeq ($(USE_KERNEL_TIMER), true)
OBJS := $(shell echo $(OBJS) | sed "s:$(TARGET)_::g")
EXTRA_CFLAGS := $(shell echo $(INCLUDES) | sed "s:-I:-I$(src)/:g")
EXTRA_CFLAGS += $(PROG_CFLAGS)
@@ -75,7 +82,7 @@
rm -f Module.symvers
install:
-
+
else
CFLAGS = SUB_OPT_CFLAGS
--- a/drivers/unix/unix.c Fri Nov 12 22:02:32 2010 +0100
+++ b/drivers/unix/unix.c Fri Nov 12 22:24:06 2010 +0100
@@ -1,5 +1,5 @@
/*
-This file is part of CanFestival, a library implementing CanOpen Stack.
+This file is part of CanFestival, a library implementing CanOpen Stack.
Copyright (C): Edouard TISSERANT and Francis DUPIN
@@ -26,6 +26,7 @@
#else
#include <linux/module.h>
#endif
+#include <linux/delay.h>
#ifndef NOT_USE_DYNAMIC_LOADING
#define DLL_CALL(funcname) (* funcname##_driver)
@@ -95,7 +96,7 @@
{
LIB_HANDLE handle = NULL;
char *error;
-
+
if(handle==NULL)
{
@@ -106,7 +107,7 @@
fprintf (stderr, "%s\n", dlerror());
return NULL;
}
-
+
/*Get function ptr*/
DLSYM(canReceive)
DLSYM(canSend)
@@ -142,7 +143,7 @@
res = DLL_CALL(canSend)(((CANPort*)port)->fd, m);
//EnterMutex();
return res; // OK
- }
+ }
return 1; // NOT OK
}
@@ -161,6 +162,13 @@
EnterMutex();
canDispatch(((CANPort*)port)->d, &m);
LeaveMutex();
+
+#ifdef __KERNEL__
+#ifdef USE_XENO
+ /* periodic task for Xenomai kernel realtime */
+ rt_task_wait_period(NULL);
+#endif
+#endif
}
}
@@ -178,19 +186,19 @@
if(!canports[i].used)
break;
}
-
+
#ifndef NOT_USE_DYNAMIC_LOADING
if (&DLL_CALL(canOpen)==NULL) {
fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
return NULL;
}
-#endif
+#endif
CAN_HANDLE fd0 = DLL_CALL(canOpen)(board);
if(fd0){
canports[i].used = 1;
canports[i].fd = fd0;
canports[i].d = d;
- d->canHandle = (CAN_PORT)&canports[i];
+ d->canHandle = (CAN_PORT)&canports[i];
CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
return (CAN_PORT)&canports[i];
}else{
@@ -207,17 +215,18 @@
int canClose(CO_Data * d)
{
UNS8 res;
-
+
((CANPort*)d->canHandle)->used = 0;
CANPort* tmp = (CANPort*)d->canHandle;
- d->canHandle = NULL;
-
+
+ // kill receiver task before port is closed and handle set to NULL
+ WaitReceiveTaskEnd(&tmp->receiveTask);
+
// close CAN port
res = DLL_CALL(canClose)(tmp->fd);
- // kill receiver task
- WaitReceiveTaskEnd(&tmp->receiveTask);
-
+ d->canHandle = NULL;
+
return res;
}
@@ -236,7 +245,7 @@
res = DLL_CALL(canChangeBaudRate)(((CANPort*)port)->fd, baud);
//EnterMutex();
return res; // OK
- }
+ }
return 1; // NOT OK
}
--- a/drivers/win32/win32.c Fri Nov 12 22:02:32 2010 +0100
+++ b/drivers/win32/win32.c Fri Nov 12 22:24:06 2010 +0100
@@ -190,16 +190,18 @@
}
tmp = (CANPort*)d->canHandle;
- d->canHandle = NULL;
if(tmp)
{
+ // kill receiver task before port is closed and handle set to NULL
+ WaitReceiveTaskEnd(&tmp->receiveTask);
+
// close CAN port
res = m_canClose(tmp->fd);
-
- // kill receiver task
- WaitReceiveTaskEnd(&tmp->receiveTask);
- }
+ }
+
+ d->canHandle = NULL;
+
return res;
}
--- a/examples/TestMasterSlave/TestMasterSlave.c Fri Nov 12 22:02:32 2010 +0100
+++ b/examples/TestMasterSlave/TestMasterSlave.c Fri Nov 12 22:24:06 2010 +0100
@@ -189,8 +189,10 @@
/* install signal handler for manual break */
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
+#endif
+ // Also Windows needs to initialize the Timer!
+ // Moving this line into the ifndef leads to a lethal crash!
TimerInit();
-#endif
#ifndef NOT_USE_DYNAMIC_LOADING
if (LoadCanDriver(LibraryPath) == NULL)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/test_copcican_comedi/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,66 @@
+#! gmake
+
+#
+# Copyright (C) 2010 Cosateq GmbH & Co.KG
+# http://www.cosateq.com/
+# http://www.scale-rt.com/
+#
+# 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
+#
+
+#ifneq ($(KERNELRELEASE),)
+# Kbuild part of Makefile
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+
+EXTRA_CFLAGS := -I$(src)/../../include
+EXTRA_CFLAGS += -I$(src)/../../include/$(TARGET)
+EXTRA_CFLAGS += -I$(src)/../../include/$(CAN_DRIVER)
+EXTRA_CFLAGS += -I$(src)/../../include/$(TIMERS_DRIVER)
+EXTRA_CFLAGS += -I/usr/src/comedi/include
+EXTRA_CFLAGS += SUB_PROG_CFLAGS
+
+OBJS := test_copcican_comedi.o
+
+obj-m := test_copcican_comedi.o
+test_copcican_comediko-objs := $(OBJS)
+
+#else
+# Normal Makefile
+CC = SUB_CC
+PREFIX = SUB_PREFIX
+KERNELDIR := SUB_KERNELDIR
+
+all: test_copcican_comedi
+
+test_copcican_comedi:
+ cat ../../drivers/can_copcican_comedi/Module.symvers > Module.symvers
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
+
+clean:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) clean
+ rm -f Module.symvers
+
+mrproper: clean
+ rm -f test_copcican_comedi.c
+
+install:
+ $(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules_install
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/test_copcican_comedi/insert.sh Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+module="test_copcican_comedi"
+device="test_copcican_comedi"
+mode="664"
+
+# insert neccessary modules
+/sbin/insmod ../../drivers/can_copcican_comedi/can_copcican_comedi.ko
+/sbin/insmod ../../src/canfestival.ko
+
+# insert module with all arguments we got
+# and use a pathname, as newer modutils don't look in . by default
+/sbin/insmod ./$module.ko $* || exit 1
+
+# stale nodes and device files are created by COMEDI
+
+rmmod $module
+rmmod canfestival
+rmmod can_copcican_comedi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/test_copcican_comedi/test_copcican_comedi.c Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,120 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ example for application with CO-PCICAN card.
+*/
+
+#include <linux/module.h>
+#include <linux/comedi.h>
+#include <linux/comedilib.h>
+#include "canfestival.h"
+
+/* only for mdelay() */
+#include <linux/delay.h>
+
+MODULE_LICENSE("GPL");
+
+#define CHTX 2 /* channel number of the CO-PCICAN */
+#define CHRX 0 /* channel number of the CO-PCICAN */
+
+void mySyncHandler( CO_Data* d )
+{
+ printk( "test_copcican_comedi: got a SYNC message...\n" );
+}
+
+static int main( void )
+{
+ s_BOARD bd;
+ CO_Data myData;
+ CAN_PORT port;
+ Message myMessage;
+ const char busname[] = "/dev/comedi0";
+ const char baudrate[] = "1M";
+ comedi_t *dev;
+
+ memset( &myData, 0x00, sizeof(CO_Data) );
+ myData.CurrentCommunicationState.csSYNC = 1;
+ myData.post_sync = mySyncHandler;
+ bd.busname = (char*)busname;
+ bd.baudrate = (char*)baudrate;
+
+ printk( "test_copcican_comedi: This example sends three SYNCs from port#%u to port#%u with a CO-PCICAN card\n", CHTX, CHRX );
+
+ /* direction: 0=RX, 1=TX */
+ co_pcican_select_channel( CHRX, 0 );
+ co_pcican_select_channel( CHTX, 1 );
+
+ port = canOpen( &bd, &myData );
+
+ if( port == NULL )
+ {
+ /* something strange happenend */
+ return 0;
+ }
+
+ /* get device pointer to control the opened device */
+ dev = get_dev_of_port( port );
+
+ co_pcican_enter_config_mode( dev );
+ co_pcican_configure_selected_channel( dev, &bd, 0 );
+ co_pcican_configure_selected_channel( dev, &bd, 1 );
+ co_pcican_enter_run_mode( dev );
+
+ memset( &myMessage, 0x00, sizeof(Message) );
+ myMessage.cob_id = 0x80; /* SYNC message */
+ myMessage.len = 1;
+ myMessage.data[0] = 0xA5;
+
+ /* SEND HERE */
+ canSend( port, &myMessage );
+
+ myMessage.data[0] = 0x5A;
+ canSend( port, &myMessage );
+
+ myMessage.data[0] = 0xA5;
+ canSend( port, &myMessage );
+
+ /* mySyncHandler() is called by the receive thread and shows a received SYNC message in the kernel log */
+ mdelay( 1*1000 ); /* 1s */
+
+ canClose( &myData );
+
+ return 0;
+}
+
+static int init(void)
+{
+ printk("test_copcican_comedi for CanFestival loaded\n");
+
+ return main();
+}
+
+static void exit(void)
+{
+ printk("test_copcican_comedi unloaded\n");
+}
+
+module_init(init);
+module_exit(exit);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/test_copcican_linux/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,76 @@
+#! gmake
+
+#
+# Copyright (C) 2010 Cosateq GmbH & Co.KG
+# http://www.cosateq.com/
+# http://www.scale-rt.com/
+#
+# 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)
+
+TEST_COPCICAN_LINUX_OBJS = test_copcican_linux.o
+
+OBJS = $(TEST_COPCICAN_LINUX_OBJS) ../../drivers/$(TARGET)/libcanfestival_$(TARGET).a ../../src/libcanfestival.a
+
+all: test_copcican_linux
+
+../../src/libcanfestival.a:
+ $(MAKE) -C ../../src libcanfestival.a
+
+
+../../drivers/$(TARGET)/libcanfestival_$(TARGET).a:
+ $(MAKE) -C ../../drivers/$(TARGET) libcanfestival_$(TARGET).a
+
+
+test_copcican_linux: test_copcican_linux.c $(OBJS)
+ $(LD) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) $(EXE_CFLAGS)
+
+%o: %c
+ $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+clean:
+ rm -f $(TEST_COPCICAN_LINUX_OBJS)
+ rm -f test_copcican_linux
+
+mrproper: clean
+ rm -f test_copcican_linux.c
+
+install: test_copcican_linux
+ mkdir -p $(PREFIX)/bin/
+ cp $< $(PREFIX)/bin/
+
+uninstall:
+ rm -f $(PREFIX)/bin/test_copcican_linux
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/test_copcican_linux/test_copcican_linux.c Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,130 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Cosateq GmbH & Co.KG
+ http://www.cosateq.com/
+ http://www.scale-rt.com/
+
+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
+*/
+
+/*
+ example for application with CO-PCICAN card.
+*/
+
+#include <stdio.h>
+#include "canfestival.h"
+
+/* only for usleep() */
+#include <linux/delay.h>
+
+#define CHTX 2 /* channel number of the CO-PCICAN */
+#define CHRX 0 /* channel number of the CO-PCICAN */
+
+void mySyncHandler( CO_Data* d )
+{
+ printf( " got a SYNC message...\n" );
+}
+
+int main()
+{
+ LIB_HANDLE driver;
+
+ /* handles for additional CO-PCICAN functions */
+ int (*get_fd_of_port)( CAN_PORT port );
+ int (*co_pcican_enter_run_mode)( const int fd );
+ int (*co_pcican_enter_config_mode)( const int fd );
+ int (*co_pcican_select_channel)( const unsigned char channel, const unsigned int direction );
+ int (*co_pcican_configure_selected_channel)( const int fd, s_BOARD *board, const unsigned int direction );
+
+ s_BOARD bd;
+ CO_Data myData;
+ CAN_PORT port;
+ Message myMessage;
+ const char busname[] = "/dev/co_pcican-0";
+ const char baudrate[] = "1M";
+ int fd;
+
+ memset( &myData, 0x00, sizeof(CO_Data) );
+ myData.CurrentCommunicationState.csSYNC = 1;
+ myData.post_sync = mySyncHandler;
+ bd.busname = (char*)busname;
+ bd.baudrate = (char*)baudrate;
+
+ printf( "This example sends three SYNCs from port#%u to port#%u with a CO-PCICAN card\n", CHTX, CHRX );
+
+ driver = LoadCanDriver( "/usr/local/lib/libcanfestival_can_copcican_linux.so" );
+
+ if( driver == NULL )
+ {
+ /* something strange happenend */
+ return 0;
+ }
+
+ /* dynamic load of additional library functions */
+ get_fd_of_port = dlsym( driver, "get_fd_of_port" );
+ co_pcican_enter_run_mode = dlsym( driver, "co_pcican_enter_run_mode" );
+ co_pcican_enter_config_mode = dlsym( driver, "co_pcican_enter_config_mode" );
+ co_pcican_select_channel = dlsym( driver, "co_pcican_select_channel" );
+ co_pcican_configure_selected_channel = dlsym( driver, "co_pcican_configure_selected_channel" );
+
+ /* direction: 0=RX, 1=TX */
+ co_pcican_select_channel( CHRX, 0 );
+ co_pcican_select_channel( CHTX, 1 );
+
+ port = canOpen( &bd, &myData );
+
+ if( port == NULL )
+ {
+ UnLoadCanDriver( driver );
+
+ /* something strange happenend */
+ return 0;
+ }
+
+ /* get file descriptor to control the opened device */
+ fd = get_fd_of_port( port );
+
+ co_pcican_enter_config_mode( fd );
+ co_pcican_configure_selected_channel( fd, &bd, 0 );
+ co_pcican_configure_selected_channel( fd, &bd, 1 );
+ co_pcican_enter_run_mode( fd );
+
+ memset( &myMessage, 0x00, sizeof(Message) );
+ myMessage.cob_id = 0x80; /* SYNC message */
+ myMessage.len = 1;
+ myMessage.data[0] = 0xA5;
+
+ /* SEND HERE */
+ canSend( port, &myMessage );
+
+ myMessage.data[0] = 0x5A;
+ canSend( port, &myMessage );
+
+ myMessage.data[0] = 0xA5;
+ canSend( port, &myMessage );
+
+ /* mySyncHandler() is called by the receive thread and shows a received SYNC message on console */
+ usleep( 1*1000*1000 ); /* 1s */
+
+ canClose( &myData );
+
+ UnLoadCanDriver( driver );
+
+ return 0;
+}
+
--- a/include/can_driver.h Fri Nov 12 22:02:32 2010 +0100
+++ b/include/can_driver.h Fri Nov 12 22:24:06 2010 +0100
@@ -46,7 +46,11 @@
};
#ifndef DLL_CALL
+#if !defined(WIN32) || defined(__CYGWIN__)
#define DLL_CALL(funcname) funcname##_driver
+#else
+//Windows was missing the definition of the calling convention
+#define DLL_CALL(funcname) __stdcall funcname##_driver
#endif
#ifndef FCT_PTR_INIT
--- a/include/objacces.h Fri Nov 12 22:02:32 2010 +0100
+++ b/include/objacces.h Fri Nov 12 22:24:06 2010 +0100
@@ -1,287 +1,287 @@
-/*
-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
-*/
-
-/** @file
- * @brief Responsible for accessing the object dictionary.
- *
- * This file contains functions for accessing the object dictionary and
- * variables that are contained by the object dictionary.
- * Accessing the object dictionary contains setting local variables
- * as PDOs and accessing (read/write) all entries of the object dictionary
- * @warning Only the basic entries of an object dictionary are included
- * at the moment.
- */
-
-/** @defgroup od Object Dictionary Management
- * @brief The Object Dictionary is the heart of each CANopen device containing all communication and application objects.
- * @ingroup userapi
- */
-
-#ifndef __objacces_h__
-#define __objacces_h__
-
-#include <applicfg.h>
-
-
+/*
+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
+*/
+
+/** @file
+ * @brief Responsible for accessing the object dictionary.
+ *
+ * This file contains functions for accessing the object dictionary and
+ * variables that are contained by the object dictionary.
+ * Accessing the object dictionary contains setting local variables
+ * as PDOs and accessing (read/write) all entries of the object dictionary
+ * @warning Only the basic entries of an object dictionary are included
+ * at the moment.
+ */
+
+/** @defgroup od Object Dictionary Management
+ * @brief The Object Dictionary is the heart of each CANopen device containing all communication and application objects.
+ * @ingroup userapi
+ */
+
+#ifndef __objacces_h__
+#define __objacces_h__
+
+#include <applicfg.h>
+
+
#ifdef __cplusplus
extern "C" {
-#endif
-
-
-typedef UNS32 (*valueRangeTest_t)(UNS8 typeValue, void *Value);
-typedef void (* storeODSubIndex_t)(CO_Data* d, UNS16 wIndex, UNS8 bSubindex);
-void _storeODSubIndex (CO_Data* d, UNS16 wIndex, UNS8 bSubindex);
-
-/**
- * @brief Print MSG_WAR (s) if error to the access to the object dictionary occurs.
- *
- * You must uncomment the lines in the file objaccess.c :\n
- * //#define DEBUG_CAN\n
- * //#define DEBUG_WAR_CONSOLE_ON\n
- * //#define DEBUG_ERR_CONSOLE_ON\n\n
- * Beware that sometimes, we force the sizeDataDict or sizeDataGiven to 0, when we wants to use
- * this function but we do not have the access to the right value. One example is
- * getSDOerror(). So do not take attention to these variables if they are null.
- * @param index
- * @param subIndex
- * @param sizeDataDict Size of the data defined in the dictionary
- * @param sizeDataGiven Size data given by the user.
- * @param code error code to print. (SDO abort code. See file def.h)
- * @return
- */
-UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex,
- UNS32 sizeDataDict, UNS32 sizeDataGiven, UNS32 code);
-
-
-/* _getODentry() Reads an entry from the object dictionary.\n
- *
- * use getODentry() macro to read from object and endianize
- * use readLocalDict() macro to read from object and not endianize
- *
- * @code
- * // Example usage:
- * UNS8 *pbData;
- * UNS8 length;
- * UNS32 returnValue;
- *
- * returnValue = getODentry( (UNS16)0x100B, (UNS8)1,
- * (void * *)&pbData, (UNS8 *)&length );
- * if( returnValue != SUCCESSFUL )
- * {
- * // error handling
- * }
- * @endcode
- * @param *d Pointer to a CAN object data structure
- * @param wIndex The index in the object dictionary where you want to read
- * an entry
- * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
- * used to tell you how many valid entries you can find
- * in this index. Look at the canopen standard for further
- * information
- * @param *pDestData Pointer to the pointer which points to the variable where
- * the value of this object dictionary entry should be copied
- * @param pExpectedSize This function writes the size of the copied value (in Byte)
- * into this variable.
- * @param *pDataType Pointer to the type of the data. See objdictdef.h
- * @param CheckAccess if other than 0, do not read if the data is Write Only
- * [Not used today. Put always 0].
- * @param Endianize When not 0, data is endianized into network byte order
- * when 0, data is not endianized and copied in machine native
- * endianness
- * @return
- * - OD_SUCCESSFUL is returned upon success.
- * - SDO abort code is returned if error occurs . (See file def.h)
- */
-UNS32 _getODentry( CO_Data* d,
- UNS16 wIndex,
- UNS8 bSubindex,
- void * pDestData,
- UNS32 * pExpectedSize,
- UNS8 * pDataType,
- UNS8 checkAccess,
- UNS8 endianize);
-
-/**
- * @ingroup od
- * @brief getODentry() to read from object and endianize
- * @param OD Pointer to a CAN object data structure
- * @param wIndex The index in the object dictionary where you want to read
- * an entry
- * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
- * used to tell you how many valid entries you can find
- * in this index. Look at the canopen standard for further
- * information
- * @param *pDestData Pointer to the pointer which points to the variable where
- * the value of this object dictionary entry should be copied
- * @param pExpectedSize This function writes the size of the copied value (in Byte)
- * into this variable.
- * @param *pDataType Pointer to the type of the data. See objdictdef.h
- * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
- * @param endianize Set to 1 : endianized into network byte order
- * @return
- * - OD_SUCCESSFUL is returned upon success.
- * - SDO abort code is returned if error occurs . (See file def.h)
- */
-#define getODentry( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
- pDataType, checkAccess) \
- _getODentry( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
- pDataType, checkAccess, 1)
-
-/**
- * @ingroup od
- * @brief readLocalDict() reads an entry from the object dictionary, but in
- * contrast to getODentry(), readLocalDict() doesn't endianize entry and reads
- * entry in machine native endianness.
- * @param OD Pointer to a CAN object data structure
- * @param wIndex The index in the object dictionary where you want to read
- * an entry
- * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
- * used to tell you how many valid entries you can find
- * in this index. Look at the canopen standard for further
- * information
- * @param *pDestData Pointer to the pointer which points to the variable where
- * the value of this object dictionary entry should be copied
- * @param pExpectedSize This function writes the size of the copied value (in Byte)
- * into this variable.
- * @param *pDataType Pointer to the type of the data. See objdictdef.h
- * @param checkAccess if other than 0, do not read if the data is Write Only
- * [Not used today. Put always 0].
- * @param endianize Set to 0, data is not endianized and copied in machine native
- * endianness
- * @return
- * - OD_SUCCESSFUL is returned upon success.
- * - SDO abort code is returned if error occurs . (See file def.h)
- */
-#define readLocalDict( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
- pDataType, checkAccess) \
- _getODentry( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
- pDataType, checkAccess, 0)
-
-/* By this function you can write an entry into the object dictionary
- * @param *d Pointer to a CAN object data structure
- * @param wIndex The index in the object dictionary where you want to write
- * an entry
- * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
- * used to tell you how many valid entries you can find
- * in this index. Look at the canopen standard for further
- * information
- * @param *pSourceData Pointer to the variable that holds the value that should
- * be copied into the object dictionary
- * @param *pExpectedSize The size of the value (in Byte).
- * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
- * @param endianize When not 0, data is endianized into network byte order
- * when 0, data is not endianized and copied in machine native
- * endianness
- * @return
- * - OD_SUCCESSFUL is returned upon success.
- * - SDO abort code is returned if error occurs . (See file def.h)
- */
-UNS32 _setODentry( CO_Data* d,
- UNS16 wIndex,
- UNS8 bSubindex,
- void * pSourceData,
- UNS32 * pExpectedSize,
- UNS8 checkAccess,
- UNS8 endianize);
-
-/**
- * @ingroup od
- * @brief setODentry converts SourceData from network byte order to machine native
- * format, and writes that to OD.
- * @code
- * // Example usage:
- * UNS8 B;
- * B = 0xFF; // set transmission type
- *
- * retcode = setODentry( (UNS16)0x1800, (UNS8)2, &B, sizeof(UNS8), 1 );
- * @endcode
- * @param d Pointer to a CAN object data structure
- * @param wIndex The index in the object dictionary where you want to write
- * an entry
- * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
- * used to tell you how many valid entries you can find
- * in this index. Look at the canopen standard for further
- * information
- * @param *pSourceData Pointer to the variable that holds the value that should
- * be copied into the object dictionary
- * @param *pExpectedSize The size of the value (in Byte).
- * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
- * @param endianize Set to 1 : endianized into network byte order
- * @return
- * - OD_SUCCESSFUL is returned upon success.
- * - SDO abort code is returned if error occurs . (See file def.h)
- */
-#define setODentry( d, wIndex, bSubindex, pSourceData, pExpectedSize, \
- checkAccess) \
- _setODentry( d, wIndex, bSubindex, pSourceData, pExpectedSize, \
- checkAccess, 1)
-
-/** @fn UNS32 writeLocalDict(d, wIndex, bSubindex, pSourceData, pExpectedSize, checkAccess)
- * @ingroup od
- * @hideinitializer
- * @brief Writes machine native SourceData to OD.
- * @param d Pointer to a CAN object data structure
- * @param wIndex The index in the object dictionary where you want to write
- * an entry
- * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
- * used to tell you how many valid entries you can find
- * in this index. Look at the canopen standard for further
- * information
- * @param *pSourceData Pointer to the variable that holds the value that should
- * be copied into the object dictionary
- * @param *pExpectedSize The size of the value (in Byte).
- * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
- * @param endianize Data is not endianized and copied in machine native endianness
- * @return
- * - OD_SUCCESSFUL is returned upon success.
- * - SDO abort code is returned if error occurs . (See file def.h)
- * \n\n
- * @code
- * // Example usage:
- * UNS8 B;
- * B = 0xFF; // set transmission type
- *
- * retcode = writeLocalDict( (UNS16)0x1800, (UNS8)2, &B, sizeof(UNS8), 1 );
- * @endcode
- */
-#define writeLocalDict( d, wIndex, bSubindex, pSourceData, pExpectedSize, checkAccess) \
- _setODentry( d, wIndex, bSubindex, pSourceData, pExpectedSize, checkAccess, 0)
-
-
-
-/**
- * @brief Scan the index of object dictionary. Used only by setODentry and getODentry.
- * @param *d Pointer to a CAN object data structure
- * @param wIndex
- * @param *errorCode : OD_SUCCESSFUL if index foundor SDO abort code. (See file def.h)
- * @param **Callback
- * @return NULL if index not found. Else : return the table part of the object dictionary.
- */
- const indextable * scanIndexOD (CO_Data* d, UNS16 wIndex, UNS32 *errorCode, ODCallback_t **Callback);
-
-UNS32 RegisterSetODentryCallBack(CO_Data* d, UNS16 wIndex, UNS8 bSubindex, ODCallback_t Callback);
-
+#endif
+
+
+typedef UNS32 (*valueRangeTest_t)(UNS8 typeValue, void *Value);
+typedef void (* storeODSubIndex_t)(CO_Data* d, UNS16 wIndex, UNS8 bSubindex);
+void _storeODSubIndex (CO_Data* d, UNS16 wIndex, UNS8 bSubindex);
+
+/**
+ * @brief Print MSG_WAR (s) if error to the access to the object dictionary occurs.
+ *
+ * You must uncomment the lines in the file objaccess.c :\n
+ * //#define DEBUG_CAN\n
+ * //#define DEBUG_WAR_CONSOLE_ON\n
+ * //#define DEBUG_ERR_CONSOLE_ON\n\n
+ * Beware that sometimes, we force the sizeDataDict or sizeDataGiven to 0, when we wants to use
+ * this function but we do not have the access to the right value. One example is
+ * getSDOerror(). So do not take attention to these variables if they are null.
+ * @param index
+ * @param subIndex
+ * @param sizeDataDict Size of the data defined in the dictionary
+ * @param sizeDataGiven Size data given by the user.
+ * @param code error code to print. (SDO abort code. See file def.h)
+ * @return
+ */
+UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex,
+ UNS32 sizeDataDict, UNS32 sizeDataGiven, UNS32 code);
+
+
+/* _getODentry() Reads an entry from the object dictionary.\n
+ *
+ * use getODentry() macro to read from object and endianize
+ * use readLocalDict() macro to read from object and not endianize
+ *
+ * @code
+ * // Example usage:
+ * UNS8 *pbData;
+ * UNS8 length;
+ * UNS32 returnValue;
+ *
+ * returnValue = getODentry( (UNS16)0x100B, (UNS8)1,
+ * (void * *)&pbData, (UNS8 *)&length );
+ * if( returnValue != SUCCESSFUL )
+ * {
+ * // error handling
+ * }
+ * @endcode
+ * @param *d Pointer to a CAN object data structure
+ * @param wIndex The index in the object dictionary where you want to read
+ * an entry
+ * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
+ * used to tell you how many valid entries you can find
+ * in this index. Look at the canopen standard for further
+ * information
+ * @param *pDestData Pointer to the pointer which points to the variable where
+ * the value of this object dictionary entry should be copied
+ * @param pExpectedSize This function writes the size of the copied value (in Byte)
+ * into this variable.
+ * @param *pDataType Pointer to the type of the data. See objdictdef.h
+ * @param CheckAccess if other than 0, do not read if the data is Write Only
+ * [Not used today. Put always 0].
+ * @param Endianize When not 0, data is endianized into network byte order
+ * when 0, data is not endianized and copied in machine native
+ * endianness
+ * @return
+ * - OD_SUCCESSFUL is returned upon success.
+ * - SDO abort code is returned if error occurs . (See file def.h)
+ */
+UNS32 _getODentry( CO_Data* d,
+ UNS16 wIndex,
+ UNS8 bSubindex,
+ void * pDestData,
+ UNS32 * pExpectedSize,
+ UNS8 * pDataType,
+ UNS8 checkAccess,
+ UNS8 endianize);
+
+/**
+ * @ingroup od
+ * @brief getODentry() to read from object and endianize
+ * @param OD Pointer to a CAN object data structure
+ * @param wIndex The index in the object dictionary where you want to read
+ * an entry
+ * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
+ * used to tell you how many valid entries you can find
+ * in this index. Look at the canopen standard for further
+ * information
+ * @param *pDestData Pointer to the pointer which points to the variable where
+ * the value of this object dictionary entry should be copied
+ * @param pExpectedSize This function writes the size of the copied value (in Byte)
+ * into this variable.
+ * @param *pDataType Pointer to the type of the data. See objdictdef.h
+ * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
+ * @param endianize Set to 1 : endianized into network byte order
+ * @return
+ * - OD_SUCCESSFUL is returned upon success.
+ * - SDO abort code is returned if error occurs . (See file def.h)
+ */
+#define getODentry( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
+ pDataType, checkAccess) \
+ _getODentry( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
+ pDataType, checkAccess, 1)
+
+/**
+ * @ingroup od
+ * @brief readLocalDict() reads an entry from the object dictionary, but in
+ * contrast to getODentry(), readLocalDict() doesn't endianize entry and reads
+ * entry in machine native endianness.
+ * @param OD Pointer to a CAN object data structure
+ * @param wIndex The index in the object dictionary where you want to read
+ * an entry
+ * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
+ * used to tell you how many valid entries you can find
+ * in this index. Look at the canopen standard for further
+ * information
+ * @param *pDestData Pointer to the pointer which points to the variable where
+ * the value of this object dictionary entry should be copied
+ * @param pExpectedSize This function writes the size of the copied value (in Byte)
+ * into this variable.
+ * @param *pDataType Pointer to the type of the data. See objdictdef.h
+ * @param checkAccess if other than 0, do not read if the data is Write Only
+ * [Not used today. Put always 0].
+ * @param endianize Set to 0, data is not endianized and copied in machine native
+ * endianness
+ * @return
+ * - OD_SUCCESSFUL is returned upon success.
+ * - SDO abort code is returned if error occurs . (See file def.h)
+ */
+#define readLocalDict( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
+ pDataType, checkAccess) \
+ _getODentry( OD, wIndex, bSubindex, pDestData, pExpectedSize, \
+ pDataType, checkAccess, 0)
+
+/* By this function you can write an entry into the object dictionary
+ * @param *d Pointer to a CAN object data structure
+ * @param wIndex The index in the object dictionary where you want to write
+ * an entry
+ * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
+ * used to tell you how many valid entries you can find
+ * in this index. Look at the canopen standard for further
+ * information
+ * @param *pSourceData Pointer to the variable that holds the value that should
+ * be copied into the object dictionary
+ * @param *pExpectedSize The size of the value (in Byte).
+ * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
+ * @param endianize When not 0, data is endianized into network byte order
+ * when 0, data is not endianized and copied in machine native
+ * endianness
+ * @return
+ * - OD_SUCCESSFUL is returned upon success.
+ * - SDO abort code is returned if error occurs . (See file def.h)
+ */
+UNS32 _setODentry( CO_Data* d,
+ UNS16 wIndex,
+ UNS8 bSubindex,
+ void * pSourceData,
+ UNS32 * pExpectedSize,
+ UNS8 checkAccess,
+ UNS8 endianize);
+
+/**
+ * @ingroup od
+ * @brief setODentry converts SourceData from network byte order to machine native
+ * format, and writes that to OD.
+ * @code
+ * // Example usage:
+ * UNS8 B;
+ * B = 0xFF; // set transmission type
+ *
+ * retcode = setODentry( (UNS16)0x1800, (UNS8)2, &B, sizeof(UNS8), 1 );
+ * @endcode
+ * @param d Pointer to a CAN object data structure
+ * @param wIndex The index in the object dictionary where you want to write
+ * an entry
+ * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
+ * used to tell you how many valid entries you can find
+ * in this index. Look at the canopen standard for further
+ * information
+ * @param *pSourceData Pointer to the variable that holds the value that should
+ * be copied into the object dictionary
+ * @param *pExpectedSize The size of the value (in Byte).
+ * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
+ * @param endianize Set to 1 : endianized into network byte order
+ * @return
+ * - OD_SUCCESSFUL is returned upon success.
+ * - SDO abort code is returned if error occurs . (See file def.h)
+ */
+#define setODentry( d, wIndex, bSubindex, pSourceData, pExpectedSize, \
+ checkAccess) \
+ _setODentry( d, wIndex, bSubindex, pSourceData, pExpectedSize, \
+ checkAccess, 1)
+
+/** @fn UNS32 writeLocalDict(d, wIndex, bSubindex, pSourceData, pExpectedSize, checkAccess)
+ * @ingroup od
+ * @hideinitializer
+ * @brief Writes machine native SourceData to OD.
+ * @param d Pointer to a CAN object data structure
+ * @param wIndex The index in the object dictionary where you want to write
+ * an entry
+ * @param bSubindex The subindex of the Index. e.g. mostly subindex 0 is
+ * used to tell you how many valid entries you can find
+ * in this index. Look at the canopen standard for further
+ * information
+ * @param *pSourceData Pointer to the variable that holds the value that should
+ * be copied into the object dictionary
+ * @param *pExpectedSize The size of the value (in Byte).
+ * @param checkAccess Flag that indicate if a check rights must be perfomed (0 : no , other than 0 : yes)
+ * @param endianize Data is not endianized and copied in machine native endianness
+ * @return
+ * - OD_SUCCESSFUL is returned upon success.
+ * - SDO abort code is returned if error occurs . (See file def.h)
+ * \n\n
+ * @code
+ * // Example usage:
+ * UNS8 B;
+ * B = 0xFF; // set transmission type
+ *
+ * retcode = writeLocalDict( (UNS16)0x1800, (UNS8)2, &B, sizeof(UNS8), 1 );
+ * @endcode
+ */
+#define writeLocalDict( d, wIndex, bSubindex, pSourceData, pExpectedSize, checkAccess) \
+ _setODentry( d, wIndex, bSubindex, pSourceData, pExpectedSize, checkAccess, 0)
+
+
+
+/**
+ * @brief Scan the index of object dictionary. Used only by setODentry and getODentry.
+ * @param *d Pointer to a CAN object data structure
+ * @param wIndex
+ * @param *errorCode : OD_SUCCESSFUL if index foundor SDO abort code. (See file def.h)
+ * @param **Callback
+ * @return NULL if index not found. Else : return the table part of the object dictionary.
+ */
+ const indextable * scanIndexOD (CO_Data* d, UNS16 wIndex, UNS32 *errorCode, ODCallback_t **Callback);
+
+UNS32 RegisterSetODentryCallBack(CO_Data* d, UNS16 wIndex, UNS8 bSubindex, ODCallback_t Callback);
+
#ifdef __cplusplus
}
-#endif
-
-#endif /* __objacces_h__ */
+#endif
+
+#endif /* __objacces_h__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/timers_kernel_xeno/timerscfg.h Fri Nov 12 22:24:06 2010 +0100
@@ -0,0 +1,42 @@
+/*
+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 __TIMERSCFG_H__
+#define __TIMERSCFG_H__
+
+#include <native/task.h>
+#include <native/timer.h>
+#include <native/mutex.h>
+#include <native/cond.h>
+#include <native/sem.h>
+#include <native/alarm.h>
+
+// Time unit : ns
+// Time resolution : 64bit (~584 years)
+#define TIMEVAL RTIME
+#define TIMEVAL_MAX ~(RTIME)0
+#define MS_TO_TIMEVAL(ms) rt_timer_ns2ticks((RTIME)ms*1000000)
+#define US_TO_TIMEVAL(us) rt_timer_ns2ticks((RTIME)us*1000)
+
+#define TASK_HANDLE RT_TASK
+
+#endif
--- a/src/Makefile.in Fri Nov 12 22:02:32 2010 +0100
+++ b/src/Makefile.in Fri Nov 12 22:24:06 2010 +0100
@@ -2,24 +2,24 @@
#
# 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
-#
+#
ifneq ($(KERNELRELEASE),)
# Kbuild part of Makefile
@@ -60,11 +60,18 @@
OPT_CFLAGS = -O2
endif
-# # # # Options # # # #
+# # # # Options # # # #
all: canfestival
ifeq ($(TIMERS_DRIVER), timers_kernel)
+USE_KERNEL_TIMER = true
+endif
+ifeq ($(TIMERS_DRIVER), timers_kernel_xeno)
+USE_KERNEL_TIMER = true
+endif
+
+ifeq ($(USE_KERNEL_TIMER), true)
OBJS := $(shell echo $(OBJS) | sed "s:$(TARGET)_::g")
OBJS += symbols.o
OBJS += ../drivers/unix/libcanfestival_$(TARGET).o
--- a/src/objacces.c Fri Nov 12 22:02:32 2010 +0100
+++ b/src/objacces.c Fri Nov 12 22:24:06 2010 +0100
@@ -40,10 +40,12 @@
#include "data.h"
-#ifdef DEBUG_WAR_CONSOLE_ON
+//We need the function implementation for linking
+//Only a placeholder with a define isnt enough!
UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex,
UNS32 sizeDataDict, UNS32 sizeDataGiven, UNS32 code)
{
+#ifdef DEBUG_WAR_CONSOLE_ON
MSG_WAR(0x2B09,"Dictionary index : ", index);
MSG_WAR(0X2B10," subindex : ", subIndex);
switch (code) {
@@ -72,11 +74,10 @@
default :
MSG_WAR(0x2B20, "Unknown error code : ", code);
}
+ #endif
+
return 0;
}
-#else
-#define accessDictionaryError(index, subIndex, sizeDataDict, sizeDataGiven, code)
-#endif
UNS32 _getODentry( CO_Data* d,
UNS16 wIndex,
--- a/src/pdo.c Fri Nov 12 22:02:32 2010 +0100
+++ b/src/pdo.c Fri Nov 12 22:24:06 2010 +0100
@@ -487,8 +487,8 @@
{
/*store_as_last_message */
d->PDO_status[pdoNum].last_message = *pdo;
- MSG_WAR (0x396D, "sendPDO cobId :", UNS16_LE(pdo->cob_id));
- MSG_WAR (0x396E, " Nb octets : ", pdo->len);
+ MSG_WAR (0x396D, "sendPDO cobId :", UNS16_LE(pdo.cob_id));
+ MSG_WAR (0x396E, " Nb octets : ", pdo.len);
canSend (d->canHandle, pdo);
}
@@ -512,16 +512,18 @@
UNS8
sendOnePDOevent (CO_Data * d, UNS32 pdoNum)
{
+ UNS16 offsetObjdict;
+ Message pdo;
if (!d->CurrentCommunicationState.csPDO ||
- (d->PDO_status[pdoNum].transmit_type_parameter & PDO_INHIBITED))
+ !(d->PDO_status[pdoNum].transmit_type_parameter & PDO_INHIBITED))
{
return 0;
}
- UNS16 offsetObjdict = d->firstIndex->PDO_TRS + pdoNum;
+ offsetObjdict = d->firstIndex->PDO_TRS + pdoNum;
MSG_WAR (0x3968, " PDO is on EVENT. Trans type : ",
*pTransmissionType);
- Message pdo;
+
memset(&pdo, 0, sizeof(pdo));
if (buildPDO (d, pdoNum, &pdo))
{
--- a/src/symbols.c Fri Nov 12 22:02:32 2010 +0100
+++ b/src/symbols.c Fri Nov 12 22:24:06 2010 +0100
@@ -50,10 +50,12 @@
// objacces.h
EXPORT_SYMBOL (_storeODSubIndex);
+#ifdef DEBUG_WAR_CONSOLE_ON
EXPORT_SYMBOL (accessDictionaryError);
-EXPORT_SYMBOL (getODentry);
-EXPORT_SYMBOL (setODentry);
-EXPORT_SYMBOL (writeLocalDict);
+#endif
+EXPORT_SYMBOL (_getODentry);
+EXPORT_SYMBOL (_setODentry);
+//EXPORT_SYMBOL (writeLocalDict);
EXPORT_SYMBOL (scanIndexOD);
EXPORT_SYMBOL (RegisterSetODentryCallBack);
--- a/src/timer.c Fri Nov 12 22:02:32 2010 +0100
+++ b/src/timer.c Fri Nov 12 22:24:06 2010 +0100
@@ -124,7 +124,7 @@
TIMEVAL next_wakeup = TIMEVAL_MAX; /* used to compute when should normaly occur next wakeup */
/* First run : change timer state depending on time */
/* Get time since timer signal */
- TIMEVAL overrun = getElapsedTime();
+ UNS32 overrun = (UNS32)getElapsedTime();
TIMEVAL real_total_sleep_time = total_sleep_time + overrun;
@@ -142,8 +142,9 @@
}
else /* or period have expired */
{
- /* set val as interval, with overrun correction */
- row->val = row->interval - (overrun % row->interval);
+ /* set val as interval, with 32 bit overrun correction, */
+ /* modulo for 64 bit not available on all platforms */
+ row->val = row->interval - (overrun % (UNS32)row->interval);
row->state = TIMER_TRIG_PERIOD; /* ask for trig, periodic */
/* Check if this new timer value is the soonest */
if(row->val < next_wakeup)