# HG changeset patch # User etisserant # Date 1147273180 -7200 # Node ID 4472ee7c6c3efd98790a6ec71a187e2f8431c08c Commit a new cvs repo. diff -r 000000000000 -r 4472ee7c6c3e .cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,5 @@ +.cdtproject +.project +.settings +.externalToolBuilders +Makefile diff -r 000000000000 -r 4472ee7c6c3e AUTHORS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AUTHORS Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,7 @@ + +Authors : +========= + +Edouard TISSERANT (www.lolitech.fr) +Francis DUPIN (LIVIC) +Laurent BESSARD (www.lolitech.fr) diff -r 000000000000 -r 4472ee7c6c3e CHANGES --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CHANGES Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,3 @@ + + +02-17-2006 CanFestival-3 import \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e CONTRIBUTORS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CONTRIBUTORS Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,12 @@ + +Contributors : +============== + +Raphael Zulliger (author of slavelib project) + +Camille BOSSARD +David DUMINY (sté A6R) +Laurent ROMIEUX +Zakaria BELAMRI + +Many thanks to the main contributors for their great work. diff -r 000000000000 -r 4472ee7c6c3e COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/COPYING Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,32 @@ + CanFestival Master/slave CANopen Library + + Copyright (C): Francis DUPIN (LIVIC), Edouard TISSERANT and Laurent BESSARD (LOLITECH) + + LIVIC : Laboratoire Interractions Véhicule Infrastructure Conducteur + INRETS/LIVIC (http://www.inrets.fr) + Institut National de Recherche sur les Transports et leur Sécurité + LCPC Laboratoire Central des Ponts et Chaussées + + LOLITECH : www.lolitech.fr - Logiciel Libre et Technologie. + + This work is based on + - CanOpenMatic by Edouard TISSERANT + http://sourceforge.net/projects/canfestival/ + - slavelib by Raphael Zulliger + http://sourceforge.net/projects/canopen/ + +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 + +See LICENCE file for LGPL details. diff -r 000000000000 -r 4472ee7c6c3e LICENCE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LICENCE Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,458 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff -r 000000000000 -r 4472ee7c6c3e Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,59 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +all: objdictgen canfestival examples + +examples: canfestival driver + $(MAKE) -C examples all + +objdictgen: + $(MAKE) -C objdictgen all + +canfestival: driver + $(MAKE) -C src $@ + +driver: + $(MAKE) -C drivers $@ + +install: canfestival driver + $(MAKE) -C drivers $@ + $(MAKE) -C src $@ + $(MAKE) -C objdictgen $@ + +uninstall: + $(MAKE) -C drivers $@ + $(MAKE) -C src $@ + $(MAKE) -C objdictgen $@ + +clean: + $(MAKE) -C src $@ + $(MAKE) -C drivers $@ + $(MAKE) -C examples $@ + $(MAKE) -C objdictgen $@ + +mrproper: clean + $(MAKE) -C src $@ + $(MAKE) -C drivers $@ + $(MAKE) -C examples $@ + $(MAKE) -C objdictgen $@ + diff -r 000000000000 -r 4472ee7c6c3e configure --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configure Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,645 @@ +#!/bin/bash + +# +# 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. +# +# 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 +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. +# for a slave node, usually put 1. +SDO_MAX_SIMULTANEOUS_TRANSFERTS=4 + +# 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 + +#Timeout in milliseconds for SDO. +# Comment the #define if not used (infinite wait for SDO response message) +SDO_TIMEOUT_MS=3000 + +MAX_NB_TIMER=32 + +# Default to little-endian +CANOPEN_LITTLE_ENDIAN=1 +CANOPEN_BIG_ENDIAN= + +########################################################################### +# DEFAULT BUILD OPTIONS # +########################################################################### + +# Leave empty for automatic detection +CC= + +#default target +SUB_TARGET= + +# First compiler option - we will check if it exists +CC1=gcc +# Second compiler option - we will check if it exists +CC2=cc + +# Install prefix +SUB_PREFIX= + +SUB_TIMERS_ENABLE=YES + +# Used for C compiler test/detection +CFLAGS= +test=conftest +rm -f $test $test.c + +# Jaxe install is now disbaled by default +DISABLE_JAXE=1 + +XENO_CONFIG=/usr/xenomai/bin/xeno-config + +########################################################################### +# ARGUMENTS PARSING # +########################################################################### +while [ $# -ge 1 ]; do + optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + + case $1 in + --cc=*) CC=$optarg;; + --arch=*) SUB_ARCH_NAME=$optarg;; + --os=*) SUB_OS_NAME=$optarg;; + --prefix=*) SUB_PREFIX=$optarg;; + --target=*) SUB_TARGET=$optarg;; + --can=*) SUB_CAN_DRIVER=$optarg;; + --timers=*) SUB_TIMERS_DRIVER=$optarg;; + --disable-Ox) DISABLE_OPT=1; + echo "On user request: Won't optimize with \"-Ox\"";; + --enable-jaxe) DISABLE_JAXE=0; + echo "On user request: Will not install jaxe";; + --debug) DEBUG=1; + echo "Debug messages enabled !!";; + --debugPDO) DEBUG=PDO; + echo "Debug messages (PDO) enabled !!";; + --enable-lss) SUB_LSS_ENABLE=YES; + echo "On user request: Will enable Auto Baudrate detect Feature";; + --enable-led) SUB_LED_ENABLE=YES; + echo "On user request: Will enable diagnostic LED feature";; + --enable-nvram) SUB_NVRAM_ENABLE=YES; + echo "On user request: Will enable Non Volatile RAM Feature";; + --desable-timers) SUB_TIMERS_ENABLE=NO; + echo "On user request: Will enable built-in timer dispatch Feature";; + --MAX_CAN_BUS_ID=*) MAX_CAN_BUS_ID=$1;; + --SDO_MAX_LENGTH_TRANSFERT=*) SDO_MAX_LENGTH_TRANSFERT=$1;; + --SDO_MAX_SIMULTANEOUS_TRANSFERTS=*) SDO_MAX_SIMULTANEOUS_TRANSFERTS=$1;; + --NMT_MAX_NODE_ID=*) NMT_MAX_NODE_ID=$1;; + --SDO_TIMEOUT_MS=*) SDO_TIMEOUT_MS=$1;; + --CANOPEN_BIG_ENDIAN=*) CANOPEN_BIG_ENDIAN=$1;; + --MAX_NB_TIMER=*) MAX_NB_TIMER=$1;; + --help) echo "Usage: ./configure [options]" + echo "Options:" + echo " --cc=foo Use compiler 'foo' instead of defaults ${CC1} or ${CC2}." + echo " --arch=foo Use architecture 'foo' instead of trying to autodetect." + echo " --os=foo Use operative system 'foo' instead of trying to autodetect." + echo " --prefix=foo Use prefix 'foo' instead of default ${SUB_PREFIX}." + echo " --target=foo Use 'foo' as build target." + echo " Where 'foo' can be \"generic\" to have independant CAN and TIMERS driver" + echo " or" + echo " \"hcs12\" for HCS12 micro-controller" + echo " \"ecos_lpc2138_sja1000\" for eCOS + Philips ARM LPC21381 + Philips SJA1000" + echo " --can=foo Use 'foo' as CAN driver (can be either 'peak' or 'virtual')" + echo " --timers=foo Use 'foo' as TIMERS driver (can be either 'unix' or 'xenomai')" + echo " --disable-Ox Disable gcc \"-Ox\" optimizations." + echo " --enable-jaxe Enable \"jaxe\" installation." + echo " --debug Enable debug messages." + echo " --debugPDO Enable debug messages, using PDO." + echo " --enable-lss Enable Auto Baudrate detect Feature" + echo " --enable-led Enable DS-305 LED diagnistic Feature" + echo " --enable-nvram Enable Non-volatile RAM managment Feature" + echo " --enable-timers Enable built-in schuduler Feature" + echo " --enable- Enable Feature" + echo + echo "Stack compilation constants" + echo " --MAX_CAN_BUS_ID [=1] Number of can bus to use" + echo " --SDO_MAX_LENGTH_TRANSFERT [=32] max bytes to transmit by SDO" + echo " --SDO_MAX_SIMULTANEOUS_TRANSFERTS [=4] Number of SDO that the node can manage concurrently" + echo " --NMT_MAX_NODE_ID [=128] can be reduced to gain memory on small network" + echo " --SDO_TIMEOUT_MS [=3000] Timeout in milliseconds for SDO (None to disable the feature)" + exit 0;; + *) echo "Unknown argument ${1}"; exit -1;; + esac + + shift +done + +if [ "$DISABLE_JAXE" = "1" ]; then + SUB_OPT_JAXE= +else + which java >/dev/null 2>&1 + if (( $? )); then + SUB_OPT_JAXE= + echo "Could not find java VM ! Jaxe XML editor disabled !" + else + SUB_OPT_JAXE=jaxe + fi +fi +########################################################################### +# DEFAULT TARGET/DRIVERS GUESSING # +########################################################################### +# If target not specified, try to gess one +if [ "$SUB_TARGET" = "" ]; then + SUB_TARGET=generic +fi + +# If target generic, try to gess can +if [ "$SUB_TARGET" = "generic" -a "$SUB_CAN_DRIVER" = "" ]; then + if [ -e /usr/lib/libpcan.so ]; then + echo "Choosing installed Peak driver as CAN driver." + SUB_CAN_DRIVER=peak + else + echo "Choosing virtual CAN driver." + SUB_CAN_DRIVER=virtual + SUB_LED_ENABLE=YES + fi +fi + +# If target generic, try to gess timers +if [ "$SUB_TARGET" = "generic" -a "$SUB_TIMERS_DRIVER" = "" ]; then + echo "Choosing unix timers driver." + SUB_TIMERS_DRIVER=unix +fi + +if [ "$SUB_CAN_DRIVER" = "peak" ]; then + if [ ! -e /usr/lib/libpcan.so ]; then + echo "Peak driver hasn't been installed !" + exit -1 + fi +fi + +########################################################################### +# GUESS OS/ARCH # +########################################################################### + +if [ "$SUB_OS_NAME" = "" ]; then + SUB_OS_NAME="`(uname -s | sed \"s/\//-/\" | sed \"s/_/-/\" \ + | sed \"s/-.*//g\") 2>&1`" +fi +if [ "$SUB_OS_NAME" = "HP" -o "$SUB_OS_NAME" = "HP-UX" ]; then + SUB_OS_NAME=HPUX +fi + +if [ "$SUB_ARCH_NAME" = "" ]; then + if [ "$CC" = "" ]; then + A_NAME="`(uname -m) 2>&1`" + else + A_NAME="`$CC -dumpmachine | sed 's:-.*::'`" + fi +fi + +# x86 +if [ "$A_NAME" = "i386" ]; then + SUB_ARCH_NAME=x86 +fi +if [ "$A_NAME" = "i486" ]; then + SUB_ARCH_NAME=x86 +fi +if [ "$A_NAME" = "i586" ]; then + SUB_ARCH_NAME=x86 +fi +if [ "$A_NAME" = "i686" ]; then + SUB_ARCH_NAME=x86 +fi +if [ "$A_NAME" = "x86" ]; then + SUB_ARCH_NAME=x86 +fi + +# x86_64 +if [ "$A_NAME" = "x86_64" ]; then + SUB_ARCH_NAME=x86_64 +fi + +# ia64 +if [ "$A_NAME" = "ia64" ]; then + SUB_ARCH_NAME=ia64 +fi + +# alpha +if [ "$A_NAME" = "alpha" ]; then + SUB_ARCH_NAME=alpha +fi + +# parisc +if [ "$A_NAME" = "parisc" ]; then + SUB_ARCH_NAME=parisc +fi +if [ "$SUB_OS_NAME" = "HPUX" -a "$A_NAME" != "ia64" ]; then + # If we're on HP-UX and the architecture is *not* ia64, + # it's most likely parisc + SUB_ARCH_NAME=parisc +fi + +# sparc +if [ "$A_NAME" = "sparc" ]; then + SUB_ARCH_NAME=sparc +fi +if [ "$A_NAME" = "sun4u" ]; then + SUB_ARCH_NAME=sparc +fi + +# sparc64 +if [ "$A_NAME" = "sparc64" ]; then + SUB_ARCH_NAME=sparc64 +fi + + +# +# The following has not been verified +# + +# ppc +if [ "$A_NAME" = "powerpc" ]; then + SUB_ARCH_NAME=ppc +fi + +# ppc64 +if [ "$A_NAME" = "powerpc64" ]; then + SUB_ARCH_NAME=ppc64 +fi + +# arm +if [ "$A_NAME" = "arm" ]; then + SUB_ARCH_NAME=arm +fi + +# mips3 +if [ "$A_NAME" = "ip32" ]; then # IRIX + SUB_ARCH_NAME=mips3 +fi +if [ "$A_NAME" = "ip35" ]; then # IRIX + SUB_ARCH_NAME=mips3 +fi + +# mips32 +if [ "$A_NAME" = "mips32" ]; then + SUB_ARCH_NAME=mips32 +fi +if [ "$A_NAME" = "mips" ]; then + SUB_ARCH_NAME=mips32 +fi +if [ "$A_NAME" = "MIPS" ]; then + SUB_ARCH_NAME=mips32 +fi +if [ "$A_NAME" = "RISC" ]; then # MIPS Ultrix + SUB_ARCH_NAME=mips32 +fi + +# mips64 +if [ "$A_NAME" = "mips64" ]; then + SUB_ARCH_NAME=mips64 +fi +if [ "$A_NAME" = "MIPS64" ]; then + SUB_ARCH_NAME=mips64 +fi +if [ "$A_NAME" = "IP64" ]; then # IRIX + SUB_ARCH_NAME=mips64 +fi + +# power +if [ "$A_NAME" = "power" ]; then # Manual + SUB_ARCH_NAME=power +fi + +echo "Using OS: ${SUB_OS_NAME}" +echo "Using architecture: ${SUB_ARCH_NAME}" + +if [ "$SUB_ARCH_NAME" = "" ]; then + echo "Error: could not detect what architecture this system is running!" + echo "Please supply manually instead with \"--arch=foo\"" + exit -1 +fi + +if [ "$SUB_OS_NAME" = "HPUX" -a "$CC" = "gcc" ]; then + # Only if we are on HP-UX, ia64 and using gcc + SUB_PROG_CFLAGS=-mlp64 +fi + +if [ "$SUB_OS_NAME" = "SunOS" -a "$SUB_ARCH_NAME" = "sparc" -a "$CC" = "gcc" ]; then + # Only if we are on SunOS, sparc and using gcc + # Tells the assembler that we are dealing with a v8plusa arch sparc + # and -mimpure-text is needed for shared library linking + SUB_PROG_CFLAGS="-Wa,-xarch=v8plusa -mimpure-text" +fi + +if [ "$SUB_OS_NAME" = "AIX" -a "$SUB_ARCH_NAME" = "power" -a "$CC" = "gcc" ]; then + # Only if we are on AIX, power and using gcc + # The assembler may default to generating Power and PowerPC compatible + # code. We need to override that. + SUB_PROG_CFLAGS=-Wa,-mpwr +fi + +if [ "$SUB_OS_NAME" = "AIX" -a "$SUB_ARCH_NAME" = "ppc" -a "$CC" = "gcc" ]; then + # Only if we are on AIX, ppc and using gcc + # The assembler may default to generating Power and PowerPC compatible + # code. We need to override that. + SUB_PROG_CFLAGS=-Wa,-mppc +fi + +if [ "$SUB_ARCH_NAME" = "x86_64" -a "$CC" = "gcc" ]; then + # Only if we are on x86_64 and using gcc + # For shared library generation, it needs this + SUB_PROG_CFLAGS=-fPIC +fi + +########################################################################### +# TARGET/DRIVER SPECIFIC CFLAGS and OPTIONS # +########################################################################### +if [ "$SUB_TARGET" = "hcs12" ]; then + # Only if we want to compile for a µC HCS12 + # search for gcc hcs12 compiler m6811-elf-gcc or m68hc12-gcc ? + if [ "$CC" = "" ]; then + which m6811-elf-gcc >/dev/null 2>&1 + if (( $? )); then + which m68hc12-gcc >/dev/null 2>&1 + if (( $? )); then + echo "Please use --cc flag to specify compiler" + exit 0 + else + CC=m68hc12-gcc + fi + else + CC=m6811-elf-gcc + SUB_PROG_CFLAGS=-m68hc12 + fi + fi + # hcs12 driver implement its own timers + SUB_TIMERS_ENABLE=YES +fi + +if [ "$SUB_TARGET" = "ecos_lpc2138_sja1000" ]; then + # search for gcc arm compiler arm-elf-gcc or arm-elf-gcc ? + if [ "$CC" = "" ]; then + which arm-elf-gcc >/dev/null 2>&1 + if (( $? )); then + echo "error : Could not find arm-elf-gcc" + else + CC=arm-elf-gcc + SUB_PROG_CFLAGS="-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Os \ + -ffunction-sections -fdata-sections -fno-exceptions -finline-functions" + fi + fi + # ecos sja1000 driver implements calls needed by LSS. + SUB_LSS_ENABLE=YES + SUB_LED_ENABLE=YES + SUB_NVRAM_ENABLE=YES + # ecos driver implement its own timers + SUB_TIMERS_ENABLE=NO +# SUB_TIMERS_DRIVER=ecos +# SUB_CAN_DRIVER=ecos_lpc2138_sja1000 + +fi + + +#### CAN_DRIVER #### + +if [ "$SUB_CAN_DRIVER" = "peak" ]; then + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpcan +fi + +if [ "$SUB_CAN_DRIVER" = "ecos_lpc2138_sja1000" ]; then + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ +fi + + +#### TIMERS_DRIVER #### + +if [ "$SUB_TIMERS_DRIVER" = "ecos" ]; then + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -llpthread +fi + +if [ "$SUB_TIMERS_DRIVER" = "unix" ]; then + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpthread +fi + +if [ "$SUB_TIMERS_DRIVER" = "xeno" ]; then + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lnative\ +\ -L`$XENO_CONFIG --library-dir` + SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ `$XENO_CONFIG --xeno-cflags` +fi + +########################################################################### +# GUESS COMPILER # +########################################################################### +# If CC is empty, the user wanted automatic detection +if [ "$CC" = "" ]; then + # Check for second compiler, CC2 + cat > $test.c <&1`" = ""; then + DETECTCC=$CC2 + echo "Checking for ${CC2}... Yes." + else + echo "Checking for ${CC2}... No." + fi + rm -f $test.c $test.o + + # Check for first compiler, CC1 + cat > $test.c <&1`" = ""; then + DETECTCC=$CC1 + echo "Checking for ${CC1}... Yes." + else + echo "Checking for ${CC1}... No." + fi + rm -f $test.c $test.o + CC=$DETECTCC +fi +# Check if we decided on a compiler after all +if [ "$CC" = "" ]; then + echo "Error: Could not find a C compiler" + echo "Please supply the wanted compiler" + exit -1 +fi + +echo "Using ${CC}" + +########################################################################### +# GUESS PREFIX's # +########################################################################### + +SUB_BINUTILS_PREFIX=`echo "$CC" | sed 's/gcc$//'` + +# Guess prefix as regard cross compiling target machine +if [ "$SUB_PREFIX" = "" ]; then + $CC -dumpspecs |grep -A 1 'cross_compile'|grep -q 1 + if (( $? )); then + SUB_PREFIX=/usr/local + echo "Not cross-compiling. Will install in $SUB_PREFIX"; + else + SUB_PREFIX=/usr/`$CC -dumpmachine` + echo "This is a cross-compiler. Will install in $SUB_PREFIX"; + fi +fi + +echo "Using prefix: ${SUB_PREFIX}" + +########################################################################### +# CANFESTIVAL DEFINES --> config.h # +########################################################################### +# Some CONSTANTS preparation +if [ "$CANOPEN_BIG_ENDIAN" = "" ]; then + CANOPEN_LITTLE_ENDIAN=1 +else + CANOPEN_LITTLE_ENDIAN= +fi + +# Create include/config.h with the relevant contents +rm -f include/config.h +echo "/*"\ > include/config.h +echo "This file is part of CanFestival, a library implementing CanOpen Stack." >> include/config.h +echo "" >> include/config.h +echo "Copyright (C): Edouard TISSERANT and Francis DUPIN" >> include/config.h +echo "See COPYING file for copyrights details." >> include/config.h +echo "" >> include/config.h +echo "This library is free software; you can redistribute it and/or" >> include/config.h +echo "modify it under the terms of the GNU Lesser General Public" >> include/config.h +echo "License as published by the Free Software Foundation; either" >> include/config.h +echo "version 2.1 of the License, or (at your option) any later version." >> include/config.h +echo "" >> include/config.h +echo "This library is distributed in the hope that it will be useful," >> include/config.h +echo "but WITHOUT ANY WARRANTY; without even the implied warranty of" >> include/config.h +echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU" >> include/config.h +echo "Lesser General Public License for more details." >> include/config.h +echo "" >> include/config.h +echo "You should have received a copy of the GNU Lesser General Public" >> include/config.h +echo "License along with this library; if not, write to the Free Software" >> include/config.h +echo "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA" >> include/config.h +echo "*/" >> include/config.h +echo "" >> include/config.h +echo "#ifndef _CONFIG_H_" >> include/config.h +echo "#define _CONFIG_H_" >> include/config.h +echo "" >> include/config.h +for i in \ + MAX_CAN_BUS_ID\ + SDO_MAX_LENGTH_TRANSFERT\ + SDO_MAX_SIMULTANEOUS_TRANSFERTS\ + NMT_MAX_NODE_ID\ + SDO_TIMEOUT_MS\ + MAX_NB_TIMER\ + CANOPEN_BIG_ENDIAN\ + CANOPEN_LITTLE_ENDIAN ; do +if [ "${!i}" = "" ]; then +echo "// $i is not defined" >> include/config.h +else +echo "#define $i ${!i}" >> include/config.h +fi +done +echo "" >> include/config.h +echo "#endif /* _CONFIG_H_ */" >> include/config.h + +########################################################################### +# DEBUG DEFINES/CFLAGS # +########################################################################### +if [ "$DEBUG" != "" ]; then + SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -DDEBUG_CAN\ -DDEBUG_WAR_CONSOLE_ON\ -DDEBUG_ERR_CONSOLE_ON\ -g +fi + +if [ "$DEBUG" = "PDO" ]; then + SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -DPDO_ERROR +fi + +if [ "$DISABLE_OPT" = "1" ]; then + SUB_OPT_CFLAGS= +else + SUB_OPT_CFLAGS=\$\(OPT_CFLAGS\) +fi + +########################################################################### +# CREATE MAKEFILES # +########################################################################### +MAKEFILES=Makefile.in\ +\ src/Makefile.in\ +\ drivers/Makefile.in\ +\ objdictgen/Makefile.in\ +\ examples/Makefile.in + +if [ "$SUB_TARGET" = "hcs12" ]; then + MAKEFILES=$MAKEFILES\ +\ drivers/hcs12/Makefile.in\ +\ examples/AppliMaster_HCS12/Makefile.in\ +\ examples/AppliSlave_HCS12/Makefile.in\ +\ examples/gene_SYNC_HCS12/Makefile.in +fi + +if [ "$SUB_TIMERS_DRIVER" != "" ]; then + MAKEFILES=$MAKEFILES\ +\ drivers/timers_$SUB_TIMERS_DRIVER/Makefile.in +fi + +if [ "$SUB_CAN_DRIVER" != "" ]; then + MAKEFILES=$MAKEFILES\ +\ drivers/can_$SUB_CAN_DRIVER/Makefile.in +fi + +if [ "$SUB_TARGET" = "generic" ]; then + MAKEFILES=$MAKEFILES\ +\ drivers/generic/Makefile.in\ +\ examples/AppliMaster_Linux/Makefile.in\ +\ examples/AppliSlave_Linux/Makefile.in\ +\ examples/TestMasterSlave/Makefile.in +fi + +if [ "$SUB_TARGET" = "ecos_lpc2138_sja1000" ]; then + MAKEFILES=$MAKEFILES\ +\ drivers/ecos_lpc2138_sja1000/Makefile.in\ +\ examples/ecos_lpc2138_sja1000/src/Makefile.in +fi + +for makefile_in in $MAKEFILES; do + makefile=`echo $makefile_in | sed 's:.in$::'` + echo "Creating $makefile" + sed < $makefile_in " + s:SUB_CC:${CC}: + s:SUB_PROG_CFLAGS:${SUB_PROG_CFLAGS}: + s:SUB_EXE_CFLAGS:${SUB_EXE_CFLAGS}: + s:SUB_PREFIX:${SUB_PREFIX}: + s:SUB_OS_NAME:${SUB_OS_NAME}: + s:SUB_ARCH_NAME:${SUB_ARCH_NAME}: + s:SUB_OPT_CFLAGS:${SUB_OPT_CFLAGS}: + s:SUB_TARGET:${SUB_TARGET}: + s:SUB_BINUTILS_PREFIX:${SUB_BINUTILS_PREFIX}: + s:SUB_OPT_JAXE:${SUB_OPT_JAXE}: + s:SUB_LSS_ENABLE:${SUB_LSS_ENABLE}: + s:SUB_LED_ENABLE:${SUB_LED_ENABLE}: + s:SUB_NVRAM_ENABLE:${SUB_NVRAM_ENABLE}: + s:SUB_TIMERS_ENABLE:${SUB_TIMERS_ENABLE}: + s:SUB_TIMERS_DRIVER:timers_${SUB_TIMERS_DRIVER}: + s:SUB_CAN_DRIVER:can_${SUB_CAN_DRIVER}: + " > $makefile +done + +echo "All done." diff -r 000000000000 -r 4472ee7c6c3e doc/301_v04000201.pdf Binary file doc/301_v04000201.pdf has changed diff -r 000000000000 -r 4472ee7c6c3e doc/CANOpen_memento.odg Binary file doc/CANOpen_memento.odg has changed diff -r 000000000000 -r 4472ee7c6c3e doc/about.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/about.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,36 @@ + + +
+ +

+CanFestival is an OpenSource (LGPL) CANOpen framework. +

+http://canfestival.sourceforge.net +

+Copyright ©: Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +

+Version: CAN Festival 3.0 +

+ + + + + + + + + +
+ Contributor : + + LIVIC
+ http://www.inrets.fr/ur/livic +
+ Supported by : + + LOLITech
+ http://www.lolitech.fr +
+
+ + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e doc/architecture.sxd Binary file doc/architecture.sxd has changed diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival.gif Binary file doc/canfestival.gif has changed diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/canfestival.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,11 @@ + + +
+ +


+ +


+ +
+ + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival_CAN.png Binary file doc/canfestival_CAN.png has changed diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival_CAN_interface.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/canfestival_CAN_interface.svg Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,826 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + SCHEDULINGtimer.cTimeDispatch + + CanFestival Library + + + + + + + Application + + + Callbacks + + + + + CANDISPATCHINGstates.ccanDispatch + + + + + + + + + CanFestival interface to CAN + Because most CAN controllers and drivers implement FIFOs, CanFestival consider sending message as a non bloking operation.In order to prevent reentrent calls to the stack, messages reception is implemented differently on µC and OS.:- µC must provide interuption masking for timer and can receive IT- OS must provide a receive thread, a timer thread and a mutex. CAN reception is a bloking operation. + + + CAN DRIVERINTERFACE(can_xxx.c)canSendcanReceiveLoop + + HW interfaces (for OS) + + + mutex + + + + SYSTEM TIMERSINTERFACE(timers_xxx.c)CreateReceiveTaskTimerLoop + + + + CANreceivethread + + + + HW interfaces (for µC) + + + CAN DRIVERINTERFACE(can_xxx.c)canSendcanReceiveLoop + + + + SYSTEM TIMERSINTERFACE(timers_xxx.c)CreateReceiveTaskTimerLoop + + + + CANreceiveIRQ + + + + + + TIMERIRQ + + + + + + Timerthread + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival_overview.png Binary file doc/canfestival_overview.png has changed diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival_overview.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/canfestival_overview.svg Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1211 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + Implementation overview + + HWinterfaces + + + + + + + + + + (GUI generated .c+.h file,one per node,to compile and link with your code) + Node DATA CO_Datadata.h + OBJECT DICTIONARY + + + + + + SCHEDULINGtimer.c + + + + OD ACCESSobjaccess.c + + HardwareAbstactionLayer + CanFestival Library + CanOpen Protocols + Node Management + + + + + + + + + + STATE MACHINEstates.c + CanDispatch + + + + + + + + + SERVICE DATA OBJECTSsdo.c + + + + PROCESS DATA OBJECTSpdo.c + + + + NETWORK MANAGEMENTnmtMaster.c + nmtSlave.c + + + + SYNCHRONIZATIONsync.c + + + + CAN DRIVERINTERFACEcan_xxx.c + RCV + TRS + + + + SYSTEM TIMERSINTERFACEtimers_xxx.c + + + + + PERSITANT STORAGEnvram.c + + + + + LED INDICATORSled.c + + + + PERSISTANTSTORAGE INTERFACEnvram_xxx.c + + + + LEDINTERFACEled_xxx.c + + + + + + AUTO CAN BAUDRATElss.c + + Application(master/slave) + + + + Optional:- NVRAM- LED- CAN LSS supportInterfaces can be provideddirectly by application. + libcanfestival_$(TARGET).a + libcanfestival.a + + Mandatory:- Declare nodes callbacks- Open CAN interfaces- Initiate TImersEach call to the CanFestival API provide a pointer to the related node's CO_Data struct.In order to respect data integrity in the stack, all calls to the API should be made from mandatory nodes callback. + + + + + Node Callbacks:SDOtimeoutErrorheartbeatErrorcanSendinitialisationpreOperationaoperationalstoppedpost_syncpost_TPDO + + + + NodesInitialisationCalled atinitialisationof stack,once CANinterfacesopened. + + + diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival_scheduling.png Binary file doc/canfestival_scheduling.png has changed diff -r 000000000000 -r 4472ee7c6c3e doc/canfestival_scheduling.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/canfestival_scheduling.svg Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,855 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + CanFestival Scheduling + + + + + + Alarm A value + + + + + + + + + + + Alarm Bvalue + Alarm Bperiod + + Alarm Bperiod + + + + + Alarm Bperiod + Alarm Bperiod + + + Clock range + t0 + t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + Clock value + Time + + A CanOpen must be able to take delayed actions. As exemples, periodic sync emission, heartbeat production or SDO timeout need to set some alarms that will be called later and do the job.µC generaly do not have many anough free timers to handle all the CanOpen needs directly. Moreover, CanFestival internal data may be corrupt by reentrant calls. CanFestival implement a mini-scheduler (timer.c). It uses only one timer to mimic many timers. It manage an alarm table, and call alarms at time.Scheduler can handle short clock value ranges limitation found on some µC. As an example, value range for a 16bit clock counter with 4µs tick is crossed within 0.26 seconds... Long alarms must be segmented.Chronogram illustrate a long alarm (A) and a short periodic alarm (B), with a A value > clock range > B value. Values t0...t8 are successive setTimer values. t1 illustrates an intermediate call to TimeDispatch, caused by a delay longer than clock range. At the end of t1, TimeDispatch call will not trig any alarm callback. + + + HW interfaces + + + + + SCHEDULINGtimer.cSetAlarmDelAlarmTimeDispatch + + + + SYSTEM TIMERSINTERFACE(timers_xxx.c)setTimergetElapsedTime + + + + + + + + + + + + + + + + + + + + + + CanFestival Library + + + + + + + + + + + + Application + + + Callbacks + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e doc/code_debug.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/code_debug.txt Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,49 @@ + +# Debug and warning codes +------------------------- + +Errors are managed by the macro +MSG_ERR(nbr, string, value) + +Warnings and Informations are managed by the macro +MSG_WAR(nbr, string, value) + + + +The format of nbr +++++++++++++++++++++ +16 bits, writen in hexadecimal: 0xtfxx + +t : 1 -> Error + 2 -> Warning + 3 -> Information + +f : 0 -> In file sync.c + 1 -> lifegrd.c + 2 -> objacces.c + 3 -> timer.c + 4 -> nmtSlave.c + 5 -> nmtMaster.c + 6 -> canOpenDriver.c, interrupt.c, variahw.c (errors nb 20 .. 30) + 7 -> initObjdict.c + 8 -> Maps_module_utilisé.cpp + 9 -> pdo.c + A -> sdo.c + B -> objacces.c + D -> user's application + E -> user's application + F -> user's application + +xx : a number + + +The format of string +++++++++++++++++++++ +A string, ended by a space, whithout a newline + +The format of value +++++++++++++++++++++ +Unsigned 32 bits or less + + + diff -r 000000000000 -r 4472ee7c6c3e doc/manual/en/manual.odt Binary file doc/manual/en/manual.odt has changed diff -r 000000000000 -r 4472ee7c6c3e drivers/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e drivers/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,80 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +TARGET = SUB_TARGET +CAN_DRIVER = SUB_CAN_DRIVER +TIMERS_DRIVER = SUB_TIMERS_DRIVER + +all: driver + +driver: +ifneq ($(TIMERS_DRIVER),timers_) + $(MAKE) -C $(TIMERS_DRIVER) $@ +endif + +ifneq ($(CAN_DRIVER),can_) + $(MAKE) -C $(CAN_DRIVER) $@ +endif + $(MAKE) -C $(TARGET) $@ + +install: +ifneq ($(TIMERS_DRIVER),timers_) + $(MAKE) -C $(TIMERS_DRIVER) $@ +endif + +ifneq ($(CAN_DRIVER),can_) + $(MAKE) -C $(CAN_DRIVER) $@ +endif + $(MAKE) -C $(TARGET) $@ + +uninstall: +ifneq ($(TIMERS_DRIVER),timers_) + $(MAKE) -C $(TIMERS_DRIVER) $@ +endif + +ifneq ($(CAN_DRIVER),can_) + $(MAKE) -C $(CAN_DRIVER) $@ +endif + $(MAKE) -C $(TARGET) $@ + +clean: +ifneq ($(TIMERS_DRIVER),timers_) + $(MAKE) -C $(TIMERS_DRIVER) $@ +endif + +ifneq ($(CAN_DRIVER),can_) + $(MAKE) -C $(CAN_DRIVER) $@ +endif + $(MAKE) -C $(TARGET) $@ + +mrproper: clean +ifneq ($(TIMERS_DRIVER),timers_) + $(MAKE) -C $(TIMERS_DRIVER) $@ +endif + +ifneq ($(CAN_DRIVER),can_) + $(MAKE) -C $(CAN_DRIVER) $@ +endif + $(MAKE) -C $(TARGET) $@ + + diff -r 000000000000 -r 4472ee7c6c3e drivers/can_peak/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_peak/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e drivers/can_peak/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_peak/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,58 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET +CAN_DRIVER = SUB_CAN_DRIVER +TIMERS_DRIVER = SUB_TIMERS_DRIVER + +INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER) + +OBJS = $(CAN_DRIVER).o + +SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h + +TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h + +all: driver + +driver: $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: + mkdir -p $(PREFIX)/include/canfestival + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(TARGET_HFILES) + +clean: + -\rm $(OBJS) + +mrproper: clean diff -r 000000000000 -r 4472ee7c6c3e drivers/can_peak/can_peak.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_peak/can_peak.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,165 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include /* for NULL */ +#include +#include +#include +#include +#include + +/* driver pcan pci for Peak board */ +//#include "libpcan.h" +//#include "pcan.h" + +#include "libpcan.h" // for CAN_HANDLE + +#include +#include "timer.h" +#include "can_driver.h" +#include "timers_driver.h" + +#define MAX_NB_CAN_PORTS 16 + +typedef struct { + char used; + HANDLE fd; + TASK_HANDLE receiveTask; + CO_Data* d; +} CANPort; + +CANPort canports[MAX_NB_CAN_PORTS] = {{0,},}; + +// Define for rtr CAN message +#define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR + +/*********functions which permit to communicate with the board****************/ +UNS8 canReceive(CAN_HANDLE fd0, Message *m) +{ + UNS8 data; + TPCANMsg peakMsg; + if ((errno = CAN_Read(((CANPort*)fd0)->fd, & peakMsg))) { // Blocks until no new message or error. + perror("!!! Peak board : error of reading. (from f_can_receive function) \n"); + return 1; + } + m->cob_id.w = peakMsg.ID; + if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_*/ + m->rtr = 0; + else + m->rtr = 1; + m->len = peakMsg.LEN; /* count of data bytes (0..8) */ + for(data = 0 ; data < peakMsg.LEN ; data++) + m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */ + + return 0; +} + +void canReceiveLoop(CAN_HANDLE fd0) +{ + CO_Data* d = ((CANPort*)fd0)->d; + Message m; + while (1) { + if(!canReceive(fd0, &m)) + { + EnterMutex(); + canDispatch(d, &m); + LeaveMutex(); + }else{ +// printf("canReceive returned error\n"); + break; + } + } +} + +/***************************************************************************/ +UNS8 canSend(CAN_HANDLE fd0, Message *m) +{ + UNS8 data; + TPCANMsg peakMsg; + peakMsg.ID=m -> cob_id.w; /* 11/29 bit code */ + if(m->rtr == 0) + peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_*/ + else { + peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_*/ + } + peakMsg.LEN = m->len; + /* count of data bytes (0..8) */ + for(data = 0 ; data < m->len; data ++) + peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */ + + if((errno = CAN_Write(((CANPort*)fd0)->fd, & peakMsg))) { + perror("!!! Peak board : error of writing. (from canSend function) \n"); + return 1; + } + return 0; + +} + +/***************************************************************************/ +CAN_HANDLE canOpen(s_BOARD *board) +{ + HANDLE fd0 = NULL; + char busname[64]; + char* pEnd; + int i; + + for(i=0; i < MAX_NB_CAN_PORTS; i++) + { + if(!canports[i].used) + break; + } + + if(strtol(board->busname, &pEnd,0) >= 0) + { + sprintf(busname,"/dev/pcan%s",board->busname); + fd0 = LINUX_CAN_Open(busname, O_RDWR); + } + + if (i==MAX_NB_CAN_PORTS || fd0 == NULL) + { + fprintf (stderr, "Open failed.\n"); + return (CAN_HANDLE)NULL; + } + + CAN_Init(fd0, board->baudrate, CAN_INIT_TYPE_ST); + + canports[i].used = 1; + canports[i].fd = fd0; + + canports[i].d = board->d; + CreateReceiveTask((CANPort*) &canports[i], &canports[i].receiveTask); + + return (CANPort*) &canports[i]; +} + +/***************************************************************************/ +int canClose(CAN_HANDLE fd0) +{ + CAN_Close(((CANPort*)fd0)->fd); + ((CANPort*)fd0)->used = 0; + WaitReceiveTaskEnd(&((CANPort*)fd0)->receiveTask); + return 0; +} diff -r 000000000000 -r 4472ee7c6c3e drivers/can_virtual/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_virtual/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,2 @@ +Makefile +*.a diff -r 000000000000 -r 4472ee7c6c3e drivers/can_virtual/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_virtual/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,68 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +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) + + +OBJS = $(CAN_DRIVER).o + +SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h + +TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h + +ifeq ($(LED_ENABLE),YES) +OBJS += led_virtual.o +SRC_HFILES += ../include/led.h +endif + +all: driver + +driver: $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: + mkdir -p $(PREFIX)/include/canfestival + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(TARGET_HFILES) + +clean: + -\rm $(OBJS) + +mrproper: clean diff -r 000000000000 -r 4472ee7c6c3e drivers/can_virtual/can_virtual.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_virtual/can_virtual.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,124 @@ +/* +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 +*/ + +/* + Virtual CAN driver. +*/ + +#include + +#include +#include +#include + +#include +#include "timer.h" +#include "can_driver.h" +#include "timers_driver.h" + +#define MAX_NB_CAN_PIPES 10 + +typedef struct { + char used; + int pipe[2]; + TASK_HANDLE receiveTask; + CO_Data* d; +} CANPipe; + +CANPipe canpipes[MAX_NB_CAN_PIPES] = {{0,{0,0},},}; + +/*********functions which permit to communicate with the board****************/ +UNS8 canReceive(CAN_HANDLE fd0, Message *m) +{ + if(read(((CANPipe*)fd0)->pipe[0], m, sizeof(Message)) < sizeof(Message)) + { + return 1; + } + return 0; +} + +void canReceiveLoop(CAN_HANDLE fd0) +{ + CO_Data* d = ((CANPipe*)fd0)->d; + Message m; + while (1) { + if(!canReceive(fd0, &m)) + { + EnterMutex(); + canDispatch(d, &m); + LeaveMutex(); + }else{ + break; + } + } +} + +/***************************************************************************/ +UNS8 canSend(CAN_HANDLE fd0, Message *m) +{ + int i; + // Send to all readers, except myself + for(i=0; i < MAX_NB_CAN_PIPES; i++) + { + if(canpipes[i].used && &canpipes[i] != (CANPipe*)fd0) + { + write(canpipes[i].pipe[1], m, sizeof(Message)); + } + } + return 0; +} + +/***************************************************************************/ +CAN_HANDLE canOpen(s_BOARD *board) +{ + int i; + for(i=0; i < MAX_NB_CAN_PIPES; i++) + { + if(!canpipes[i].used) + break; + } + + /* Create the pipe. */ + if (i==MAX_NB_CAN_PIPES || pipe(canpipes[i].pipe)) + { + fprintf (stderr, "Open failed.\n"); + return (CAN_HANDLE)NULL; + } + + canpipes[i].used = 1; + + canpipes[i].d = board->d; + CreateReceiveTask((CAN_HANDLE) &canpipes[i], &canpipes[i].receiveTask); + + return (CAN_HANDLE) &canpipes[i]; +} + +/***************************************************************************/ +int canClose(CAN_HANDLE fd0) +{ + close(((CANPipe*)fd0)->pipe[0]); + close(((CANPipe*)fd0)->pipe[1]); + ((CANPipe*)fd0)->used = 0; + WaitReceiveTaskEnd(&((CANPipe*)fd0)->receiveTask); +} + + diff -r 000000000000 -r 4472ee7c6c3e drivers/can_virtual/led_virtual.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_virtual/led_virtual.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,20 @@ +/***************************************************************************/ +#include + +void led_set_redgreen(CO_Data *d, int state) +{ + + printf("LEDS %d\n",bits); + + if (bits & 0x01) + printf("\e[41m ERROR LED ON \e[m\n"); + else + printf("error led off\n"); + + if (bits & 0x02) + printf("\e[34;42m RUN LED ON \e[m\n"); + else + printf("run led off\n"); +} + + diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,97 @@ +#! gmake + +# +# Copyright (C) 2006 OREMEQ +# +# 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 = SUB_OPT_CFLAGS +CFLAGS = +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET +INCLUDES = -I../../include -I../../examples/ecos_lpc2138_sja1000/include + +ECOS_GLOBAL_CFLAGS=-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Os -ffunction-sections -fdata-sections -fno-exceptions -finline-functions +ECOS_GLOBAL_LDFLAGS=-mcpu=arm7tdmi -Wl,--gc-sections -Wl,-static -nostdlib + +export CAN_CONTROLER_CLOCK_SPEED := 24.000 # Crystal frequency of the SJA1000 clock input. +export CAN_CONTROLER_PHASE_SHIFT_TOLERANCE := 3 #Synchronization Jump Width (SJW) (in SJA1000==> 0..3) + #To compensate for phase shifts between + #clock oscillators of different bus + # controllers, any bus controller must + #re-synchronize on any relevant signal + #edge of the current transmission. + + +OBJS = canOpenDriver.o lpc2138.o sja1000.o time_slicer.o +INCLUDE_H = applicfg.h baudrate_table.h canOpenDriver.h lpc2138.h lpc2138_defs.h \ +lpc2138_pinout.h sja1000.h time_slicer.h + +all: driver + +driver: build_baudrate $(OBJS) + +build_baudrate: + gcc -o build_baudrate build_baudrate.c + @echo "Generate The baudrate register structure in canControler.h regarding the" + @echo "SJA1000 clock speed defined in the Makefile, CAN_CONTROLER_CLOCK_SPEED" + ./build_baudrate $(CAN_CONTROLER_CLOCK_SPEED) $(CAN_CONTROLER_PHASE_SHIFT_TOLERANCE) + + +libcandriver.a: $(OBJS) + @echo " " + @echo "*********************************************" + @echo "**Building [libcandriver]" + @echo "*********************************************" + $(BINUTILS_PREFIX)ar rc $@ $(OBJS) + $(BINUTILS_PREFIX)ranlib $@ + +%o: %c + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) -g -c $(ECOS_GLOBAL_CFLAGS) $(INCLUDES) -I. -c -o $@ $< + +%o: %s + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) -c -x assembler-with-cpp $(ECOS_GLOBAL_CFLAGS) $(INCLUDES) -I. -o $@ $< + +install: + mkdir -p $(PREFIX)/lib + ln -s ../../../drivers/ecos_lpc2138_sja1000 $(PREFIX)/lib/driver + +uninstall: + rm -f ../../examples/ecos_lpc2138_sja1000/lib/driver + +clean: + -\rm -f $(OBJS) build_baudrate baudrate_table.h + +mrproper: clean + -\rm ../../lib/ecos_lpc2138_sja1000/libcandriver.a + diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/ReadMe.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/ReadMe.txt Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,247 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + ____ _ _ _ + / ___| / \ | \ | | ___ _ __ ___ _ __ +| | / _ \ | \| |/ _ \| '_ \ / _ \ '_ \ +| |___ / ___ \| |\ | (_) | |_) | __/ | | | + \____/_/ \_\_| \_|\___/| .__/ \___|_| |_| + |_| + ____ _ + / ___|__ _ _ __ __ _ __| | __ _ + | | / _` | '_ \ / _` |/ _` |/ _` | + | |__| (_| | | | | (_| | (_| | (_| | + \____\__,_|_| |_|\__,_|\__,_|\__,_| + + canfestival@canopencanada.ca +/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ + +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 +MARKETING 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 +*/ + + +CanFestival driver for the Philips ARM7 model LPC2138 , with a Philips +SJA1000 CAN controler, and running on the eCOS operating system. + +Driver Features: +Full CANfestival-3 support including: +DS-150/205: CAN Power Management Layer specification (sleep/wake-up) +DS-201: CAN low level layer +DS-301: CANopen Application layer and Communication Profile (basic CANopen specification) +DS-303-1: LED diagnostic usage (led.c) +DS-305: Layer Setting Service (lss.c) to set the baudrateand node ID in a PnP fashion. +NVRAM: Non Volatil Ram (nvram.c) Full support for internal Philips IAT programming FLASH mode + + +To use this driver, you need to proceed to do all these steps. +NB: We choose to leave this driver in .o object code to keep the capability +to make on-the-fly redefinition of some parameters for all examples. + +Step 1 +----------- +Have a developpement workstation. To build everything, we chose to use +an old AMD K6/2-300Mhz running with FreeBSD-5.2-RELEASE freely available +at http://www.freebsd.org/. +To install freebsd, download the two floppy images from +ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/5.2-RELEASE/floppies +and copy them to a simple floppy disk by typeing: + dd if=./image.dd of=/dev/fd0 + dd if=./image2.dd of=/dev/fd0 +and proceed to boot on them. +You can use Linux or Windows also or any other O/S where you can use GCC. + +on FreeBSD, you need to configure the serial port by editing the /etc/rc/serial +config file by adding this entry: + +lpc2000 () { + # Philips LPC2000 serial port configuration for 57600 bauds connection. + + ci=$1; shift + co=$1; shift + + for i in $* + do + # Lock clocal on, hupcl off. + # XON-XOFF printer + stty < /dev/ttyi${ci}${i} clocal -hupcl ixon -imaxbel -ixany -ixoff -crtscts 57600 + stty < /dev/ttyl${ci}${i} clocal hupcl + stty < /dev/cuai${co}${i} clocal -hupcl ixon -imaxbel -ixany -ixoff -crtscts 57600 + stty < /dev/cual${co}${i} clocal hupcl + done +} + +############### +lpc2000 d a 0 1 # to configure COM1 and COM2, mean, /dev/cuaa0 and /dev/cuaa1 +############### + +Step 2 +----------- +Find an upload tool to be able to flash the LPC2138. +We found the lpc2isp at the address: + + http://guest.engelschall.com/~martin/lpc21xx/isp/index.html + + You can use this upload script to call it with proper arguments. + +#!/bin/sh +lpc21isp -term -control build/terminal.hex /dev/cuaa1 57600 14746 + + +Step 3 +----------- +Proceed to build a GCC cross compiler to be able to produce ARM7TDMI compatible +binary. Go to the port directory of your FreeBSD + + cd /usr/ports/devel/arm-elf-binutils + gmake install + + cd /usr/ports/devel/arm-elf-gcc295 + gmake install + +And add the installation binary PATH to your environment variables. + + cd /etc + vi profile + + export PATH=$PATH:/usr/local/armelf/bin + + +Step 4 +----------- +Build an eCOS tree for the LPC2138. +Download eCOS from http://www.ecoscentric.com and proceed to compile +the configtool program. + + cd /usr/ports/devel/ecos-tools/ + gmake install + + untar our special package for eCOS named eCOS-OLIMEX-p2138.tgz in + the eCOS three on your files system. + +Start now your configtool for eCOS: + configtool + +Choose the right target +For our purpose, we choose to use an OLIMEX P2138 target board. +This target is not in the list, we created it from a derivative of +the OLIMEX P2106. We simply selected an other processor in the pulldown menu +of the configtool. The LPC2138. Adjust some memory capacity, and that's it. + +When all you need is properly selected in the configtool, you click on +Save_As and you suggest a name like My2138. +After, you click on Generate Build Tree. + cd My2138_build + gmake depend + gmake + gmake install + And now you have you own eCOS tree for your project in My2138_install + +Step 5 +----------- +Prepare the hardware board for this project. We chose to use an +http://www.olimex.com/ board, the P2138. +Any other LPC2138 evaluation could made the job. +On the P2138 board, we have a little area that we can use to solder +the SJA1000 controler. +See can_controler.gif to know how to solder all wires. + +Warning: If you want to use different GPIO (General Purpose Input Output) +pin to fit with your own project, +you can choose a different one, but you need +to be sure to properly define then in the lpc2138_pinout.h + +Step 6 +----------- +Put the CANfestival-3.tar.gz stuff in My2138_install/src/CANfestival-3 + cd My2138_install/src/CANfestival-3 + ./configure target=ecos-lpc2138-sja1000 + gmake + cd My2138_install/lib + ln -s My2138_install/src/CANfestival-3/src/libcanfestival.a + cd My2138_install/src + ln -s My2138_install/src/CANfestival-3/driver/ecos-lpc2138-sja1000 + +Step 7 +----------- +Now you are ready to build our demo. + cd My2138_install/src/CANfestival-3/examples/DS-406Master_ecos + gmake + + cd My2138_install/src/CANfestival-3/examples/TerminalSlave_ecos + gmake +Step 8 +----------- +To test, upload both .hex file to both targets with lpc21isp and +see the DS-406 absolut rotary encoder transmiting his absolute value to the +terminal. + + For more info about this project, see http://www.oremeq.qc.ca/ +Step 9 +----------- +For your own project, you can copy all the examples files in your own +directory and modify them. + +What is important to understand is: + +driver/ecos_lpc2138_sja1000: + + build_baudrate.c is a commande line tool to generate the proper + timing file for your sja1000 regarding your sja1000 clk. + see the Makefile for adjustment. + + canOpenDriver.c is the only link between the libcanfestival and + the hardware. + f_can_send + f_can_receive + interrupts + nvram_save/load + baudrate + + eCOS-OLIMEX-p2138.tgz eCOS package for the OLIMEX p2138 evaluation board + you have to untar that files in your eCOS three. + + sja1000.c containe only function for initialization or + configuration of the CAN controler. All this stuff is + _not_ use by the libcanfestival. You have to call them + from your main() to enable CAN with your needed configuration. + + hardware init + + lpc2138.c All the basic stuff to run the LPC2138 + iat_flash user programmable internal flash of the lpc2138 + + lpc2138_pinout.h Is your LPC2138 pinout definition. Modify this file + if you want to redefine your pinout affectation. + + time_slicer.c eCOS implementation of the CANfestival scheduler. + settimer + alarm + + applicfg.h is your configuration file for the libcanfestival + + lpc2138_pinout.h define all your GPIO to fit macros. + + +objdictedit: + Objdictedit will produce the dictionary. + Generate your dictionnary. (Or use an already made YourFile.od with + the tool: objdictgen.py + The job is to implement all functions define in the YourFIle.c in + your own project files. + +Enjoye!!!! + Canopen Canada core team + canfestival@canopencanada.ca diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/applicfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/applicfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,108 @@ +/* +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 __APPLICFG_ECOS__ +#define __APPLICFG_ECOS__ + +#include +#include + +// Define the architecture : little_endian or big_endian +// ----------------------------------------------------- +// Test : +// UNS32 v = 0x1234ABCD; +// char *data = &v; +// +// Result for a little_endian architecture : +// data[0] = 0xCD; +// data[1] = 0xAB; +// data[2] = 0x34; +// data[3] = 0x12; +// +// Result for a big_endian architecture : +// data[0] = 0x12; +// data[1] = 0x34; +// data[2] = 0xAB; +// data[3] = 0xCD; + +// Integers +#define INTEGER8 char +#define INTEGER16 short +#define INTEGER24 +#define INTEGER32 long +#define INTEGER40 +#define INTEGER48 +#define INTEGER56 +#define INTEGER64 + +// Unsigned integers +#define UNS8 unsigned char +#define UNS16 unsigned short +#define UNS32 unsigned long +#define UNS24 +#define UNS40 +#define UNS48 +#define UNS56 +#define UNS64 + +// Time unit : us +// Time resolution : 32bits +#define TIMEVAL unsigned int +#define TIMEVAL_MAX 0xffff +#define MS_TO_TIMEVAL(ms) ms*1000 +#define US_TO_TIMEVAL(us) us + +#define HANDLE int + +#if !defined(CAN_HANDLE) +#define CAN_HANDLE void* +#endif + +// Reals +#define REAL32 float +#define REAL64 double + +/// Definition of error and warning macros +// -------------------------------------- +#if defined DEBUG_ERR_CONSOLE_ON || defined DEBUG_WAR_CONSOLE_ON +#include +#endif + +/// Definition of MSG_ERR +// --------------------- +#ifdef DEBUG_ERR_CONSOLE_ON +# define MSG_ERR(num, str, val) \ + printf("%s,%d : 0X%x %s 0X%x \n",__FILE__, __LINE__,num, str, val); +#else +# define MSG_ERR(num, str, val) +#endif + +/// Definition of MSG_WAR +// --------------------- +#ifdef DEBUG_WAR_CONSOLE_ON +# define MSG_WAR(num, str, val) \ + printf("%s,%d : 0X%x %s 0X%x \n",__FILE__, __LINE__,num, str, val); +#else +# define MSG_WAR(num, str, val) +#endif + +#endif diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/build_baudrate.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/build_baudrate.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,126 @@ +#include +#include + + +/* + CiA DS-301, p.20 +*/ +#define MAX_BIT_TIMING 9 +int table_bit_timing_settings[MAX_BIT_TIMING][3] = +{ + {1000, 8, 6}, /* baudrate, number of time quanta per bit, tsync+tseg1 */ + {800, 10, 8}, + {500, 16, 14}, + {250, 16, 14}, + {125, 16, 14}, + {100, 16, 14}, + { 50, 16, 14}, + { 25, 16, 14}, + { 10, 16, 14} +}; + + +void can_timing_registers(double f, int *v) +/* fill the vector v with the proper setting for TIMER 0 and TIMER 1 + regarding the clock and the baudrate */ +{ + int i; + + int BRP, TSEG1, TSEG2; + + double nominal, tq, tscl; + + double tclk = 1 / (f*1e6); /* sec */ + + for(i=0; i + +#include +#include + +#include +#include + +#include "applicfg.h" +#include +#include +#include +#include +#include +#include + +#include "lpc2138_pinout.h" +#include "lpc2138_defs.h" +#include "lpc2138.h" + +#include "sja1000.h" + +#include "time_slicer.h" + + +/* + SEND/RECEIVE +*/ +CAN_HANDLE canOpen(s_BOARD *board) +{ + return NULL; +} + +/***************************************************************************/ +int canClose(CAN_HANDLE fd0) +{ + return 0; +} + +UNS8 canReceive(CAN_HANDLE fd0, Message *m) +/* +Message *m : + typedef struct { + SHORT_CAN cob_id; // l'ID du mesg + UNS8 rtr; // remote transmission request. 0 if not rtr, + // 1 for a rtr message + UNS8 len; // message length (0 to 8) + UNS8 data[8]; // data + } Message; + +Fill the structure "Message" with data from the CAN receive buffer + +return : 0 +*/ +{ +/* + the sja1000 must be set to the PeliCAN mode +*/ + m->cob_id.w = sja1000_read(16) + (sja1000_read(17)<<8); // IO_PORTS_16(CAN0 + CANRCVID) >> 5 + + m->rtr = (sja1000_read(17) >> 4) & 0x01; // (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01; + + m->len = sja1000_read(18); + + m->data[0] = sja1000_read(19); + m->data[1] = sja1000_read(20); + m->data[2] = sja1000_read(21); + m->data[3] = sja1000_read(22); + m->data[4] = sja1000_read(23); + m->data[5] = sja1000_read(24); + m->data[6] = sja1000_read(25); + m->data[7] = sja1000_read(26); + + sja1000_write(CMR, 1<cob_id.w & 0xff); + sja1000_write(17, (m->cob_id.w >> 8) & 0xff); + sja1000_write(18, m->len); + + sja1000_write(19, m->data[0]); // tx data 1 + sja1000_write(20, m->data[1]); // tx data 2 + sja1000_write(21, m->data[2]); // tx data 3 + sja1000_write(22, m->data[3]); // tx data 4 + sja1000_write(23, m->data[4]); // tx data 5 + sja1000_write(24, m->data[5]); // tx data 6 + sja1000_write(25, m->data[6]); // tx data 7 + sja1000_write(26, m->data[7]); // tx data 8 + + sja1000_write(CMR,( (0< 256) + { + iat_flash_write_page(data_addr); + data_len = 0; + data_addr += 256; + } + + memcpy(((char *)data_page)+data_len, data, len); + + data_len += len; + + return 0; +} + + +char nvram_read(int type, int access_attr, void *data) +/* return 0 if successful */ +{ + int len = _get_data_len(type); + + if (data_len+len > 256) + { + data_addr += 256; + iat_flash_read_page(data_addr); + data_len = 0; + } + + memcpy(data, ((char *)data_page)+data_len, len); + + data_len += len; + + return 0; +} + + +/* + LED +*/ + +void led_set_redgreen(unsigned char bits) +{ + lpc2138_redgreenled_set(bits); +} + diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/lpc2138.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/lpc2138.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,373 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include + +#include "applicfg.h" +// #include "objdictdef.h" + +#include "lpc2138_pinout.h" +#include "lpc2138_defs.h" +#include "lpc2138.h" + +#define IAP_LOCATION 0x7ffffff1 + +// define a page of data of 256 bytes +// +short data_len; /* 0 to 256 bytes */ +unsigned int *data_page = NULL; +unsigned int data_addr; + +// local definitons +void ee_erase(unsigned int ,unsigned int[]); //function erases EEPROM +void ee_write_page(unsigned int); //function adds a record in EEPROM +void ee_read_page(unsigned int); //function reads the latest valid record in EEPROM + +typedef void (*IAP)(unsigned int [],unsigned int[]); +IAP iap_entry; + + +/***************************************************************************************/ + +void lpc2138_pinsel_set(int pin, LPC2138_PORT port, int size, int func) +{ + int i; + + for (i = 0; i < size; pin++, i++) + { + /* 2 bits par broche. */ + int shift = (pin - ((pin < 16) ? 0 : 16)) << 1; + + REG32_ADDR pinsel = (port == 1) ? + (REG32_ADDR) P1_PINSEL2_ADDR : ((pin < 16) ? + (REG32_ADDR) P0_PINSEL0_ADDR : (REG32_ADDR) P0_PINSEL1_ADDR); + + *pinsel = (*pinsel & ~(BITMASK_2 << shift)) | (func << shift); + } +} + +void lpc2138_pinsel_clear() +{ + P0_PINSEL0 = 0x00000000; + P0_PINSEL1 = 0x00000000; + P1_PINSEL2 = 0x00000000; +} + + +int lpc2138_printf(void) +{ + return lpc2138_fprintf(stdout); +} + + +int lpc2138_printf_pins(void) +{ + return lpc2138_fprintf_pins(stdout); +} + + +int lpc2138_fprintf(FILE *stream) +{ + return fprintf(stream, + "[p0=0x%08X,p0_iodir=0x%08X,p0_pinsel0=0x%08X,p0_pinsel1=0x%08X," \ + "p1=0x%08X,p1_iodir=0x%08X,p1_pinsel2=0x%08X]", + P0_IOPIN, P0_IODIR, P0_PINSEL0, P0_PINSEL1, + P1_IOPIN, P1_IODIR, P1_PINSEL2); +} + +int lpc2138_fprintf_pins(FILE *stream) +{ + return fprintf(stream, + "[cs_s1d13706=0x%X," \ + "cs_sja1000=0x%X," \ + "wait=0x%X," \ + "bhe=0x%X," \ + "interrupt_sja1000=0x%X," \ + "redgreenled=0x%X," \ + "ale=0x%X," \ + "rd=0x%X," \ + "wr=0x%X," \ + "data=0x%X," \ + "addresses=0x%X]", + lpc2138_cs_s1d13706_get(), + lpc2138_cs_sja1000_get(), + lpc2138_wait_get(), + lpc2138_bhe_get(), + lpc2138_redgreenled_get(), + lpc2138_interrupt_sja1000_get(), + lpc2138_ale_get(), + lpc2138_rd_get(), + lpc2138_wr_get(), + lpc2138_data_get(), + lpc2138_addresses_get()); +} + + +/* + SJA1000 interface +*/ + +unsigned char sja1000_read(unsigned char addr8) +{ + unsigned char data; + + lpc2138_data_set_mode(LPC2138_MODE_OUTPUT); + lpc2138_ale_set(1); + lpc2138_data_set(addr8); + + lpc2138_ale_set(0); + lpc2138_data_set_mode(LPC2138_MODE_INPUT); + + lpc2138_cs_sja1000_set(0); + lpc2138_rd_set(0); + data = lpc2138_data_get(); + data = lpc2138_data_get(); + + lpc2138_rd_set(1); + + lpc2138_cs_sja1000_set(1); + lpc2138_data_set_mode(LPC2138_MODE_OUTPUT); + + return data; +} + + +void sja1000_write(unsigned char addr8, unsigned char data) +{ + lpc2138_data_set_mode(LPC2138_MODE_OUTPUT); + + lpc2138_data_set(addr8); + + lpc2138_ale_set(1); + + lpc2138_ale_set(0); + lpc2138_cs_sja1000_set(0); + lpc2138_wr_set(0); + + lpc2138_data_set(data); + + lpc2138_wr_set(1); + lpc2138_cs_sja1000_set(1); + +} + +/* + FLASH interface +*/ + +/************************************************************************/ +/* */ +/* function: */ +/* void ee_erase(unsigned int command_ee,unsigned int result_ee[]) */ +/* */ +/* type: void */ +/* */ +/* parameters: */ +/* command_ee - Not used. */ +/* result_ee[0] - Returns a response to the last IAP command used. */ +/* 0 - EEPROM successfully erased. */ +/* For all other response values, see microcontroller */ +/* User Manual, IAP Commands and Status Codes Summary. */ +/* result_ee[1] - Not used. */ +/* */ +/* version: 1.1 (01/27/2006) */ +/* */ +/* constants defined in LPC2k_ee.h used in this function: */ +/* EE_SEC_L - microcontroller's Flash sector where EEPROM begins */ +/* EE_SEC_H - microcontroller's Flash sector where EEPROM ends */ +/* EE_CCLK - microcontroller's system clock (cclk) */ +/* */ +/* description: */ +/* This function erases LPC2000 on-chip Flash sectors selected to act */ +/* as an EEPROM. All Flash sectors between EE_SEC_L abd EE_SEC_H */ +/* (including these sectors) will be erased using the In Application */ +/* Programming (IAP) routines (see User Manual for more details). */ +/* Also, this function disables all interrupts while erasing the */ +/* EEPROM. If this is not needed, three lines of the ee_erase */ +/* subroutine can simply be commented-out without affecting the */ +/* routine performance at all. */ +/* */ +/* revision history: */ +/* - Rev. 1.1 adds interrupt disable feature. */ +/* */ +/************************************************************************/ +void iat_flash_erase(unsigned int command_ee,unsigned int result_ee[]) +{ + unsigned int command_iap[5]; + unsigned int result_iap[3]; + unsigned long int enabled_interrupts; + + enabled_interrupts = VICIntEnable; //disable all interrupts + VICIntEnClr = enabled_interrupts; + + command_iap[0]=50; // prepare sectors from EE_SEC_L to EE_SEC_H for erase + command_iap[1]=EE_SEC_L; + command_iap[2]=EE_SEC_H; + iap_entry=(IAP) IAP_LOCATION; + iap_entry(command_iap,result_iap); + + command_iap[0]=52; // erase sectors from EE_SEC_L to EE_SEC_H + command_iap[1]=EE_SEC_L; + command_iap[2]=EE_SEC_H; + command_iap[3]=EE_CCLK; + iap_entry=(IAP) IAP_LOCATION; + iap_entry(command_iap,result_iap); + + command_iap[0]=53; // blankcheck sectors from EE_SEC_L to EE_SEC_H + command_iap[1]=EE_SEC_L; + command_iap[2]=EE_SEC_H; + iap_entry=(IAP) IAP_LOCATION; + iap_entry(command_iap,result_iap); + + VICIntEnable = enabled_interrupts; //restore interrupt enable register + + result_ee[0]=result_iap[0]; + return; +} + +/************************************************************************/ +/* */ +/* function: */ +/* void ee_write(unsigned int command_ee,unsigned int result_ee[]) */ +/* */ +/* type: void */ +/* */ +/* parameters: */ +/* command_ee - An address of a content of ee_data type that has */ +/* to be programmed into EEPROM. */ +/* result_ee[0] - Returns a response to the last IAP command used. */ +/* 0 - data successfully programmed in EEPROM. */ +/* 501 - no space in EEPROM to program data. */ +/* For all other response values, see microcontroller */ +/* User Manual, IAP Commands and Status Codes Summary. */ +/* result_ee[1] - Not used. */ +/* */ +/* version: 1.1 (01/27/2006) */ +/* */ +/* constants defined in LPC2k_ee.h used in this function: */ +/* EE_BUFFER_SIZE - IAP buffer size; must be 256 or 512 */ +/* NO_SPACE_IN_EEPROM - EEPROM is full and no data can be programmed */ +/* EE_BUFFER_MASK - parameter used for interfacing with IAP */ +/* EE_REC_SIZE - ee_data structure size in bytes */ +/* EE_SEC_L - micro's Flash sector where EEPROM begins */ +/* EE_SEC_H - micro's Flash sector where EEPROM ends */ +/* EE_CCLK - micro's system clock (cclk) */ +/* */ +/* description: */ +/* This function writes a single structure of ee_data type into the */ +/* EEPROM using an In Application Programming (IAP) routines (see */ +/* User Manual for more details). command_ee contains an address of */ +/* this structure. EEPROM is scanned for the last (if any) record */ +/* identifier (EE_REC_ID), and a new record is added next to it. */ +/* Also, this function disables all interrupts while erasing the */ +/* EEPROM. If this is not needed, three lines of the ee_write */ +/* subroutine can simply be commented-out without affecting the */ +/* routine performance at all. */ +/* */ +/* revision history: */ +/* - Rev. 1.1 fixes a bug related to verifying a content written into */ +/* the EEPROM. 1.0 was reporting missmatch even when there were no */ +/* problems at all. */ +/* Rev. 1.1 adds interrupt disable feature. */ +/* */ +/************************************************************************/ + +void iat_flash_write_page(unsigned int addr) +{ + unsigned long int enabled_interrupts; + // unsigned char ee_buffer[16]; + unsigned int command_iap[5], result_iap[3]; + + enabled_interrupts = VICIntEnable; //disable all interrupts + VICIntEnClr = enabled_interrupts; + + iap_entry = (IAP) IAP_LOCATION; + + // prepare sectors from EE_SEC_L to EE_SEC_H for erase + command_iap[0] = 50; + command_iap[1] = EE_SEC_L; + command_iap[2] = EE_SEC_H; + iap_entry(command_iap, result_iap); + + // copy RAM to flash/eeprom + command_iap[0] = 51; + command_iap[1] = (unsigned int) (addr & EE_START_MASK); // 256 kb boundary + command_iap[2] = (unsigned int) (data_page); // should be on a word boundary + command_iap[3] = 256; + command_iap[4] = EE_CCLK; + iap_entry(command_iap, result_iap); + +#if 0 + // compare RAM and flash/eeprom + command_iap[0] = 56; + command_iap[1] = (unsigned int) data; + command_iap[2] = addr; + command_iap[3] = dlen; + iap_entry(command_iap, result_iap); +#endif + + VICIntEnable = enabled_interrupts; //restore interrupt enable register +} + + +/************************************************************************/ +/* */ +/* function: */ +/* void ee_read(unsigned int command_ee,unsigned int result_ee[]) */ +/* */ +/* type: void */ +/* */ +/* parameters: */ +/* command_ee - Not used. */ +/* result_ee[0] - Returns a response. */ +/* 0 - data successfully found in EEPROM. */ +/* 500 - no data/records available in EEPROM. */ +/* result_ee[1] - an address of the last record of ee_data type */ +/* in EEPROM. */ +/* */ +/* version: 1.1 (01/27/2006) */ +/* */ +/* constants defined in LPC2k_ee.h used in this function: */ +/* NO_RECORDS_AVAILABLE - EEPROM is empty/no records identifiable */ +/* with a record identifier (EE_REC_ID) found */ +/* EE_ADR_L - micro's Flash address from where EEPROM begins */ +/* EE_REC_SIZE - size (in bytes) of a ee_data structure */ +/* */ +/* description: */ +/* This function scans an EEPROM content looking for the last record */ +/* that can be identified with a record identifier (EE_REC_ID). When */ +/* such data is found, its address is passed as result_ee[1]. */ +/* */ +/* revision history: */ +/* - Rev. 1.0 had problems with accessing the last record in a fully */ +/* occupied EEPROM. Rev. 1.1 fixes this. */ +/* */ +/************************************************************************/ +void iat_flash_read_page(unsigned int addr) +{ + memcpy(data_page, (unsigned int *)addr, sizeof(unsigned int)*64); +} + + + + diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/lpc2138.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/lpc2138.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,51 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +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 +*/ + + +#if !defined(_LPC2138_H_) +#define _LPC2138_H_ + + +extern short data_len; +extern unsigned int *data_page; +extern unsigned int data_addr; + + +void lpc2138_pinsel_set(int pin, LPC2138_PORT port, int size, int func); +void lpc2138_pinsel_clear(void); + +int lpc2138_printf(void); +int lpc2138_printf_pins(void); + +int lpc2138_fprintf(FILE *stream); +int lpc2138_fprintf_pins(FILE *stream); + +unsigned char sja1000_read(unsigned char addr8); +void sja1000_write(unsigned char addr8, unsigned char data); + +void iat_flash_erase(unsigned int command_ee,unsigned int result_ee[]); +void iat_flash_write_page(unsigned int addr); +void iat_flash_read_page(unsigned int addr); + + +#endif + diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/lpc2138_defs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/lpc2138_defs.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,529 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +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 +*/ + +/** + * Définitions pour le LPC2138. + */ + +#if !defined(_LPC2138_DEF_H_) +#define _LPC2138_DEF_H_ + +#include + +// #include "types.h" + +#define BITMASK_0 0x00000000 +#define BITMASK_1 0x00000001 +#define BITMASK_2 0x00000003 +#define BITMASK_4 0x0000000F +#define BITMASK_8 0x000000FF +#define BITMASK_16 0x0000FFFF +#define BITMASK_32 0xFFFFFFFF + +typedef volatile unsigned char REG8; +typedef volatile unsigned char *REG8_ADDR; +typedef volatile unsigned short REG16; +typedef volatile unsigned short *REG16_ADDR; +typedef volatile unsigned int REG32; +typedef volatile unsigned int *REG32_ADDR; + + +#define SET_EQ_SET = +#define SET_EQ_CLR = + +#define P0_IOPIN_ADDR 0xE0028000 +#define P0_IOSET_ADDR 0xE0028004 +#define P0_IODIR_ADDR 0xE0028008 +#define P0_IOCLR_ADDR 0xE002800C +#define P0_PINSEL0_ADDR 0xE002C000 +#define P0_PINSEL1_ADDR 0xE002C004 + +#define P1_IOPIN_ADDR 0xE0028010 +#define P1_IOSET_ADDR 0xE0028014 +#define P1_IODIR_ADDR 0xE0028018 +#define P1_IOCLR_ADDR 0xE002801C +#define P1_PINSEL2_ADDR 0xE002C014 + +#define DACR_ADDR 0xE006C000 + +/* Vectored Interrupt Controller (VIC) */ +#define VICVectAddr_ADDR 0xFFFFF030 +#define VICVectAddr0_ADDR 0xFFFFF100 +#define VICVectCntl0_ADDR 0xFFFFF200 +#define VICIntEnable_ADDR 0xFFFFF010 + +/* External Interrupts */ +#define EXTINT_ADDR 0xE01FC140 +#define INTWAKE_ADDR 0xE01FC144 +#define EXTMODE_ADDR 0xE01FC148 +#define EXTPOLAR_ADDR 0xE01FC14C + +#ifdef TEST +#include "test_stubs.h" +#endif + +/* Vectored Interrupt Controller (VIC) */ +#define VICIRQStatus (*((REG32_ADDR) 0xFFFFF000)) +#define VICFIQStatus (*((REG32_ADDR) 0xFFFFF004)) +#define VICRawIntr (*((REG32_ADDR) 0xFFFFF008)) +#define VICIntSelect (*((REG32_ADDR) 0xFFFFF00C)) +#define VICIntEnable (*((REG32_ADDR) 0xFFFFF010)) +#define VICIntEnClr (*((REG32_ADDR) 0xFFFFF014)) +#define VICSoftInt (*((REG32_ADDR) 0xFFFFF018)) +#define VICSoftIntClr (*((REG32_ADDR) 0xFFFFF01C)) +#define VICProtection (*((REG32_ADDR) 0xFFFFF020)) +#define VICVectAddr (*((REG32_ADDR) 0xFFFFF030)) +#define VICDefVectAddr (*((REG32_ADDR) 0xFFFFF034)) +#define VICVectAddr0 (*((REG32_ADDR) 0xFFFFF100)) +#define VICVectAddr1 (*((REG32_ADDR) 0xFFFFF104)) +#define VICVectAddr2 (*((REG32_ADDR) 0xFFFFF108)) +#define VICVectAddr3 (*((REG32_ADDR) 0xFFFFF10C)) +#define VICVectAddr4 (*((REG32_ADDR) 0xFFFFF110)) +#define VICVectAddr5 (*((REG32_ADDR) 0xFFFFF114)) +#define VICVectAddr6 (*((REG32_ADDR) 0xFFFFF118)) +#define VICVectAddr7 (*((REG32_ADDR) 0xFFFFF11C)) +#define VICVectAddr8 (*((REG32_ADDR) 0xFFFFF120)) +#define VICVectAddr9 (*((REG32_ADDR) 0xFFFFF124)) +#define VICVectAddr10 (*((REG32_ADDR) 0xFFFFF128)) +#define VICVectAddr11 (*((REG32_ADDR) 0xFFFFF12C)) +#define VICVectAddr12 (*((REG32_ADDR) 0xFFFFF130)) +#define VICVectAddr13 (*((REG32_ADDR) 0xFFFFF134)) +#define VICVectAddr14 (*((REG32_ADDR) 0xFFFFF138)) +#define VICVectAddr15 (*((REG32_ADDR) 0xFFFFF13C)) +#define VICVectCntl0 (*((REG32_ADDR) 0xFFFFF200)) +#define VICVectCntl1 (*((REG32_ADDR) 0xFFFFF204)) +#define VICVectCntl2 (*((REG32_ADDR) 0xFFFFF208)) +#define VICVectCntl3 (*((REG32_ADDR) 0xFFFFF20C)) +#define VICVectCntl4 (*((REG32_ADDR) 0xFFFFF210)) +#define VICVectCntl5 (*((REG32_ADDR) 0xFFFFF214)) +#define VICVectCntl6 (*((REG32_ADDR) 0xFFFFF218)) +#define VICVectCntl7 (*((REG32_ADDR) 0xFFFFF21C)) +#define VICVectCntl8 (*((REG32_ADDR) 0xFFFFF220)) +#define VICVectCntl9 (*((REG32_ADDR) 0xFFFFF224)) +#define VICVectCntl10 (*((REG32_ADDR) 0xFFFFF228)) +#define VICVectCntl11 (*((REG32_ADDR) 0xFFFFF22C)) +#define VICVectCntl12 (*((REG32_ADDR) 0xFFFFF230)) +#define VICVectCntl13 (*((REG32_ADDR) 0xFFFFF234)) +#define VICVectCntl14 (*((REG32_ADDR) 0xFFFFF238)) +#define VICVectCntl15 (*((REG32_ADDR) 0xFFFFF23C)) + +#define P0_IOPIN (*((REG32_ADDR) P0_IOPIN_ADDR)) +#define P0_IOSET (*((REG32_ADDR) P0_IOSET_ADDR)) +#define P0_IODIR (*((REG32_ADDR) P0_IODIR_ADDR)) +#define P0_IOCLR (*((REG32_ADDR) P0_IOCLR_ADDR)) +#define P0_PINSEL0 (*((REG32_ADDR) P0_PINSEL0_ADDR)) +#define P0_PINSEL1 (*((REG32_ADDR) P0_PINSEL1_ADDR)) + +#define P1_IOPIN (*((REG32_ADDR) P1_IOPIN_ADDR)) +#define P1_IOSET (*((REG32_ADDR) P1_IOSET_ADDR)) +#define P1_IODIR (*((REG32_ADDR) P1_IODIR_ADDR)) +#define P1_IOCLR (*((REG32_ADDR) P1_IOCLR_ADDR)) +#define P1_PINSEL2 (*((REG32_ADDR) P1_PINSEL2_ADDR)) + +#define DACR (*((REG32_ADDR) DACR_ADDR)) + +/* External Interrupts */ +#define EXTINT (*((REG32_ADDR) EXTINT_ADDR)) +#define INTWAKE (*((REG32_ADDR) INTWAKE_ADDR)) +#define EXTMODE (*((REG32_ADDR) EXTMODE_ADDR)) +#define EXTPOLAR (*((REG32_ADDR) EXTPOLAR_ADDR)) + + +/* Timer 0 */ +#define T0IR (*((REG32_ADDR) 0xE0004000)) +#define T0TCR (*((REG32_ADDR) 0xE0004004)) +#define T0TC (*((REG32_ADDR) 0xE0004008)) +#define T0PR (*((REG32_ADDR) 0xE000400C)) +#define T0PC (*((REG32_ADDR) 0xE0004010)) +#define T0MCR (*((REG32_ADDR) 0xE0004014)) +#define T0MR0 (*((REG32_ADDR) 0xE0004018)) +#define T0MR1 (*((REG32_ADDR) 0xE000401C)) +#define T0MR2 (*((REG32_ADDR) 0xE0004020)) +#define T0MR3 (*((REG32_ADDR) 0xE0004024)) +#define T0CCR (*((REG32_ADDR) 0xE0004028)) +#define T0CR0 (*((REG32_ADDR) 0xE000402C)) +#define T0CR1 (*((REG32_ADDR) 0xE0004030)) +#define T0CR2 (*((REG32_ADDR) 0xE0004034)) +#define T0CR3 (*((REG32_ADDR) 0xE0004038)) +#define T0EMR (*((REG32_ADDR) 0xE000403C)) +#define T0CTCR (*((REG32_ADDR) 0xE0004070)) + +/* Timer 1 */ +#define T1IR (*((REG32_ADDR) 0xE0008000)) +#define T1TCR (*((REG32_ADDR) 0xE0008004)) +#define T1TC (*((REG32_ADDR) 0xE0008008)) +#define T1PR (*((REG32_ADDR) 0xE000800C)) +#define T1PC (*((REG32_ADDR) 0xE0008010)) +#define T1MCR (*((REG32_ADDR) 0xE0008014)) +#define T1MR0 (*((REG32_ADDR) 0xE0008018)) +#define T1MR1 (*((REG32_ADDR) 0xE000801C)) +#define T1MR2 (*((REG32_ADDR) 0xE0008020)) +#define T1MR3 (*((REG32_ADDR) 0xE0008024)) +#define T1CCR (*((REG32_ADDR) 0xE0008028)) +#define T1CR0 (*((REG32_ADDR) 0xE000802C)) +#define T1CR1 (*((REG32_ADDR) 0xE0008030)) +#define T1CR2 (*((REG32_ADDR) 0xE0008034)) +#define T1CR3 (*((REG32_ADDR) 0xE0008038)) +#define T1EMR (*((REG32_ADDR) 0xE000803C)) +#define T1CTCR (*((REG32_ADDR) 0xE0008070)) + +/* Real Time Clock */ +#define ILR (*((REG8_ADDR) 0xE0024000)) +#define CTC (*((REG16_ADDR) 0xE0024004)) +#define CCR (*((REG8_ADDR) 0xE0024008)) +#define CIIR (*((REG8_ADDR) 0xE002400C)) +#define AMR (*((REG8_ADDR) 0xE0024010)) +#define CTIME0 (*((REG32_ADDR) 0xE0024014)) +#define CTIME1 (*((REG32_ADDR) 0xE0024018)) +#define CTIME2 (*((REG32_ADDR) 0xE002401C)) +#define SEC (*((REG8_ADDR) 0xE0024020)) +#define MIN (*((REG8_ADDR) 0xE0024024)) +#define HOUR (*((REG8_ADDR) 0xE0024028)) +#define DOM (*((REG8_ADDR) 0xE002402C)) +#define DOW (*((REG8_ADDR) 0xE0024030)) +#define DOY (*((REG16_ADDR) 0xE0024034)) +#define MONTH (*((REG8_ADDR) 0xE0024038)) +#define YEAR (*((REG16_ADDR) 0xE002403C)) +#define ALSEC (*((REG8_ADDR) 0xE0024060)) +#define ALMIN (*((REG8_ADDR) 0xE0024064)) +#define ALHOUR (*((REG8_ADDR) 0xE0024068)) +#define ALDOM (*((REG8_ADDR) 0xE002406C)) +#define ALDOW (*((REG8_ADDR) 0xE0024070)) +#define ALDOY (*((REG16_ADDR) 0xE0024074)) +#define ALMON (*((REG8_ADDR) 0xE0024078)) +#define ALYEAR (*((REG16_ADDR) 0xE002407C)) +#define PREINT (*((REG16_ADDR) 0xE0024080)) +#define PREFRAC (*((REG16_ADDR) 0xE0024084)) + +/* SPI Registers */ +#define S0SPCR (*((REG32_ADDR) 0xE0020000)) +#define S0SPSR (*((REG32_ADDR) 0xE0020004)) +#define S0SPDR (*((REG32_ADDR) 0xE0020008)) +#define S0SPCCR (*((REG32_ADDR) 0xE002000C)) +#define S0SPINT (*((REG32_ADDR) 0xE002001C)) + +/* SSP Registers */ +#define SSPCR0 (*((REG32_ADDR) 0xE0068000)) +#define SSPCR1 (*((REG32_ADDR) 0xE0068004)) +#define SSPDR (*((REG32_ADDR) 0xE0068008)) +#define SSPSR (*((REG32_ADDR) 0xE006800C)) +#define SSPCPSR (*((REG32_ADDR) 0xE0068010)) +#define SSPIMSC (*((REG32_ADDR) 0xE0068014)) +#define SSPRIS (*((REG32_ADDR) 0xE0068018)) +#define SSPMIS (*((REG32_ADDR) 0xE006801C)) +#define SSPICR (*((REG32_ADDR) 0xE0068020)) + + +typedef enum { + LPC2138_MODE_INPUT = 0, + LPC2138_MODE_OUTPUT = 1 +} LPC2138_MODE; + +typedef enum { + P0 = 0, + P1 = 1 +} LPC2138_PORT; + +/* === Fonctions "#define" génériques ======================================= */ + +#define _cat(a, b) a##b +#define _CAT(a, b) _cat(a, b) + +#define _PIN(pin) LPC2138_##pin +#define _PORT(pin) LPC2138_##pin##_PORT +#define _SIZE(pin) LPC2138_##pin##_SIZE + +/* ((P[0|1]_IOPIN >> pin) & BITMASK_[0-32]) */ +#define lpc2138_get(pin) \ + ((_CAT(_PORT(pin), _IOPIN) >> _PIN(pin)) & _CAT(BITMASK_, _SIZE(pin))) + +#define lpc2138_set(pin, i) \ + { if (_SIZE(pin) == 1) { lpc2138_set_bit(pin, i); } \ + else { lpc2138_set_all(pin, i); } } + +#define lpc2138_set_bit(pin, i) \ + { if ((i) == 1) { _CAT(_PORT(pin), _IOSET) SET_EQ_SET (1 << _PIN(pin)); } \ + else { _CAT(_PORT(pin), _IOCLR) SET_EQ_CLR (1 << _PIN(pin)); } } + +#define lpc2138_set_all(pin, i) \ + (_CAT(_PORT(pin), _IOPIN) = \ + (_CAT(_PORT(pin), _IOPIN) & \ + ~(_CAT(BITMASK_, _SIZE(pin)) << _PIN(pin))) | ((i) << _PIN(pin))) + +/* Identique à lpc2138_set(p, f, nbits, i) sans effet secondaire (plus lent). */ +#define lpc2138_set_SAFE_(pin, i) \ + ((_SIZE(pin) == 1) && lpc2138_set_bit_SAFE_(pin, (i)) || \ + lpc2138_set_all(pin, (i))) + +/* Identique à lpc2138_set_bit(p, f, i) sans effet secondaire (plus lent). */ +#define lpc2138_set_bit_SAFE_(pin, i) \ + ((i == 1) && (_CAT(_PORT(pin), _IOSET) SET_EQ_SET (1 << _PIN(pin))) || \ + (_CAT(_PORT(pin), _IOCLR) SET_EQ_CLR (1 << _PIN(pin)))) + +#define lpc2138_set_mode(pin, mode) \ + (_CAT(_PORT(pin), _IODIR) = (mode == LPC2138_MODE_OUTPUT) ? \ + (_CAT(_PORT(pin), _IODIR)|(_CAT(BITMASK_, _SIZE(pin)) << _PIN(pin))) : \ + (_CAT(_PORT(pin), _IODIR) & ~(_CAT(BITMASK_, _SIZE(pin)) << _PIN(pin)))) + +#define lpc2138_set_pinsel(pin, func) \ + lpc2138_pinsel_set(_PIN(pin), _PORT(pin), _SIZE(pin), func) + +/* === Fonctions pinout "#define" par défaut ================================ */ + +#ifndef lpc2138_uart0_tx_set_pinsel +#define lpc2138_uart0_tx_set_pinsel(func) lpc2138_set_pinsel(uart0_tx, func) +#endif + +#ifndef lpc2138_uart0_rx_set_pinsel +#define lpc2138_uart0_rx_set_pinsel(func) lpc2138_set_pinsel(uart0_rx, func) +#endif + +#ifndef lpc2138_cs_s1d13706_get +#define lpc2138_cs_s1d13706_get() lpc2138_get (cs_s1d13706) +#endif + +#ifndef lpc2138_cs_s1d13706_set +#define lpc2138_cs_s1d13706_set(i) lpc2138_set (cs_s1d13706, i) +#endif + +#ifndef lpc2138_cs_s1d13706_set_mode +#define lpc2138_cs_s1d13706_set_mode(mode) lpc2138_set_mode (cs_s1d13706, mode) +#endif + +#ifndef lpc2138_cs_s1d13706_set_pinsel +#define lpc2138_cs_s1d13706_set_pinsel(func) lpc2138_set_pinsel(cs_s1d13706, func) +#endif + +#ifndef lpc2138_cs_sja1000_get +#define lpc2138_cs_sja1000_get() lpc2138_get (cs_sja1000) +#endif + +#ifndef lpc2138_cs_sja1000_set +#define lpc2138_cs_sja1000_set(i) lpc2138_set (cs_sja1000, i) +#endif + +#ifndef lpc2138_cs_sja1000_set_mode +#define lpc2138_cs_sja1000_set_mode(mode) lpc2138_set_mode (cs_sja1000, mode) +#endif + +#ifndef lpc2138_cs_sja1000_set_pinsel +#define lpc2138_cs_sja1000_set_pinsel(func) lpc2138_set_pinsel(cs_sja1000, func) +#endif + +#ifndef lpc2138_wait_get +#define lpc2138_wait_get() lpc2138_get (wait) +#endif + +#ifndef lpc2138_wait_set +#define lpc2138_wait_set(i) lpc2138_set (wait, i) +#endif + +#ifndef lpc2138_wait_set_mode +#define lpc2138_wait_set_mode(mode) lpc2138_set_mode (wait, mode) +#endif + +#ifndef lpc2138_wait_set_pinsel +#define lpc2138_wait_set_pinsel(func) lpc2138_set_pinsel(wait, func) +#endif + +#ifndef lpc2138_bhe_get +#define lpc2138_bhe_get() lpc2138_get (bhe) +#endif + +#ifndef lpc2138_bhe_set +#define lpc2138_bhe_set(i) lpc2138_set (bhe, i) +#endif + +#ifndef lpc2138_bhe_set_mode +#define lpc2138_bhe_set_mode(mode) lpc2138_set_mode (bhe, mode) +#endif + +#ifndef lpc2138_bhe_set_pinsel +#define lpc2138_bhe_set_pinsel(func) lpc2138_set_pinsel(bhe, func) +#endif + +#ifndef lpc2138_interrupt_sja1000_get +#define lpc2138_interrupt_sja1000_get() lpc2138_get (interrupt_sja1000) +#endif + +#ifndef lpc2138_interrupt_sja1000_set +#define lpc2138_interrupt_sja1000_set(i) lpc2138_set (interrupt_sja1000, i) +#endif + +#ifndef lpc2138_interrupt_sja1000_set_mode +#define lpc2138_interrupt_sja1000_set_mode(mode) lpc2138_set_mode (interrupt_sja1000, mode) +#endif + +#ifndef lpc2138_interrupt_sja1000_set_pinsel +#define lpc2138_interrupt_sja1000_set_pinsel(func) lpc2138_set_pinsel(interrupt_sja1000, func) +#endif + +#ifndef lpc2138_redgreenled_get +#define lpc2138_redgreenled_get() lpc2138_get (redgreenled) +#endif + +#ifndef lpc2138_redgreenled_set +#define lpc2138_redgreenled_set(i) lpc2138_set (redgreenled, i) +#endif + +#ifndef lpc2138_redgreenled_set_mode +#define lpc2138_redgreenled_set_mode(mode) lpc2138_set_mode (redgreenled, mode) +#endif + +#ifndef lpc2138_redgreenled_set_pinsel +#define lpc2138_redgreenled_set_pinsel(func) lpc2138_set_pinsel(redgreenled, func) +#endif + +#ifndef lpc2138_dac0_set +#define lpc2138_dac0_set() lpc2138_set (dac0, i) +#endif + +#ifndef lpc2138_dac0_set_value +#define lpc2138_dac0_set_value(i) DACR = ((1 << 16) | ((i & 0x3FF) << 6)) +#endif + +#ifndef lpc2138_dac0_set_pinsel +#define lpc2138_dac0_set_pinsel(func) lpc2138_set_pinsel(dac0, func) +#endif + +#ifndef lpc2138_spi0_set +#define lpc2138_spi0_set() lpc2138_set (spi0, i) +#endif + +#ifndef lpc2138_spi0_set_value +#define lpc2138_spi0_set_value(i) SSPDR = i +#endif + +#ifndef lpc2138_spi0_set_pinsel +#define lpc2138_spi0_set_pinsel(func) lpc2138_set_pinsel(spi0, func) +#endif + +#ifndef lpc2138_ale_get +#define lpc2138_ale_get() lpc2138_get (ale) +#endif + +#ifndef lpc2138_ale_set +#define lpc2138_ale_set(i) lpc2138_set (ale, i) +#endif + +#ifndef lpc2138_ale_set_mode +#define lpc2138_ale_set_mode(mode) lpc2138_set_mode (ale, mode) +#endif +#ifndef lpc2138_ale_set_pinsel +#define lpc2138_ale_set_pinsel(func) lpc2138_set_pinsel(ale, func) +#endif + +#ifndef lpc2138_rd_get +#define lpc2138_rd_get() lpc2138_get (rd) +#endif + +#ifndef lpc2138_rd_set +#define lpc2138_rd_set(i) lpc2138_set (rd, i) +#endif + +#ifndef lpc2138_rd_set_mode +#define lpc2138_rd_set_mode(mode) lpc2138_set_mode (rd, mode) +#endif + +#ifndef lpc2138_rd_set_pinsel +#define lpc2138_rd_set_pinsel(func) lpc2138_set_pinsel(rd, func) +#endif + +#ifndef lpc2138_wr_get +#define lpc2138_wr_get() lpc2138_get (wr) +#endif + +#ifndef lpc2138_wr_set +#define lpc2138_wr_set(i) lpc2138_set (wr, i) +#endif + +#ifndef lpc2138_wr_set_mode +#define lpc2138_wr_set_mode(mode) lpc2138_set_mode (wr, mode) +#endif + +#ifndef lpc2138_wr_set_pinsel +#define lpc2138_wr_set_pinsel(func) lpc2138_set_pinsel(wr, func) +#endif + +#ifndef lpc2138_data_get +#define lpc2138_data_get() lpc2138_get (data) +#endif + +#ifndef lpc2138_data_set +#define lpc2138_data_set(i) lpc2138_set (data, i) +#endif + +#ifndef lpc2138_data_set_mode +#define lpc2138_data_set_mode(mode) lpc2138_set_mode (data, mode) +#endif + +#ifndef lpc2138_data_set_pinsel +#define lpc2138_data_set_pinsel(func) lpc2138_set_pinsel(data, func) +#endif + +#ifndef lpc2138_addresses_get +#define lpc2138_addresses_get() ((lpc2138_get (a17_mr) << 17) | \ + (lpc2138_get (a16) << 16) | \ + (lpc2138_get (a0_a15))) +#endif + +#ifndef lpc2138_addresses_set +#define lpc2138_addresses_set(i) lpc2138_set (a17_mr, ((i >> 17) & BITMASK_1)); \ + lpc2138_set (a16, ((i >> 16) & BITMASK_1)); \ + lpc2138_set (a0_a15, ((i) & BITMASK_16)) +#endif + +#ifndef lpc2138_addresses_set_mode +#define lpc2138_addresses_set_mode(mode) (lpc2138_set_mode (a17_mr, mode), \ + lpc2138_set_mode (a16, mode), \ + lpc2138_set_mode (a0_a15, mode)) +#endif + +#ifndef lpc2138_addresses_set_pinsel +#define lpc2138_addresses_set_pinsel(func) (lpc2138_set_pinsel(a17_mr, func), \ + lpc2138_set_pinsel(a16, func), \ + lpc2138_set_pinsel(a0_a15, func)) +#endif + +#define CMR 1 +#define RRB 2 // 1=released message in fifo are released +#define AT 1 // 1= cancel next tranmission +#define SR 2 +#define TBS 2 // 1=released the cpu may write a message in the transmit buffer +#define SRR 4 // 1=present a message shall be transmit and receive sim +#define TR 0 // 1=present a message shall be transmit + + +/* + FLASH +*/ +#define EE_SEC_L 1 // Flash sector where EEPROM begins (see UM for details) +#define EE_SEC_H 3 // Flash sector where EEPROM ends (see UM for details) +#define EE_ADDR_L 0x00001000 // Must match the EE_SEC_L Flash sector start address +#define EE_ADDR_H 0x00003FFF // Must match the EE_SEC_H Flash sector end address +#define EE_CCLK 60000 // system clock cclk expressed in kHz (5*12 MHz) +#define EE_BUFFER_SIZE 256 +#define EE_START_MASK 0xFFFFFF00 +#define EE_BUFFER_MASK 0x000000F0 + + +#endif diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/lpc2138_pinout.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/lpc2138_pinout.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,103 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +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 +*/ + +/** + * Définitions du brochage LPC2138 par défaut. + */ +#if !defined(_LPC2138_PINOUT_H_) +#define _LPC2138_PINOUT_H_ + +#define LPC2138_uart0_tx 0 /* Pin 0 */ +#define LPC2138_uart0_tx_PORT P0 +#define LPC2138_uart0_tx_SIZE 1 + +#define LPC2138_uart0_rx 1 /* Pin 1 */ +#define LPC2138_uart0_rx_PORT P0 +#define LPC2138_uart0_rx_SIZE 1 + +#define LPC2138_cs_sja1000 4 /* Pin 4 */ +#define LPC2138_cs_sja1000_PORT P0 +#define LPC2138_cs_sja1000_SIZE 1 + +#define LPC2138_cs_s1d13706 5 /* Pin 5 */ +#define LPC2138_cs_s1d13706_PORT P0 +#define LPC2138_cs_s1d13706_SIZE 1 + +#define LPC2138_wait 7 /* Pin 7 */ +#define LPC2138_wait_PORT P0 +#define LPC2138_wait_SIZE 1 + +#define LPC2138_uart1_tx 8 /* Pin 8 */ +#define LPC2138_uart1_tx_PORT P0 +#define LPC2138_uart1_tx_SIZE 1 + +#define LPC2138_uart1_rx 9 /* Pin 9 */ +#define LPC2138_uart1_rx_PORT P0 +#define LPC2138_uart1_rx_SIZE 1 + +#define LPC2138_bhe 10 /* Pin 10 */ +#define LPC2138_bhe_PORT P0 +#define LPC2138_bhe_SIZE 1 + +#define LPC2138_a17_mr 12 /* Pin 12 */ +#define LPC2138_a17_mr_PORT P0 +#define LPC2138_a17_mr_SIZE 1 + +#define LPC2138_a16 13 /* Pin 13 */ +#define LPC2138_a16_PORT P0 +#define LPC2138_a16_SIZE 1 + +#define LPC2138_interrupt_sja1000 14 /* Pin 14 */ +#define LPC2138_interrupt_sja1000_PORT P0 +#define LPC2138_interrupt_sja1000_SIZE 1 + +#define LPC2138_data 16 /* Pins 16-23 */ +#define LPC2138_data_PORT P0 +#define LPC2138_data_SIZE 8 + +#define LPC2138_dac0 25 /* Pin 25 */ +#define LPC2138_dac0_PORT P0 +#define LPC2138_dac0_SIZE 1 + +#define LPC2138_ale 26 /* Pin 26 */ +#define LPC2138_ale_PORT P0 +#define LPC2138_ale_SIZE 1 + +#define LPC2138_redgreenled 27 /* Pin 27 */ +#define LPC2138_redgreenled_PORT P0 +#define LPC2138_redgreenled_SIZE 2 + +#define LPC2138_rd 29 /* Pin 29 */ +#define LPC2138_rd_PORT P0 +#define LPC2138_rd_SIZE 1 + +#define LPC2138_wr 30 /* Pin 30 */ +#define LPC2138_wr_PORT P0 +#define LPC2138_wr_SIZE 1 + +#define LPC2138_a0_a15 16 /* Pins 16-31 */ +#define LPC2138_a0_a15_PORT P1 +#define LPC2138_a0_a15_SIZE 16 + +#define LPC2138_addresses_SIZE 18 + +#endif diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/sja1000.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/sja1000.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,23 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +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 +*/ + + diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/sja1000.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/sja1000.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,76 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +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 +*/ + +#if !defined(_SJA1000_H_) +#define _SJA1000_H_ + +#define MOD 0 +#define RM 0 /* RM 1=reset 0 = normal */ +#define bustiming0 6 +#define OCMODE1 1 +#define OCMODE0 0 + +#define SJW1 7 +#define SJW0 6 +#define BRP5 5 +#define BRP4 4 +#define BRP3 3 +#define BRP2 2 +#define BRP1 1 +#define BRP0 0 + +#define CDO 3 /* 1=clear data overun status bit */ +#define SAM 7 +#define TSEG22 6 +#define TSEG21 5 +#define TSEG20 4 +#define TSEG13 3 +#define TSEG12 2 +#define TSEG11 1 +#define TSEG10 0 +#define OCTP1 7 +#define OCTN1 6 +#define OCPOL1 5 +#define OCTP0 4 +#define OCTN0 3 +#define OCPOL0 2 +#define OCMODE1 1 +#define OCMODE0 0 +#define clockdivider 31 +#define CANmode 7 /* 1= PELICAN */ +#define CBP 6 /* 1= bypass comparator */ +#define RXINTEN 5 /* 1= receive interrupt from tx */ +#define clockoff 3 /* 1= disabled */ +#define CD2 2 +#define CD1 1 +#define CD0 0 + +#define AFM 3 /* AFM 1=single 0=dual acceptance filter */ +#define STM 2 /* STM 1=self test 0= norma */ +#define IER 4 +#define bustiming1 7 +#define outputcontrol 8 +#define TXIDENTIFIER1 17 +#define TXIDENTIFIER2 18 + + +#endif diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/time_slicer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/time_slicer.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,219 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include + +#include +#include + +#include "applicfg.h" + +#include + + +#define max(a,b) a>b?a:b +#define min(a,b) astate & TIMER_ARMED) // if row is active + { + if (row->val <= real_total_sleep_time) // to be trigged + { + if (!row->interval) // if simply outdated + { + row->state = TIMER_TRIG; // ask for trig + } + else // or period have expired + { + // set val as interval, with overrun correction + row->val = row->interval - (overrun % row->interval); + row->state = TIMER_TRIG_PERIOD; // ask for trig, periodic + // Check if this new timer value is the soonest + next_wakeup = min(row->val,next_wakeup); + } + } + else + { + // Each armed timer value in decremented. + row->val -= real_total_sleep_time; + + // Check if this new timer value is the soonest + next_wakeup = min(row->val,next_wakeup); + } + } + } + + // Remember how much time we should sleep. + total_sleep_time = next_wakeup; + + // Set timer to soonest occurence + setTimer(next_wakeup); + + // Then trig them or not. + for(i=0; i<=last_timer_raw; i++) + { + s_timer_entry *row = (timers+i); + + if (row->state & TIMER_TRIG) + { + row->state &= ~TIMER_TRIG; // reset trig state (will be free if not periodic) + (*row->callback)(row->d, row->id); // trig ! + } + } +} + + + + +TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period) +{ + int i; + TIMER_HANDLE row_number = TIMER_NONE; + + if (callback == NULL) // nothing to store + return TIMER_NONE; + + // in order to decide new timer setting we have to run over all timer rows + + for(i=0; i <= last_timer_raw + 1 && i < MAX_NB_TIMER; i++) + { + s_timer_entry *row = (timers+i); + + if (row->state == TIMER_FREE) // an empty row + { // just store + row->callback = callback; + row->d = d; + row->id = id; + row->val = value; + row->interval = period; + row->state = TIMER_ARMED; + + row_number = i; + break; + } + } + + if (row_number != TIMER_NONE) // if successfull + { + if (row_number == last_timer_raw + 1) last_timer_raw++; + + // set next wakeup alarm if new entry is sooner than others, or if it is alone + unsigned int real_timer_value = min(value, TIMEVAL_MAX); + unsigned int elapsed_time = getElapsedTime(); + + if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) + { + total_sleep_time = elapsed_time + real_timer_value; + setTimer(real_timer_value); + } + + return row_number; + } + + return TIMER_NONE; +} + +// --------- Use this to remove an alarm --------- +TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) +{ + if (handle != TIMER_NONE) + { + if (handle == last_timer_raw) + last_timer_raw--; + timers[handle].state = TIMER_FREE; + } + else + { + } + + return TIMER_NONE; +} diff -r 000000000000 -r 4472ee7c6c3e drivers/ecos_lpc2138_sja1000/time_slicer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/ecos_lpc2138_sja1000/time_slicer.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,34 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: Christian Fortin (canfestival@canopencanada.ca) + +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 +*/ + + +#if !defined(_TIME_SLICER_H_) +#define _TIME_SLICER_H_ + + +extern cyg_handle_t alarm_handle_timer; + +void chrono_timer(cyg_handle_t alarmH, cyg_addrword_t data); +void init_timer(void); + + +#endif diff -r 000000000000 -r 4472ee7c6c3e drivers/generic/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/generic/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,2 @@ +Makefile +*.a diff -r 000000000000 -r 4472ee7c6c3e drivers/generic/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/generic/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,85 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +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/generic + +OBJS = + +# add timers driver if any +ifneq ($(TIMERS_DRIVER),) +OBJS += ../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o +endif + +# add can driver if any +ifneq ($(CAN_DRIVER),) +OBJS += ../$(CAN_DRIVER)/$(CAN_DRIVER).o +endif + +SRC_HFILES = ../../include/$(TARGET)/applicfg.h + +TARGET_HFILES = $(PREFIX)/include/$(TARGET)/applicfg.h + +all: driver + +driver: $(OBJS) + +#../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o: +# $(MAKE) -C ../$(TIMERS_DRIVER) driver + +#../$(CAN_DRIVER)/$(CAN_DRIVER).o: +# $(MAKE) -C ../$(CAN_DRIVER) driver + +libcanfestival_generic.a: $(OBJS) + @echo Building [libcanfestival_generic.a] + ar rc $@ $(OBJS) + ranlib $@ + +install: libcanfestival_generic.a + mkdir -p $(PREFIX)/lib/ + mkdir -p $(PREFIX)/include/canfestival + cp libcanfestival_generic.a $(PREFIX)/lib/ + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(PREFIX)/lib/libcanfestival_generic.a + rm -f $(TARGET_HFILES) + +clean: + -\rm libcanfestival_generic.a + +mrproper: clean + + diff -r 000000000000 -r 4472ee7c6c3e drivers/hcs12/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/hcs12/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,79 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +CFLAGS = +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET +INCLUDES = -I../../include -I../../include/hcs12 + +OPT_CFLAGS = -Os +PROGDEFINES = -mnoshort -Wall -Wmissing-prototypes -fno-strict-aliasing +PROGDEFINES_ASM = -mnoshort -Wall -Wmissing-prototypes + +OBJS = canOpenDriver.o interrupt.o ports.o + +all: driver + +driver: $(OBJS) + +libcandriver.a: $(OBJS) + @echo " " + @echo "*********************************************" + @echo "**Building [libcandriver]" + @echo "*********************************************" + ar rc $@ $(OBJS) + ranlib $@ + +%o: %c + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) $(OPT_CFLAGS) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -c -o $@ $< + +%o: %s + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) -c -x assembler-with-cpp $(PROG_CFLAGS) ${PROGDEFINES_ASM} -o $@ $< + +install: libcandriver.a + mkdir -p ../../lib/hc12 + mv libcandriver.a ../../lib/hc12 + +uninstall: + rm -f ../../lib/hc12/libcandriver.a + +clean: + -\rm $(OBJS) + +mrproper: clean + -\rm ../../lib/hc12/libcandriver.a + diff -r 000000000000 -r 4472ee7c6c3e drivers/hcs12/canOpenDriver.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/hcs12/canOpenDriver.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,690 @@ +/* +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 +*/ + +#define DEBUG_WAR_CONSOLE_ON +#define DEBUG_ERR_CONSOLE_ON + +#include /* for NULL */ + +#include "../include/hcs12/asm-m68hc12/portsaccess.h" +#include "../include/hcs12/asm-m68hc12/ports_def.h" +#include "../include/hcs12/asm-m68hc12/ports.h" +#include "../include/hcs12/applicfg.h" +#include "../include/hcs12/candriver.h" +#include "../include/hcs12/interrupt.h" +#include "../include/hcs12/canOpenDriver.h" + +#include "../include/can.h" +#include "../include/objdictdef.h" +#include "../include/timer.h" + + + + + + +volatile static Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV]; +volatile static t_pointerStack ptrMsgRcv[NB_LINE_CAN]; + +volatile static TIMEVAL last_time_set = TIMEVAL_MAX; +static UNS8 timer_is_set = 0; + +/* Prototypes */ +UNS8 f_can_receive(UNS8 notused, Message *m); +UNS8 canSend(UNS8 notused, Message *m); +void __attribute__((interrupt)) timer4Hdl (void); + +#define max(a,b) a>b?a:b + +/******************************************************************************/ +void setTimer(TIMEVAL value) +{ + IO_PORTS_16(TC4H) += value; + timer_is_set = 1; +} + +/******************************************************************************/ +TIMEVAL getElapsedTime() +{ + return (IO_PORTS_16(TC4H) > last_time_set ? IO_PORTS_16(TC4H) - last_time_set : last_time_set - IO_PORTS_16(TC4H)); +} + + +/******************************************************************************/ +void resetTimer(void) +{ + +} + +/******************************************************************************/ +void initTimer(void) +{ + lock(); // Inhibition of interruptions + + // Configure the timer channel 4 + IO_PORTS_8(TIOS) |= 0x10; // Canal 4 in output + IO_PORTS_8(TCTL1) &= ~(0x01 + 0x02); // Canal 4 unconnected to pin output + IO_PORTS_8(TIE) |= 0x10; // allow interruption channel 4 + IO_PORTS_8(TSCR2) |= 0X05; // Pre-scaler = 32 + // If this value is changed, change must be done also + // in void __attribute__((interrupt)) timer4Hdl (void) + + IO_PORTS_8(TSCR1) |= 0x80; // Start timer + unlock(); // Allow interruptions +} + +/******************************************************************************/ +void __attribute__((interrupt)) timer4Hdl (void) +{ + lock(); + last_time_set = IO_PORTS_16(TC4H); + IO_PORTS_8(TFLG1) = 0x10; // RAZ flag interruption timer channel 4 + // Compute the next event : When the timer reach the value of TC4, an interrupt is + // started + //IO_PORTS_16(TC4H) += 250; // To have an interruption every 1 ms + //timerInterrupt(0); + //MSG_WAR(0xFFFF, "timer4 IT", 0); + { + //MSG_WAR(0xFFFF, "t4 ", IO_PORTS_16(TCNTH) - IO_PORTS_16(TC4H)); + } + TimeDispatch(); + unlock(); +} + + +/******************************************************************************/ +void initSCI_0(void) +{ + IO_PORTS_16(SCI0 + SCIBDH) = + ((1000000 / SERIAL_SCI0_BAUD_RATE) * BUS_CLOCK) >> 4 ; + IO_PORTS_8(SCI0 + SCICR1) = 0; // format 8N1 + IO_PORTS_8(SCI0 + SCICR2) = 0x08; // Transmit enable only +} + +/******************************************************************************/ +void initSCI_1(void) +{ + IO_PORTS_16(SCI1 + SCIBDH) = + ((1000000 / SERIAL_SCI1_BAUD_RATE) * BUS_CLOCK) >> 4 ; + IO_PORTS_8(SCI1 + SCICR1) = 0; // format 8N1 + IO_PORTS_8(SCI1 + SCICR2) = 0x08; // Transmit enable only +} + + +/******************************************************************************/ +char * +hex_convert (char *buf, unsigned long value, char lastCar) +{ + //Thanks to Stéphane Carrez for this function + char num[32]; + int pos; + + *buf++ = '0'; + *buf++ = 'x'; + + pos = 0; + while (value != 0) { + char c = value & 0x0F; + num[pos++] = "0123456789ABCDEF"[(unsigned) c]; + value = (value >> 4) & (0x0fffffffL); + } + if (pos == 0) + num[pos++] = '0'; + + while (--pos >= 0) + *buf++ = num[pos]; + + *buf++ = lastCar; + *buf = 0; + return buf; +} + +/******************************************************************************/ +void printSCI_str(char sci, const char * str) +{ + char i = 0; + + while ((*(str + i) != 0) && (i < 0xFF)) { + if (*(str + i) == '\n') + { + while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0); // wait if buffer not empty + IO_PORTS_8(sci + SCIDRL) = 13; // return to start of line + } + while ((IO_PORTS_8(sci + SCISR1) & 0X80) == 0); // wait if buffer not empty + IO_PORTS_8(sci + SCIDRL) = *(str + i++); + } + +} + +/******************************************************************************/ +void printSCI_nbr(char sci, unsigned long nbr, char lastCar) +{ + char strNbr[12]; + hex_convert(strNbr, nbr, lastCar); + printSCI_str(sci, strNbr); +} + +/******************************************************************************/ +// PLL 24 MHZ if quartz on board is 16 MHZ +void initPLL(void) +{ + IO_PORTS_8(CLKSEL) &= ~0x80; // unselect the PLL + IO_PORTS_8(PLLCTL) |= 0X60; // PLL ON and bandwidth auto + IO_PORTS_8(SYNR) = 0x02; + IO_PORTS_8(REFDV) = 0x01; + while ((IO_PORTS_8(CRGFLG) & 0x08) == 0); + IO_PORTS_8(CLKSEL) |= 0x80; +} + +/******************************************************************************/ +void initHCS12(void) +{ + +# ifdef USE_PLL + MSG_WAR(0x3620, "Use the PLL ", 0); + initPLL(); +# endif + +} + +/***************************************************************************/ +char canAddIdToFilter(UNS16 adrCAN, UNS8 nFilter, UNS16 id) +{ + UNS8 fiMsb; + UNS8 fiLsb; + UNS8 idMsb = (UNS8) (id >> 3); + UNS8 idLsb = (UNS8) (id << 5); + + if (! canTestInitMode(adrCAN)) { + /* Error because not init mode */ + MSG_WAR(0X2600, "Not in init mode ", 0); + return 1; + } + switch (nFilter) { + case 0: + nFilter = CANIDAR0; /* First bank */ + break; + case 1: + nFilter = CANIDAR2; /* First bank */ + break; + case 2: + nFilter = CANIDAR4; /* Second bank */ + break; + case 3: + nFilter = CANIDAR6; /* Second bank */ + } + if (! IO_PORTS_16(adrCAN + nFilter)) { + /* if CANIDARx = 0 */ + IO_PORTS_8(adrCAN + nFilter) = idMsb; + IO_PORTS_8(adrCAN + nFilter + 1) = idLsb; + } + fiMsb = IO_PORTS_8(adrCAN + nFilter) ^ idMsb; + fiLsb = IO_PORTS_8(adrCAN + nFilter + 1) ^ idLsb; + /* address of CANIDMRx */ + IO_PORTS_8(adrCAN + nFilter + 4) = IO_PORTS_8(adrCAN + nFilter + 4) | fiMsb; + IO_PORTS_8(adrCAN + nFilter + 5) = IO_PORTS_8(adrCAN + nFilter + 5) | fiLsb; + IO_PORTS_8(adrCAN + nFilter + 5) |= 0x10; /* Not filtering on rtr value */ + return 0; +} + +/***************************************************************************/ +char canEnable(UNS16 adrCAN) +{ + /* Register CANCTL1 + bit 7 : 1 MSCAN enabled + Other bits : default reset values + */ + IO_PORTS_8(adrCAN + CANCTL1) = 0X80; + return 0; +} + +/***************************************************************************/ +char canInit(UNS16 adrCAN, canBusInit bi) +{ + /* If not in init mode, go to sleep before going in init mode*/ + if (! canTestInitMode(adrCAN)) { + canSleepMode(adrCAN); + canInitMode(adrCAN); + } + + canEnable(adrCAN); /* Does nothing if already enable */ + /* The most secure way to go in init mode : put before MSCAN in sleep mode */ + //canSleepMode(adrCAN); + /* Put MSCAN in Init mode */ + //canInitMode(adrCAN); + canInitClock(adrCAN, bi.clk); + /* Init CANCTL1 register. Must be in init mode */ + IO_PORTS_8(adrCAN + CANCTL1) &=0xC4;// 0xCB; /* Clr the bits that may be modified */ + IO_PORTS_8(adrCAN + CANCTL1) = (bi.cane << 7) | (bi.loopb << 5 ) | + (bi.listen << 4) | (bi.wupm << 2); + /* Initialize the filters for received msgs */ + /* We should decide to accept all the msgs */ + canInitFilter(adrCAN, bi.fi); + /* Before to modify CANCTL0, we must leave the init mode */ + canInitModeQ(adrCAN); + /* Init CANCTL0 register. MSCAN must not be in init mode */ + /* Do not change the value of wupe (should be 0) and slprq (should be 1) */ + /* Do not change the value of initrq (should be 0) */ + /* rxfrm is cleared, mupe also (should be before)*/ + IO_PORTS_8(adrCAN + CANCTL0) &= 0x53; /* Clr the bits that may be modified */ + IO_PORTS_8(adrCAN + CANCTL0) = (bi.cswai << 5) | (bi.time << 3); + IO_PORTS_8(adrCAN + CANRIER) = 0X01; /* Allow interruptions on receive */ + IO_PORTS_8(adrCAN + CANTIER) = 0X00; /* disallow interruptions on transmit */ + canInitModeQ(adrCAN); /* Leave the init mode */ + canSleepModeQ(adrCAN); /* Leave the sleep mode */ + return 0; +} + +/***************************************************************************/ +char canInitClock(UNS16 adrCAN, canBusTime clk) +{ + if (! canTestInitMode(adrCAN)) { + /* Not in Init mode */ + MSG_WAR(0X2601, "not in init mode ", 0); + return 1; + } + /* Set or reset CLKSRC (register CANCTL1). Does not change the other bits*/ + clk.clksrc = clk.clksrc << 6; + IO_PORTS_8(adrCAN + CANCTL1) &= 0xBF; + IO_PORTS_8(adrCAN + CANCTL1) |= clk.clksrc; + /* Build the CANBTR0 register */ + IO_PORTS_8(adrCAN + CANBTR0) = 0x00; /* Clear before changes */ + IO_PORTS_8(adrCAN + CANBTR0) = (clk.sjw << 6) | (clk.brp); + /* Build the CANBTR1 register */ + IO_PORTS_8(adrCAN + CANBTR1) = 0x00; /* Clear before changes */ + IO_PORTS_8(adrCAN + CANBTR1) = (clk.samp << 7) | (clk.tseg2 << 4) | + (clk.tseg1); + return 0; +} + +/***************************************************************************/ +char canInit1Filter(UNS16 adrCAN, UNS8 nFilter, UNS16 ar, UNS16 mr) +{ + if (! canTestInitMode(adrCAN)) { + /* Error because not init mode */ + MSG_WAR(0X2602, "not in init mode ", 0); + return 1; + } + switch (nFilter) { + case 0: + nFilter = CANIDAR0; /* First bank */ + break; + case 1: + nFilter = CANIDAR2; /* First bank */ + break; + case 2: + nFilter = CANIDAR4; /* Second bank */ + break; + case 3: + nFilter = CANIDAR6; /* Second bank */ + } + /* address of CANIDARx */ + IO_PORTS_8(adrCAN + nFilter) = (UNS8) (ar >> 8); + IO_PORTS_8(adrCAN + nFilter + 1) = (UNS8) (ar); + IO_PORTS_8(adrCAN + nFilter + 4) = (UNS8) (mr >> 8); + IO_PORTS_8(adrCAN + nFilter + 5) = (UNS8) (mr); + return 0; +} + +/***************************************************************************/ +char canInitFilter(UNS16 adrCAN, canBusFilterInit fi) +{ +if (! canTestInitMode(adrCAN)) { + /* Error because not init mode */ + MSG_WAR(0X2603, "not in init mode ", 0); + return 1; + } + IO_PORTS_8(adrCAN + CANIDAC) = fi.idam << 4; + IO_PORTS_8(adrCAN + CANIDAR0) = fi.canidar0; + IO_PORTS_8(adrCAN + CANIDMR0) = fi.canidmr0; + IO_PORTS_8(adrCAN + CANIDAR1) = fi.canidar1; + IO_PORTS_8(adrCAN + CANIDMR1) = fi.canidmr1; + IO_PORTS_8(adrCAN + CANIDAR2) = fi.canidar2; + IO_PORTS_8(adrCAN + CANIDMR2) = fi.canidmr2; + IO_PORTS_8(adrCAN + CANIDAR3) = fi.canidar3; + IO_PORTS_8(adrCAN + CANIDMR3) = fi.canidmr3; + IO_PORTS_8(adrCAN + CANIDAR4) = fi.canidar4; + IO_PORTS_8(adrCAN + CANIDMR4) = fi.canidmr4; + IO_PORTS_8(adrCAN + CANIDAR5) = fi.canidar5; + IO_PORTS_8(adrCAN + CANIDMR5) = fi.canidmr5; + IO_PORTS_8(adrCAN + CANIDAR6) = fi.canidar6; + IO_PORTS_8(adrCAN + CANIDMR6) = fi.canidmr6; + IO_PORTS_8(adrCAN + CANIDAR7) = fi.canidar7; + IO_PORTS_8(adrCAN + CANIDMR7) = fi.canidmr7; + return 0; +} + +/***************************************************************************/ +char canInitMode(UNS16 adrCAN) +{ + IO_PORTS_8(adrCAN + CANCTL0) |= 0x01; /* Set the bit INITRQ */ + while (! canTestInitMode(adrCAN)) { + } + return 0; +} + +/***************************************************************************/ +char canInitModeQ(UNS16 adrCAN) +{ + IO_PORTS_8(adrCAN + CANCTL0) &= 0xFE; /* Clear the bit INITRQ */ + while (canTestInitMode(adrCAN)) { + } + return 0; +} + +/***************************************************************************/ +char canMsgTransmit(UNS16 adrCAN, Message msg) +{ + /* Remind : only CAN A msg implemented. ie id on 11 bits, not 29 */ + UNS8 cantflg; + UNS8 i; + /* Looking for a free buffer */ + cantflg = IO_PORTS_8(adrCAN + CANTFLG); + if ( cantflg == 0) { /* all the TXEx are set */ + MSG_WAR(0X2604, "No buffer free. Msg to transmit is losted ", 0); + return 1; /* No buffer free */ + } + else{ + /* Selecting a buffer */ + IO_PORTS_8(adrCAN + CANTBSEL) = cantflg; + /* We put ide = 0 because id is on 11 bits only */ + IO_PORTS_8(adrCAN + CANTRSID) = (UNS8)(msg.cob_id.w >> 3); + IO_PORTS_8(adrCAN + CANTRSID + 1) = (UNS8)((msg.cob_id.w << 5)| + (msg.rtr << 4)); + + IO_PORTS_8(adrCAN + CANTRSLEN) = msg.len & 0X0F; + /* For the priority, we put the highter bits of the cob_id */ + IO_PORTS_8(adrCAN + CANTRSPRI) = IO_PORTS_8(adrCAN + CANTRSID); + for (i = 0 ; i < msg.len ; i++) { + IO_PORTS_8(adrCAN + CANTRSDTA + i) = msg.data[i]; + } + /* Transmitting the message */ + cantflg = IO_PORTS_8(adrCAN + CANTBSEL);/* to know which buf is selected */ + IO_PORTS_8(adrCAN + CANTBSEL) = 0x00; + IO_PORTS_8(adrCAN + CANTFLG) = cantflg; /* Ready to transmit ! */ + + } + return 0; +} + +/***************************************************************************/ +char canSleepMode(UNS16 adrCAN) +{ + IO_PORTS_8(adrCAN + CANCTL0) &= 0xFB; /* clr the bit WUPE to avoid a wake-up*/ + IO_PORTS_8(adrCAN + CANCTL0) |= 0x02; /* Set the bit SLPRQ. go to Sleep !*/ + + // IO_PORTS_8(adrCAN + CANCTL1) |= 0x04; + // IO_PORTS_8(adrCAN + CANCTL0) |= 0x02; /* Set the bit SLPRQ */ + while ( ! canTestSleepMode(adrCAN)) { + } + + return 0; +} + +/***************************************************************************/ +char canSleepModeQ(UNS16 adrCAN) +{ + if (canTestInitMode(adrCAN)) { + /* Error because in init mode */ + MSG_WAR(0X2606, "not in init mode ", 0); + return 1; + } + IO_PORTS_8(adrCAN + CANCTL0) &= 0xFD; /* clr the bit SLPRQ */ + while ( canTestSleepMode(adrCAN)) { + } + return 0; +} + +/***************************************************************************/ +char canSleepWupMode(UNS16 adrCAN) +{ + if (canTestInitMode(adrCAN)) { + MSG_WAR(0X2607, "not in init mode ", 0); + return 1; + } + IO_PORTS_8(adrCAN + CANCTL0) |= 0x06; /* Set the bits WUPE & SLPRQ */ + while ( ! canTestSleepMode(adrCAN)) { + } + return 0; +} + +/***************************************************************************/ +char canTestInitMode(UNS16 adrCAN) +{ + return IO_PORTS_8(adrCAN + CANCTL1) & 0x01; /* Test the bit INITAK */ +} + +/***************************************************************************/ +char canTestSleepMode(UNS16 adrCAN) +{ + return IO_PORTS_8(adrCAN + CANCTL1) & 0x02; /* Test the bit SLPAK */ +} + +/***************************************************************************/ +UNS8 canSend(UNS8 notused, Message *m) +{ + canMsgTransmit(CANOPEN_LINE_NUMBER_USED, *m); + return 0; +} + + +/**************************************************************************/ +UNS8 f_can_receive(UNS8 notused, Message *msgRcv) +{ + UNS8 i, j; + + switch (CANOPEN_LINE_NUMBER_USED) { + case CAN0 : j = 0; break; + case CAN1 : j = 1; break; + case CAN2 : j = 2; break; + case CAN3 : j = 3; break; + case CAN4 : j = 4; break; + } + + /* See if a message is pending in the stack */ + if (ptrMsgRcv[j].r == ptrMsgRcv[j].w) + return 0x0; // No new message + + /* Increment the reading pointer of the stack */ + if (ptrMsgRcv[j].r == (MAX_STACK_MSG_RCV - 1)) + ptrMsgRcv[j].r = 0; + else + ptrMsgRcv[j].r ++; + + /* Store the message from the stack*/ + msgRcv->cob_id.w = stackMsgRcv[j][ptrMsgRcv[j].r].cob_id.w; + msgRcv->len = stackMsgRcv[j][ptrMsgRcv[j].r].len; + msgRcv->rtr = stackMsgRcv[j][ptrMsgRcv[j].r].rtr; + for (i = 0 ; i < stackMsgRcv[j][ptrMsgRcv[j].r].len ; i++) + msgRcv->data[i] = stackMsgRcv[j][ptrMsgRcv[j].r].data[i]; + return 0xFF; +} + + +/****************************************************************************** + ******************************* CAN INTERRUPT *******************************/ + +void __attribute__((interrupt)) can0HdlTra (void) +{ + +} + +void __attribute__((interrupt)) can0HdlRcv (void) +{ + UNS8 i; + lock(); + IO_PORTS_8(PORTB) &= ~ 0x40; // led 6 port B : ON + UNS8 NewPtrW; + /* We are obliged to save the message while the interruption is pending */ + /* Increment the writing stack pointer before writing the msg */ + if (ptrMsgRcv[0].w == (MAX_STACK_MSG_RCV - 1)) + NewPtrW = 0; + else + NewPtrW = ptrMsgRcv[0].w + 1; + + if (NewPtrW == ptrMsgRcv[0].r) { + /* The stack is full. The last msg received before this one is lost */ + MSG_WAR(0X1620, "Stack for received msg is full", 0); + //IO_PORTS_8(PORTB) &= ~0x40; // led 6 : ON (for debogue) + } + else + ptrMsgRcv[0].w = NewPtrW; + + /* Store the message */ + stackMsgRcv[0][ptrMsgRcv[0].w].cob_id.w = IO_PORTS_16(CAN0 + CANRCVID) >> 5; + stackMsgRcv[0][ptrMsgRcv[0].w].len = IO_PORTS_8(CAN0 + CANRCVLEN) & 0x0F; + stackMsgRcv[0][ptrMsgRcv[0].w].rtr = (IO_PORTS_8(CAN0 + CANRCVID + 1) >> 4) & 0x01; + for (i = 0 ; i < stackMsgRcv[0][ptrMsgRcv[0].w].len ; i++) + stackMsgRcv[0][ptrMsgRcv[0].w].data[i] = IO_PORTS_8(CAN0 + CANRCVDTA + i); + + // The message is stored , so + // we can now release the receive foreground buffer + // and acknowledge the interruption + IO_PORTS_8(CAN0 + CANRFLG) |= 0x01; + // Not very usefull + IO_PORTS_8(CAN0 + CANCTL0) |= 0x80; + IO_PORTS_8(PORTB) |= 0x40; // led 6 port B : ON + unlock(); +} + +void __attribute__((interrupt)) can0HdlWup (void) +{ + +} + +void __attribute__((interrupt)) can0HdlErr (void) +{ + +} + +void __attribute__((interrupt)) can1HdlTra (void) +{ + +} + +void __attribute__((interrupt)) can1HdlRcv (void) +{ + UNS8 i; + lock(); + UNS8 NewPtrW; + /* We are obliged to save the message while the interruption is pending */ + /* Increment the writing stack pointer before writing the msg */ + if (ptrMsgRcv[1].w == (MAX_STACK_MSG_RCV - 1)) + NewPtrW = 0; + else + NewPtrW = ptrMsgRcv[1].w + 1; + + if (NewPtrW == ptrMsgRcv[1].r) { + /* The stack is full. The last msg received before this one is lost */ + MSG_WAR(0X2620, "Stack for received msg is full", 0); + } + else + ptrMsgRcv[1].w = NewPtrW; + + /* Store the message */ + stackMsgRcv[1][ptrMsgRcv[1].w].cob_id.w = IO_PORTS_16(CAN1 + CANRCVID) >> 5; + stackMsgRcv[1][ptrMsgRcv[1].w].len = IO_PORTS_8(CAN1 + CANRCVLEN) & 0x0F; + stackMsgRcv[0][ptrMsgRcv[0].w].rtr = (IO_PORTS_8(CAN1 + CANRCVID + 1) >> 4) & 0x01; + for (i = 0 ; i < stackMsgRcv[1][ptrMsgRcv[1].w].len ; i++) + stackMsgRcv[1][ptrMsgRcv[1].w].data[i] = IO_PORTS_8(CAN1 + CANRCVDTA + i); + + // The message is stored , so + // we can now release the receive foreground buffer + // and acknowledge the interruption + IO_PORTS_8(CAN1 + CANRFLG) |= 0x01; + // Not very usefull + IO_PORTS_8(CAN1 + CANCTL0) |= 0x80; + unlock(); +} + +void __attribute__((interrupt)) can1HdlWup (void) +{ + +} + +void __attribute__((interrupt)) can1HdlErr (void) +{ + +} + +void __attribute__((interrupt)) can2HdlTra (void) +{ + +} + +void __attribute__((interrupt)) can2HdlRcv (void) +{ + +} + +void __attribute__((interrupt)) can2HdlWup (void) +{ + +} + +void __attribute__((interrupt)) can2HdlErr (void) +{ + +} + +void __attribute__((interrupt)) can3HdlTra (void) +{ + +} + +void __attribute__((interrupt)) can3HdlRcv (void) +{ + +} + +void __attribute__((interrupt)) can3HdlWup (void) +{ + +} + +void __attribute__((interrupt)) can3HdlErr (void) +{ + +} + +void __attribute__((interrupt)) can4HdlTra (void) +{ + +} + +void __attribute__((interrupt)) can4HdlRcv (void) +{ + +} + +void __attribute__((interrupt)) can4HdlWup (void) +{ + +} + +void __attribute__((interrupt)) can4HdlErr (void) +{ + +} + + + diff -r 000000000000 -r 4472ee7c6c3e drivers/hcs12/interrupt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/hcs12/interrupt.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,63 @@ +/* +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 +*/ + +/* +Functions called by interrupts vectors. +*/ +/* +This is a part of the driver, of course ! +But you have to put your code in this functions, +if you plan to use interruptions. +*/ + +#include "../include/hcs12/applicfg.h" +#include "../include/hcs12/error.h" +#include "../include/hcs12/candriver.h" +#include "../include/hcs12/asm-m68hc12/regs.h" +#include "../include/hcs12/asm-m68hc12/portsaccess.h" +#include "../include/hcs12/asm-m68hc12/ports_def.h" +#include "../include/hcs12/asm-m68hc12/ports.h" +#include "../include/hcs12/interrupt.h" + +extern volatile char msgRecu; +extern volatile Message canMsgRcv; + + + +/* Inhibe les interruptions */ + +void lock (void) +{ + unsigned short mask; + __asm__ __volatile__ ("tpa\n\tsei" : "=d"(mask)); + +} + +/* Autorise les interruptions */ +void unlock (void) +{ + __asm__ __volatile__ ("cli"); +} + + + + diff -r 000000000000 -r 4472ee7c6c3e drivers/hcs12/ports.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/hcs12/ports.s Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,11 @@ +/* +Define the i/o port global symbol +*/ + +.globl _io_ports +_io_ports=0x0000 + +/* +0x0000 is the default mapping at reset. (it is 0x1000 for 68hc11) +*/ + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e drivers/hcs12/ports.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/hcs12/ports.txt Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,652 @@ +/* MC9S12DP256 Revision 1.1 66 Registers MOTOROLA */ + +$0000 PORTA +$0001 PORTB +$0002 DDRA +$0003 DDRB + +$0008 PORTE +$0009 DDRE +$000A PEAR +$000B MODE +$000C PUCR +$000D RDRIV +$000E EBICTL + +$0010 INITRM +$0011 INITRG +$0012 INITEE +$0013 MISC +$0014 MTST0 +$0015 ITCR +$0016 ITEST +$0017 MTST1 + +$001A PARTIDH +$001B PARTIDL +$001C MEMSIZ0 +$001D MEMSIZ1 +$001E INTCR +$001F HPRIO + +$0028 BKPCT0 +$0029 BKPCT1 +$002A BKP0X +$002B BKP0H +$002C BKP0L +$002D BKP1X +$002E BKP1H +$002F BKP1L +$0030 PPAGE + +$0032 PORTK +$0033 DDRK +$0034 SYNR +$0035 REFDV +$0036 CTFLG +$0037 CRGFLG +$0038 CRGINT +$0039 CLKSEL +$003A PLLCTL +$003B RTICTL +$003C COPCTL +$003D FORBYP +$003E CTCTL +$003F ARMCOP +$0040 TIOS +$0041 TCFORC +$0042 TOC7M +$0043 TOC7D +$0044 TCNTH +$0045 TCNTL +$0046 TSCR1 +$0047 TTOV +$0048 TCTL1 +$0049 TCTL2 +$004A TCTL3 +$004B TCTL4 +$004C TIE +$004D TSCR2 +$004E TFLG1 +$004F TFLG2 +$0050 TC0H +$0051 TC0L +$0052 TC1H +$0053 TC1L +$0054 TC2H +$0055 TC2L +$0056 TC3H +$0057 TC3L +$0058 TC4H +$0059 TC4L +$005A TC5H +$005B TC5L +$005C TC6H +$005D TC6L +$005E TC7H +$005F TC7L +$0060 PACTL +$0061 PAFLG +$0062 PACN3H +$0063 PACN2L +$0064 PACN1H +$0065 PACN0L +$0066 MCCTL +$0067 MCFLG +$0068 ICPAR +$0069 DLYCT +$006A ICOVW +$006B ICSYS + +$006D TIMTST + +$0070 PBCTL +$0071 PBFLG +$0072 PA3H +$0073 PA2H +$0074 PA1H +$0075 PA0H +$0076 MCCNTH +$0077 MCCNTL +$0078 TC0HH +$0079 TC0HL +$007A TC1HH +$007B TC1HL +$007C TC2HH +$007D TC2HL +$007E TC3HH + +$0080 ATD0CTL0 +$0081 ATD00CTL1 +$0082 ATD0CTL2 +$0083 ATD0CTL3 +$0084 ATD0CTL4 +$0085 ATD0CTL5 +$0086 ATD0STAT0 +$0087 ATD0STAT1 +$0088 ATD0TEST0 +$0089 ATD0TEST1 + +$008D ATD0DIEN + +$008F PORTAD0 +$0090 ATD0DR0H +$0091 ATD0DR0L +$0092 ATD0DR1H +$0093 ATD0DR1L +$0094 ATD0DR2H +$0095 ATD0DR2L +$0096 ATD0DR3H +$0097 ATD0DR3L +$0098 ATD0DR4H +$0099 ATD0DR4L +$009A ATD0DR5H +$009B ATD0DR5L +$009C ATD0DR6H +$009D ATD0DR6L +$009E ATD0DR7H +$009F ATD0DR7L +$00A0 PWME +$00A1 PWMPOL +$00A2 PWMCLK +$00A3 PWMPRCLK +$00A4 PWMCAE +$00A5 PWMCTL +$00A6 PWMTST +$00A7 PWMPRSC +$00A8 PWMSCLA +$00A9 PWMSCLB +$00AA PWMSCNTA +$00AB PWMSCNTB +$00AC PWMCNT0 +$00AD PWMCNT1 +$00AE PWMCNT2 +$00AF PWMCNT3 +$00B0 PWMCNT4 +$00B1 PWMCNT5 +$00B2 PWMCNT6 +$00B3 PWMCNT7 +$00B4 PWMPER0 +$00B5 PWMPER1 +$00B6 PWMPER2 +$00B7 PWMPER3 +$00B8 PWMPER4 +$00B9 PWMPER5 +$00BA PWMPER6 +$00BB PWMPER7 +$00BC PWMDTY0 +$00BD PWMDTY1 +$00BE PWMDTY2 +$00BF PWMDTY3 +$00C0 PWMDTY4 +$00C1 PWMDTY5 +$00C2 PWMDTY6 +$00C3 PWMDTY7 +$00C4 PWMSDN + +$00C8 SCI0BDH +$00C9 SCI0BDL +$00CA SC0CR1 +$00CB SCI0CR2 +$00CC SCI0SR1 +$00CD SC0SR2 +$00CE SCI0DRH +$00CF SCI0DRL +$00D0 SCI1BDH +$00D1 SCI1BDL +$00D2 SC1CR1 +$00D3 SCI1CR2 +$00D4 SCI1SR1 +$00D5 SC1SR2 +$00D6 SCI1DRH +$00D7 SCI1DRL +$00D8 SPI0CR1 +$00D9 SPI0CR2 +$00DA SPI0BR +$00DB SPI0SR + +$00DD SPI0DR + +$00E0 IBAD +$00E1 IBFD +$00E2 IBCR +$00E3 IBSR +$00E4 IICDR + +$00E8 DLCBCR1 +$00E9 DLCBSVR +$00EA DLCBCR2 +$00EB DLCBDR +$00EC DLCBARD +$00ED DLCBRSR +$00EE DLCSCR +$00EF DLCBSTAT +$00F0 SPI1CR1 +$00F1 SPI1CR2 +$00F2 SPI1BR +$00F3 SPI1SR + +$00F5 SPI1DR + +$00F8 SPI2CR1 +$00F9 SPI2CR2 +$00FA SPI2BR +$00FB SPI2SR + +$00FD SPI2DR + +$0100 FCLKDIV +$0101 FSEC + +$0103 FCNFG +$0104 FPROT +$0105 FSTAT +$0106 FCMD + +$0110 ECLKDIV + +$0113 ECNFG +$0114 EPROT +$0115 ESTAT +$0116 ECMD + +$0120 ATD1CTL0 +$0121 ATD1CTL1 +$0122 ATD1CTL2 +$0123 ATD1CTL3 +$0124 ATD1CTL4 +$0125 ATD1CTL5 +$0126 ATD1STAT0 +$0127 ATD1STAT1 +$0128 ATD1TEST0 +$0129 ATD1TEST1 + +$012D ATDDIEN + +$012F PORTAD1 +$0130 ATD1DR0H +$0131 ATD1DR0L +$0132 ATD1DR1H +$0133 ATD1DR1L +$0134 ATD1DR2H +$0135 ATD1DR2L +$0136 ATD1DR3H +$0137 ATD1DR3L +$0138 ATD1DR4H +$0139 ATD1DR4L +$013A ATD1DR5H +$013B ATD1DR5L +$013C ATD1DR6H +$013D ATD1DR6L +$013E ATD1DR7H +$013F ATD1DR7L +$0140 CAN0CTL0 +$0141 CAN0CTL1 +$0142 CAN0BTR0 +$0143 CAN0BTR1 +$0144 CAN0RFLG +$0145 CAN0RIER +$0146 CAN0TFLG +$0147 CAN0TIER +$0148 CAN0TARQ +$0149 CAN0TAAK +$014A CAN0TBSEL +$014B CAN0IDAC + +$014E CAN0RXERR +$014F CAN0TXERR +$0150 CAN0IDAR0 +$0151 CAN0IDAR1 +$0152 CAN0IDAR2 +$0153 CAN0IDAR3 +$0154 CAN0IDMR0 +$0155 CAN0IDMR1 +$0156 CAN0IDMR2 +$0157 CAN0IDMR3 +$0158 CAN0IDAR4 +$0159 CAN0IDAR5 +$015A CAN0IDAR6 +$015B CAN0IDAR7 +$015C CAN0IDMR4 +$015D CAN0IDMR5 +$015E CAN0IDMR6 +$015F CAN0IDMR7 +$0160 CAN0RXFG0 +$0161 CAN0RXFG1 +$0162 CAN0RXFG2 +$0163 CAN0RXFG3 +$0164 CAN0RXFG4 +$0165 CAN0RXFG5 +$0166 CAN0RXFG6 +$0167 CAN0RXFG7 +$0168 CAN0RXFG8 +$0169 CAN0RXFG9 +$016A CAN0RXFGA +$016B CAN0RXFGB +$016C CAN0RXFGC +$016D CAN0RXFGD +$016E CAN0RXFGE +$016F CAN0RXFGF +$0170 CAN0TXFG0 +$0171 CAN0TXFG1 +$0172 CAN0TXFG2 +$0173 CAN0TXFG3 +$0174 CAN0TXFG4 +$0175 CAN0TXFG5 +$0176 CAN0TXFG6 +$0177 CAN0TXFG7 +$0178 CAN0TXFG8 +$0179 CAN0TXFG9 +$017A CAN0TXFGA +$017B CAN0TXFGB +$017C CAN0TXFGC +$017D CAN0TXFGD +$017E CAN0TXFGE +$017F CAN0TXFGF +$0180 CAN1CTL0 +$0181 CAN1CTL1 +$0182 CAN1BTR0 +$0183 CAN1BTR1 +$0184 CAN1RFLG +$0185 CAN1RIER +$0186 CAN1TFLG +$0187 CAN1TIER +$0188 CAN1TARQ +$0189 CAN1TAAK +$018A CAN1TBSEL +$018B CAN1IDAC +$018E CAN1RXERR +$018F CAN1TXERR +$0190 CAN1IDAR0 +$0191 CAN1IDAR1 +$0192 CAN1IDAR2 +$0193 CAN1IDAR3 +$0194 CAN1IDMR0 +$0195 CAN1IDMR1 +$0196 CAN1IDMR2 +$0197 CAN1IDMR3 +$0198 CAN1IDAR4 +$0199 CAN1IDAR5 +$019A CAN1IDAR6 +$019B CAN1IDAR7 +$019C CAN1IDMR4 +$019D CAN1IDMR5 +$019E CAN1IDMR6 +$019F CAN1IDMR7 + +$01A0 CAN1RXFG0 +$01A1 CAN1RXFG1 +$01A2 CAN1RXFG2 +$01A3 CAN1RXFG3 +$01A4 CAN1RXFG4 +$01A5 CAN1RXFG5 +$01A6 CAN1RXFG6 +$01A7 CAN1RXFG7 +$01A8 CAN1RXFG8 +$01A9 CAN1RXFG9 +$01AA CAN1RXFGA +$01AB CAN1RXFGB +$01AC CAN1RXFGC +$01AD CAN1RXFGD +$01AE CAN1RXFGE +$01AF CAN1RXFGF +$01B0 CAN1TXFG0 +$01B1 CAN1TXFG1 +$01B2 CAN1TXFG2 +$01B3 CAN1TXFG3 +$01B4 CAN1TXFG4 +$01B5 CAN1TXFG5 +$01B6 CAN1TXFG6 +$01B7 CAN1TXFG7 +$01B8 CAN1TXFG8 +$01B9 CAN1TXFG9 +$01BA CAN1TXFGA +$01BB CAN1TXFGB +$01BC CAN1TXFGC +$01BD CAN1TXFGD +$01BE CAN1TXFGE +$01BF CAN1TXFGF +$01C0 CAN2CTL0 +$01C1 CAN2CTL1 +$01C2 CAN2BTR0 +$01C3 CAN2BTR1 +$01C4 CAN2RFLG +$01C5 CAN2RIER +$01C6 CAN2TFLG +$01C7 CAN2TIER +$01C8 CAN2TARQ +$01C9 CAN2TAAK +$01CA CAN2TBSEL +$01CB CAN2IDAC + +$01CE CAN2RXERR +$01CF CAN2TXERR +$01D0 CAN2IDAR0 +$01D1 CAN2IDAR1 +$01D2 CAN2IDAR2 +$01D3 CAN2IDAR3 +$01D4 CAN2IDMR0 +$01D5 CAN2IDMR1 +$01D6 CAN2IDMR2 +$01D7 CAN2IDMR3 +$01D8 CAN2IDAR4 +$01D9 CAN2IDAR5 +$01DA CAN2IDAR6 +$01DB CAN2IDAR7 +$01DC CAN2IDMR4 +$01DD CAN2IDMR5 +$01DE CAN2IDMR6 +$01DF CAN2IDMR7 + +$01E0 CAN2RXFG0 +$01E1 CAN2RXFG1 +$01E2 CAN2RXFG2 +$01E3 CAN2RXFG3 +$01E4 CAN2RXFG4 +$01E5 CAN2RXFG5 +$01E6 CAN2RXFG6 +$01E7 CAN2RXFG7 +$01E8 CAN2RXFG8 +$01E9 CAN2RXFG9 +$01EA CAN2RXFGA +$01EB CAN2RXFGB +$01EC CAN2RXFGC +$01ED CAN2RXFGD +$01EE CAN2RXFGE +$01EF CAN2RXFGF +$01F0 CAN2TXFG0 +$01F1 CAN2TXFG1 +$01F2 CAN2TXFG2 +$01F3 CAN2TXFG3 +$01F4 CAN2TXFG4 +$01F5 CAN2TXFG5 +$01F6 CAN2TXFG6 +$01F7 CAN2TXFG7 +$01F8 CAN2TXFG8 +$01F9 CAN2TXFG9 +$01FA CAN2TXFGA +$01FB CAN2TXFGB +$01FC CAN2TXFGC +$01FD CAN2TXFGD +$01FE CAN2TXFGE +$01FF CAN2TXFGF + +$0200 CAN3CTL0 +$0201 CAN3CTL1 +$0202 CAN3BTR0 +$0203 CAN3BTR1 +$0204 CAN3RFLG +$0205 CAN3RIER +$0206 CAN3TFLG +$0207 CAN3TIER +$0208 CAN3TARQ +$0209 CAN3TAAK +$020A CAN3TBSEL +$020B CAN3IDAC + +$020E CAN3RXERR +$020F CAN3TXERR +$0210 CAN3IDAR0 +$0211 CAN3IDAR1 +$0212 CAN3IDAR2 +$0213 CAN3IDAR3 +$0214 CAN3IDMR0 +$0215 CAN3IDMR1 +$0216 CAN3IDMR2 +$0217 CAN3IDMR3 +$0218 CAN3IDAR4 +$0219 CAN3IDAR5 +$021A CAN3IDAR6 +$021B CAN3IDAR7 +$021C CAN3IDMR4 +$021D CAN3IDMR5 +$021E CAN3IDMR6 +$021F CAN3IDMR7 + +$0220 CAN3RXFG0 +$0221 CAN3RXFG1 +$0222 CAN3RXFG2 +$0223 CAN3RXFG3 +$0224 CAN3RXFG4 +$0225 CAN3RXFG5 +$0226 CAN3RXFG6 +$0227 CAN3RXFG7 +$0228 CAN3RXFG8 +$0229 CAN3RXFG9 +$022A CAN3RXFGA +$022B CAN3RXFGB +$022C CAN3RXFGC +$022D CAN3RXFGD +$022E CAN3RXFGE +$022F CAN3RXFGF +$0230 CAN3TXFG0 +$0231 CAN3TXFG1 +$0232 CAN3TXFG2 +$0233 CAN3TXFG3 +$0234 CAN3TXFG4 +$0235 CAN3TXFG5 +$0236 CAN3TXFG6 +$0237 CAN3TXFG7 +$0238 CAN3TXFG8 +$0239 CAN3TXFG9 +$023A CAN3TXFGA +$023B CAN3TXFGB +$023C CAN3TXFGC +$023D CAN3TXFGD +$023E CAN3TXFGE +$023F CAN3TXFGF + +$0240 PTT +$0241 PTIT +$0242 DDRT +$0243 RDRT +$0244 PERT +$0245 PPST + +$0248 PTS +$0249 PTIS +$024A DDRS +$024B RDRS +$024C PERS +$024D PPSS +$024E WOMS + +$0250 PTM +$0251 PTIM +$0252 DDRM +$0253 RDRM +$0254 PERM +$0255 PPSM +$0256 WOMM + +$0258 PTP +$0259 PTIP +$025A DDRP +$025B RDRP +$025C PERP +$025D PPSP +$025E PIEP +$025F PIFP +$0260 PTH +$0261 PTIH +$0262 DDRH +$0263 RDRH +$0264 PERH +$0265 PPSH +$0266 PIEH +$0267 PIFH +$0268 PTJ +$0269 PTIJ +$026A DDRJ +$026B RDRJ +$026C PERJ +$026D PPSJ +$026E PIEJ +$026F PIFJ + +$0280 CAN4CTL0 +$0281 CAN4CTL1 +$0282 CAN4BTR0 +$0283 CAN4BTR1 +$0284 CAN4RFLG +$0285 CAN4RIER +$0286 CAN4TFLG +$0287 CAN4TIER +$0288 CAN4TARQ +$0289 CAN4TAAK +$028A CAN4TBSEL +$028B CAN4IDAC + +$028E CAN4RXERR +$028F CAN4TXERR +$0290 CAN4IDAR0 +$0291 CAN4IDAR1 +$0292 CAN4IDAR2 +$0293 CAN4IDAR3 +$0294 CAN4IDMR0 +$0295 CAN4IDMR1 +$0296 CAN4IDMR2 +$0297 CAN4IDMR3 +$0298 CAN4IDAR4 +$0299 CAN4IDAR5 +$029A CAN4IDAR6 +$029B CAN4IDAR7 +$029C CAN4IDMR4 +$029D CAN4IDMR5 +$029E CAN4IDMR6 +$029F CAN4IDMR7 + +$02A0 CAN4RXFG0 +$02A1 CAN4RXFG1 +$02A2 CAN4RXFG2 +$02A3 CAN4RXFG3 +$02A4 CAN4RXFG4 +$02A5 CAN4RXFG5 +$02A6 CAN4RXFG6 +$02A7 CAN4RXFG7 +$02A8 CAN4RXFG8 +$02A9 CAN4RXFG9 +$02AA CAN4RXFGA +$02AB CAN4RXFGB +$02AC CAN4RXFGC +$02AD CAN4RXFGD +$02AE CAN4RXFGE +$02AF CAN4RXFGF +$02B0 CAN4TXFG0 +$02B1 CAN4TXFG1 +$02B2 CAN4TXFG2 +$02B3 CAN4TXFG3 +$02B4 CAN4TXFG4 +$02B5 CAN4TXFG5 +$02B6 CAN4TXFG6 +$02B7 CAN4TXFG7 +$02B8 CAN4TXFG8 +$02B9 CAN4TXFG9 +$02BA CAN4TXFGA +$02BB CAN4TXFGB +$02BC CAN4TXFGC +$02BD CAN4TXFGD +$02BE CAN4TXFGE +$02BF CAN4TXFGF + + diff -r 000000000000 -r 4472ee7c6c3e drivers/timers_unix/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_unix/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e drivers/timers_unix/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_unix/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,64 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +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) + +OBJS = $(TIMERS_DRIVER).o + +SRC_HFILES = ../../include/$(TIMERS_DRIVER)/timerscfg.h + +TARGET_HFILES = $(PREFIX)/include/canfestival/timerscfg.h + +all: driver + +driver: $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: + mkdir -p $(PREFIX)/include/canfestival + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(TARGET_HFILES) + +clean: + -\rm $(OBJS) + +mrproper: clean + + diff -r 000000000000 -r 4472ee7c6c3e drivers/timers_unix/timers_unix.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_unix/timers_unix.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,96 @@ +#include + +#include +#include +#include + +#include "applicfg.h" +#include "can_driver.h" +#include "timer.h" + +pthread_mutex_t CanFestival_mutex = PTHREAD_MUTEX_INITIALIZER; + +TIMEVAL last_time_set = TIMEVAL_MAX; + +struct timeval last_sig; + +char stop_timer=0; + +void sig(int val) +{ + signal( SIGALRM, sig); + gettimeofday(&last_sig,NULL); +// printf("getCurrentTime() return=%u\n", p.tv_usec); +} + +void initTimer(void) +{ + gettimeofday(&last_sig,NULL); + signal( SIGALRM, sig); + stop_timer = 0; +} + +void stopTimer(void) +{ + stop_timer = 1; + kill(0, SIGALRM); +} + +void EnterMutex(void) +{ + pthread_mutex_lock(&CanFestival_mutex); +} + +void LeaveMutex(void) +{ + pthread_mutex_unlock(&CanFestival_mutex); +} + +void TimerLoop(TimerCallback_t init_callback) +{ + initTimer(); + // At first, TimeDispatch will call init_callback. + SetAlarm(NULL, 0, init_callback, 0, 0); + while (!stop_timer) { + EnterMutex(); + TimeDispatch(); + LeaveMutex(); + pause(); + } +} + +void ReceiveLoop(void* arg) +{ + canReceiveLoop((CAN_HANDLE)arg); +} + +void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread) +{ + pthread_create(Thread, NULL, (void *)&ReceiveLoop, (void*)fd0); +} + +void WaitReceiveTaskEnd(TASK_HANDLE Thread) +{ + pthread_join(Thread, NULL); +} + +#define max(a,b) a>b?a:b +void setTimer(TIMEVAL value) +{ +// printf("setTimer(TIMEVAL value=%d)\n", value); + struct itimerval timerValues; + struct itimerval timerV = {{0,0},{0,0}}; + timerValues.it_value.tv_sec = 0; + timerValues.it_value.tv_usec = max(value,1); + timerValues.it_interval.tv_sec = 0; + timerValues.it_interval.tv_usec = 0; + setitimer(ITIMER_REAL, &timerValues, &timerV); +} + +TIMEVAL getElapsedTime(void) +{ + struct timeval p; + gettimeofday(&p,NULL); +// printf("getCurrentTime() return=%u\n", p.tv_usec); + return (p.tv_sec - last_sig.tv_sec)* 1000000 + p.tv_usec - last_sig.tv_usec; +} diff -r 000000000000 -r 4472ee7c6c3e drivers/timers_xeno/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_xeno/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e drivers/timers_xeno/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_xeno/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,62 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +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) + +OBJS = $(TIMERS_DRIVER).o + +SRC_HFILES = ../../include/$(TIMERS_DRIVER)/timerscfg.h + +TARGET_HFILES = $(PREFIX)/include/canfestival/timerscfg.h + +all: driver + +driver: $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: + mkdir -p $(PREFIX)/include/canfestival + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(TARGET_HFILES) + +clean: + -\rm $(OBJS) + +mrproper: clean diff -r 000000000000 -r 4472ee7c6c3e drivers/timers_xeno/timers_xeno.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/timers_xeno/timers_xeno.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,138 @@ +#include +#include + +#include +#include +#include +#include + +#include "applicfg.h" +#include "can_driver.h" +#include "timer.h" + +#define TIMERLOOP_TASK_CREATED 1 + +RT_MUTEX CanFestival_mutex; +RT_TASK timerloop_task; +RT_ALARM timerloop_alarm; +RTIME last_time_read; +RTIME last_occured_alarm; +RTIME last_alarm_set; + +char stop_timer=0; + +void cleanup_all(void) +{ + rt_task_delete(&timerloop_task); + rt_alarm_delete(&timerloop_alarm); +} +void stopTimer(void) +{ + stop_timer = 1; + rt_task_unblock(&timerloop_task); +} + + +void EnterMutex(void) +{ + rt_mutex_lock(&CanFestival_mutex, TM_INFINITE); +} + +void LeaveMutex(void) +{ + rt_mutex_unlock(&CanFestival_mutex); +} + +void timerloop_task_proc(void *arg) +{ + int ret; + do{ + do{ + last_occured_alarm = last_alarm_set; + EnterMutex(); + TimeDispatch(); + LeaveMutex(); + }while ((ret = rt_task_sleep_until(last_alarm_set)) == 0); + }while (ret == -EINTR && !stop_timer ); + printf("End of TimerLoop, code %d\n",ret); +} + +void TimerLoop(TimerCallback_t init_callback) +{ + int ret; + stop_timer = 0; + + ret = rt_alarm_create( &timerloop_alarm, NULL); + if (ret) { + printf("Failed to create timerloop_alarm, code %d\n",errno); + goto error; + } + + //create timerloop_task + ret = rt_task_create(&timerloop_task,"timerloop",0,50,0); + if (ret) { + printf("Failed to create timerloop_task, code %d\n",errno); + return; + } + + getElapsedTime(); + last_alarm_set = last_time_read; + last_occured_alarm = last_alarm_set; + SetAlarm(NULL, 0, init_callback, 0, 0); + // start timerloop_task + ret = rt_task_start(&timerloop_task,&timerloop_task_proc,NULL); + if (ret) { + printf("Failed to start timerloop_task, code %d\n",errno); + goto error; + } + + // At first, TimeDispatch will call init_callback. + pause(); + +error: + cleanup_all(); +} + +void ReceiveLoop_task_proc(void* arg) +{ + canReceiveLoop((CAN_HANDLE)arg); +} + +void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE *ReceiveLoop_task) +{ + int ret; + static int id = 0; + char taskname[64]; + sprintf(taskname,"canloop%d",id); + id++; + + //create timerloop_task + ret = rt_task_create(ReceiveLoop_task,taskname,0,50,0); + if (ret) { + printf("Failed to create ReceiveLoop_task number %d, code %d\n", id, errno); + return; + } + // start timerloop_task + ret = rt_task_start(ReceiveLoop_task,&ReceiveLoop_task_proc,(void*)fd0); + if (ret) { + printf("Failed to start ReceiveLoop_task number %d, code %d\n", id, errno); + return; + } +} + +void WaitReceiveTaskEnd(TASK_HANDLE Thread) +{ + rt_task_delete(&Thread); +} +#define max(a,b) a>b?a:b +void setTimer(TIMEVAL value) +{ + last_alarm_set = last_time_read + value; + rt_task_unblock(&timerloop_task); +} + +TIMEVAL getElapsedTime(void) +{ + last_time_read = rt_timer_ticks2ns(rt_timer_read()); + return last_time_read - last_occured_alarm; +} diff -r 000000000000 -r 4472ee7c6c3e examples/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,84 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -Os +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +BINUTILS_PREFIX = SUB_BINUTILS_PREFIX +TARGET = SUB_TARGET + +INCLUDES = -I../../include -I../../include/hcs12 +MEMORY_X = ../../include/hcs12/board/arch + +OBJCOPY = $(BINUTILS_PREFIX)objcopy +OBJCOPY_FLAGS = --only-section=.text --only-section=.rodata --only-section=.vectors --only-section=.data + +PROGDEFINES = -mnoshort -Wall -Wmissing-prototypes -fno-strict-aliasing -g + +PGR=AppliMaster + +MASTER_OBJS = objdict.o appli.o vectors.o + +OBJS = ../../src/hc12_pdo.o ../../src/hc12_sdo.o ../../src/hc12_init.o ../../src/hc12_sync.o\ + ../../src/hc12_objacces.o ../../src/hc12_lifegrd.o ../../src/hc12_timer.o ../../src/hc12_nmtMaster.o\ + ../../drivers/hc12/canOpenDriver.o ../../drivers/hc12/ports.o ../../drivers/hc12/interrupt.o\ + ../../drivers/hc12/timerhw.o ../../drivers/hc12/variahw.o $(MASTER_OBJS) + +LDFLAGS= -Wl,-m,m68hc12elfb -L$(MEMORY_X) + +all: $(PGR).elf $(PGR).s19 $(PGR).b $(PGR).s MSG + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -c -o $@ $< + +%o: %s + $(CC) -c -x assembler-with-cpp $(PROG_CFLAGS) -o $@ $< + +$(PGR).elf: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) + +$(PGR).s19: $(PGR).elf + $(OBJCOPY) --output-target=srec $(OBJCOPY_FLAGS) $< $@ + +$(PGR).b: $(PGR).elf + $(OBJCOPY) --output-target=binary --gap-fill=255 --only-section=.data $(OBJCOPY_FLAGS) $< $@ + +$(PGR).s: $(PGR).elf + @echo "Desassemble" + $(BINUTILS_PREFIX)objdump -D $(PGR).elf > $(PGR).s + +MSG: + $(BINUTILS_PREFIX)readelf -S $(PGR).elf + @echo + $(BINUTILS_PREFIX)size $(PGR).elf + +clean: + -\rm $(MASTER_OBJS) + +mrproper: clean + -\rm $(PGR).elf $(PGR).s19 $(PGR).b $(PGR).s + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/appli.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/appli.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1143 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include /* for NULL */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "objacces.h" +#include "canOpenDriver.h" +#include "sdo.h" +#include "pdo.h" +#include "init.h" +#include "timer.h" +#include "lifegrd.h" +#include "sync.h" + +#include "nmtMaster.h" + +// For prototype of exit(); +#define exit _exit + + + + +// HCS12 configuration +// ----------------------------------------------------- + +enum E_CanBaudrate +{ + CAN_BAUDRATE_250K, + CAN_BAUDRATE_500K, + CAN_BAUDRATE_1M, + CAN_BAUDRATE_OLD_VALUE +}; + +const canBusTime CAN_Baudrates[] = +{ + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 3, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 13 tq for the TIME 1 segment (tseg1 = 12) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 4 MHZ (brp = 3+1), and there are 16 tq in the bit time, + so the freq of the bit time is 250 kHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 13 tq for the TIME 1 segment (tseg1 = 12) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 8 MHZ (brp = 1+1), and there are 16 tq in the bit time, + so the freq of the bit time is 500 kHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 4, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 5 tq for the TIME 1 segment (tseg1 = 4) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 8 MHZ (brp = 1+1), and there are 8 tq in the bit time, + so the freq of the bit time is 1 MHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 0, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 1, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 1, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 4, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 9, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 10 tq for the TIME 1 segment (tseg1 = 9) + - 5 tq for the TIME 2 segment (tseg2 = 4) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 16 MHZ (brp = 0), and there are 16 tq in the bit time, + so the freq of the bit time is 1 MHz. + */ + } +}; + + + +// Required definition variables +// ----------------------------- +// The variables that you should define for debugging. +// They are used by the macro MSG_ERR and MSG_WAR in applicfg.h +// if the node is a slave, they can be mapped in the object dictionnary. + +UNS8 printMsgErrToConsole = 1; +UNS8 printMsgWarToConsole = 1; + +// The variables mapped in the object dictionnary +// ---------------------------------------------- +extern UNS32 canopenErrNB_node5; // Mapped at index 0x6000, subindex 0x0 +extern UNS32 canopenErrVAL_node5; // Mapped at index 0x6001, subindex 0x0 +extern UNS8 second; // Mapped at index 0x6002, subindex 0x1 +extern UNS8 minutes; // Mapped at index 0x6002, subindex 0x2 +extern UNS8 hour; // Mapped at index 0x6002, subindex 0x3 +extern UNS8 day; // Mapped at index 0x6002, subindex 0x4 +extern UNS32 canopenErrNB; // Mapped at index 0x6003, subindex 0x1 +extern UNS32 canopenErrVAL; // Mapped at index 0x6003, subindex 0x2 + +/*************************User's variables declaration**************************/ +UNS8 connectedNode[128]; +volatile UNS8 sec = 0; // To count the time every second +UNS8 softCount = 0; + +/* The variable to map in a PDO is defined at index and subIndex. Its length is size bytes */ +typedef struct mappedVar +{ + UNS32 index; + UNS8 subIndex; + UNS8 size; // in byte +} s_mappedVar; + +typedef struct heartbeatConsumer +{ + UNS8 nodeProducer; + UNS16 time_ms; +} s_heartbeatConsumer; + +/**************************prototypes*****************************************/ +/* You *must* have these 2 functions in your code*/ +void heartbeatError(UNS8 heartbeatID ); +void SD0timeoutError(UNS8 bus_id, UNS8 line); + +void waitMessage (void ); +void heartBeat (void ); +void transmitSync (void); +e_nodeState stateNode (UNS8 node); +void configure_master_SDO (UNS32 index, UNS8 serverNode); +UNS8 waitingWriteToSlaveDict ( UNS8 slaveNode, UNS8 error); +UNS8 waitingReadToSlaveDict (UNS8 slaveNode, void * data, UNS8 * size, UNS8 error); +UNS8 configure_client_SDO (UNS8 slaveNode, UNS8 clientNode); +void masterMappingPDO (UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar); +void slaveMappingPDO (UNS8 slaveNode, UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar); +void masterHeartbeatConsumer (s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats); +void masterHeartbeatProducer (UNS16 time); +void slaveHeartbeatConsumer (UNS8 slaveNode, s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats); +void slaveHeartbeatProducer (UNS8 slaveNode, UNS16 time); +void masterPDOTransmissionMode (UNS32 indexPDO, UNS8 transType); +void slavePDOTransmissionMode (UNS8 slaveNode, UNS32 indexPDO, UNS8 transType); +void masterSYNCPeriod (UNS32 SYNCPeriod); +int main (void); + +// Interruption timer 3. (The timer 4 is used by CanOpen) +void __attribute__((interrupt)) timer3Hdl (void); +void incDate (void); +void initLeds (void); +void initCanHCS12 (void); +void initTimerClk (void); + + +/*****************************************************************************/ +void heartbeatError(UNS8 heartbeatID) +{ + // MSG_ERR should send the values canopenErrNB and canopenErrVAL on event in a PDO, + // But we do not have mapped the variables in a PDO, so it sends nothing. + // See the note at the end of END CONFIGURING THE NETWORK. + MSG_WAR(0x2F00, "HeartBeat, no response from node : ", heartbeatID); +} + +/*****************************************************************************/ +void SD0timeoutError (UNS8 bus_id, UNS8 line) +{ + // Informations on what occurs are in transfers[bus_id][line].... + // See scanSDOtimeout() in sdo.c +} + +//------------------------------------------------------------------------------ +/************************** FUNCTIONS TO CONFIGURE THE NETWORK******************/ + +//------------------------------------------------------------------------------ +/* Node mode result after NodeGuard query */ +e_nodeState stateNode(UNS8 node) +{ + e_nodeState state = getNodeState(0, node); + switch (state) { + case Unknown_state: + MSG_WAR(0x3F05, "Not connected (Does not have sent its status) node :", node); + break; + case Operational: + MSG_WAR(0x3F06, "Ok, in operational mode, node : ", node); + break; + case Pre_operational: + MSG_WAR(0x3F07, "OK in pre-operational mode, node : ", node); + break; + default: + MSG_WAR(0x3F08, "OK connected but in curious mode, node : ", node); + } + return state; +} + +//------------------------------------------------------------------------------ +/* The master is writing in its dictionnary to configure the SDO parameters +to communicate with server_node +*/ +void configure_master_SDO(UNS32 index, UNS8 serverNode) +{ + UNS32 data32; + UNS8 data8; + UNS8 sizeData = 4 ; // in bytes + + /* At subindex 1, the cobId of the Can message from the client. + It is always defined inside the server dictionnary as 0x600 + server_node. + So, we have no choice here ! */ + data32 = 0x600 + serverNode; + setODentry(index, 1, &data32, sizeData, 0); + + { + // Test + UNS32 *pbData; + UNS8 length; + UNS32 returnValue; + UNS8 dataType; + // Relecture + MSG_WAR(0x1000, "Reading index : ", index); + MSG_WAR(0x1000, " subindex : ", 1); + returnValue = getODentry(index, 1, (void * *)&pbData, (UNS8 *)&length, &dataType, 0); + MSG_WAR(0x1000, " val : ", *pbData); + } + + + /* At subindex 2, the cobId of the Can message from the server to the client. + It is always defined inside the server dictionnary as 0x580 + client_node. + So, we have no choice here ! */ + data32 = 0x580 + serverNode; + setODentry(index, 2, &data32, sizeData, 0); + + /* At subindex 3, the node of the server */ + data8 = serverNode; + sizeData = 1; + setODentry(index, 3, &data8, sizeData, 0); + + { + UNS8 *pbData; + UNS8 length; + UNS32 returnValue; + UNS8 dataType; + // Relecture + MSG_WAR(0x1000, "Reading index : ", index); + MSG_WAR(0x1000, " subindex : ", 3); + returnValue = getODentry(index, 1, (void * *)&pbData, (UNS8 *)&length, &dataType, 0); + MSG_WAR(0x1000, " val : ", *pbData); + } +} + +//------------------------------------------------------------------------------ +/* + */ +UNS8 waitingWriteToSlaveDict(UNS8 slaveNode, UNS8 error) +{ + UNS8 err; + UNS32 abortCode; + MSG_WAR(0x3F21, "Sending SDO to write in dictionnary of node : ", slaveNode); + if (error) { + MSG_ERR(0x1F22, "Unable to send the SDO to node ", slaveNode); + return -1; + } + /* Waiting until the slave has responded */ + while (getWriteResultNetworkDict (0, slaveNode, &abortCode) == SDO_DOWNLOAD_IN_PROGRESS) { + // Check if some SDO response are missing + scanSDOtimeout(); + } + + err = getWriteResultNetworkDict (0, slaveNode, &abortCode); + if (err == SDO_FINISHED) { + MSG_WAR(0x3F22, "SDO download finished to Node : ", slaveNode); + // Release the line. Don't forget !!! + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + return 0; + } + + if (err == SDO_ABORTED_RCV) { + MSG_WAR(0x2F20, "Received SDO abort from node : ", slaveNode); + } + + if (err == SDO_ABORTED_INTERNAL) { + MSG_WAR(0x2F20, "Internal SDO abort for node : ", slaveNode); + } + // Looking for the line transfert number to read the index, subindex and releasing the line. + { + UNS8 line; + err = getSDOlineOnUse(0, slaveNode, SDO_CLIENT, &line); + if (err) { + MSG_WAR(0x2F21, "No line found for node : ", slaveNode); + exit(-1); + } + MSG_WAR (0x2F22, "while writing at his index : ", transfers[0][line].index); + MSG_WAR (0x2F23, " subIndex : ", transfers[0][line].subIndex); + //Releasing the line. + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + exit(-1); + } + return 0; +} + +//------------------------------------------------------------------------------ +/* + */ +UNS8 waitingReadToSlaveDict(UNS8 slaveNode, void * data, UNS8 * size, UNS8 error) +{ + UNS8 err; + UNS32 abortCode; + MSG_WAR(0x3F2A, "Sending SDO to read in dictionnary of node : ", slaveNode); + if (error) { + MSG_ERR(0x1F2B, "Unable to send the SDO to node ", slaveNode); + return -1; + } + /* Waiting until the slave has responded */ + while (getReadResultNetworkDict (0, slaveNode, data, size, &abortCode) == SDO_UPLOAD_IN_PROGRESS) { + // Check if some SDO response are missing + scanSDOtimeout(); + } + err = getReadResultNetworkDict (0, slaveNode, data, size, &abortCode); + if (err == SDO_FINISHED) { + MSG_WAR(0x3F2C, "SDO upload finished to Node : ", slaveNode); + // Release the line. Don't forget !!! + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + return 0; + } + if (err == SDO_ABORTED_RCV) { + MSG_WAR(0x2F2D, "Received SDO abort from node : ", slaveNode); + } + + if (err == SDO_ABORTED_INTERNAL) { + MSG_WAR(0x2F2E, "Internal SDO abort for node : ", slaveNode); + } + // Looking for the line transfert number to read the index, subindex and releasing the line. + { + UNS8 line; + err = getSDOlineOnUse(0, slaveNode, SDO_CLIENT, &line); + if (err) { + MSG_WAR(0x2F2F, "No line found for node : ", slaveNode); + exit(-1); + } + MSG_WAR (0x2F30, "while writing at his index : ", transfers[0][line].index); + MSG_WAR (0x2F31, " subIndex : ", transfers[0][line].subIndex); + //Releasing the line. + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + exit(-1); + } + + return 0; +} + +//------------------------------------------------------------------------------ +/* The master is writing in the slave dictionnary to configure the SDO parameters +Remember that the slave is the server, and the master is the client. + */ +UNS8 configure_client_SDO(UNS8 slaveNode, UNS8 clientNode) +{ + UNS8 data; + UNS8 NbDataToWrite = 1 ; // in bytes + UNS8 err = 0; + MSG_WAR(0x3F20, "Configuring SDO by writing in dictionnary Node ", slaveNode); + /* It is only to put at subindex 3 the serverNode. It is optionnal. + In the slave dictionary, only one SDO server is defined, at index + 0x1200 */ + data = clientNode; + err = writeNetworkDict(0, slaveNode, 0x1200, 3, NbDataToWrite, 0, &data); + waitingWriteToSlaveDict(slaveNode, err); + + return 0; +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterMappingPDO(UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar) +{ + UNS32 *pbData; + UNS32 data32; + UNS8 i; + UNS8 size = 0; + UNS8 dataType; + + if ((indexPDO >= 0x1400) && (indexPDO <= 0x15FF)) + MSG_WAR(0x3F30, "Configuring MASTER for PDO receive, COBID : ", cobId); + + if ((indexPDO >= 0x1800) && (indexPDO <= 0x19FF)) + MSG_WAR(0x3F31, "Configuring MASTER for PDO transmit, COBID : ", cobId); + + /* At indexPDO, subindex 1, defining the cobId of the PDO */ + setODentry(indexPDO, 1, &cobId, 4, 0); + /* The mapping ... */ + /* ----------------*/ + /* At subindex 0, the number of variables in the PDO */ + setODentry(indexPDO + 0x200, 0, &nbVar, 1, 0); + getODentry(indexPDO + 0x200, 0, (void * *)&pbData, &size, &dataType, 0); + /* At each subindex 1 .. nbVar, The index,subindex and size of the variable to map in + the PDO. The first variable after the COBID is defined at subindex 1, ... + The data to write is the concatenation on 32 bits of (msb ... lsb) : + index(16b),subIndex(8b),sizeVariable(8b) +*/ + for (i = 0 ; i < nbVar ; i++) { + data32 = ((tabMappedVar + i)->index << 16) | + (((tabMappedVar + i)->subIndex & 0xFF) << 8) | + ((tabMappedVar + i)->size & 0xFF); + // Write dictionary + setODentry(indexPDO + 0x200, i + 1, &data32, 4, 0); + +# ifdef MORE_COMMENTS + printf("Mapped variable defined at index 0x%X, subIndex 0x%X, %d bits\n", + (tabMappedVar + i)->index, (tabMappedVar + i)->subIndex, 8 * (tabMappedVar + i)->size); + // Only to verify. + // Read dictionnary + getODentry(indexPDO + 0x200, i + 1, (void * *)&pbData, &size, &dataType, 0); + printf("Writen à index 0x%X, subIndex 0x%X, %d bits : 0x%08X\n", + indexPDO + 0x200, i + 1, 8 * size, *pbData); +# endif + + } +} + +//------------------------------------------------------------------------------ +/* + */ + +void slaveMappingPDO(UNS8 slaveNode, UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar) +{ + UNS32 data32; + UNS8 i; + UNS8 err; + UNS8 nbBytes = 1; + if ((indexPDO >= 0x1400) && (indexPDO <= 0x15FF)) + MSG_WAR(0x3F32, "Configuring slave for PDO receive, COBID : ", cobId); + + if ((indexPDO >= 0x1800) && (indexPDO <= 0x19FF)) + MSG_WAR(0x3F33, "Configuring slave for PDO transmit, COBID : ", cobId); + + /* At indexPDO, subindex 1, defining the cobId of the PDO */ + err = writeNetworkDict(0, slaveNode, indexPDO, 1, 4, 0, &cobId); + waitingWriteToSlaveDict(slaveNode, err); + + /* The mapping ... */ + /* ----------------*/ + /* At subindex 0, the number of variables in the PDO */ + err = writeNetworkDict(0, slaveNode, indexPDO + 0x200, 0, nbBytes, 0, &nbVar); + waitingWriteToSlaveDict(slaveNode, err); + + /* At each subindex 1 .. nbVar, The index,subindex and size of the variable to map in + the PDO. The first variable after the COBID is defined at subindex 1, ... + The data to write is the concatenation on 32 bits of (msb ... lsb) : + index(16b),subIndex(8b),sizeVariable(8b) +*/ + for (i = 0 ; i < nbVar ; i++) { + data32 = ((tabMappedVar + i)->index << 16) | + (((tabMappedVar + i)->subIndex & 0xFF) << 8) | + ((tabMappedVar + i)->size & 0xFF); + + // Write dictionary + err = writeNetworkDict(0, slaveNode, indexPDO + 0x200, i + 1, 4, 0, &data32); + waitingWriteToSlaveDict(slaveNode, err); + +# ifdef MORE_COMMENTS + printf("Mapped variable defined at index 0x%X, subIndex 0x%X, %d bits\n", + (tabMappedVar + i)->index, (tabMappedVar + i)->subIndex, 8 * (tabMappedVar + i)->size); + + printf("At node 0x%X Writen at index 0x%X, subIndex 0x%X, %d bits : 0x%08X\n", + slaveNode, indexPDO + 0x200, i + 1, 32, data32); +# endif + + } +} + +//------------------------------------------------------------------------------ +/* + */ +void masterHeartbeatConsumer(s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats) +{ + UNS32 data; + UNS8 i; + UNS8 nbHB = nbHeartbeats; + + MSG_WAR(0x3F40, "Configuring heartbeats consumers for master", 0); + /* At index 1016, subindex 0 : the nb of consumers (ie nb of nodes of which are expecting heartbeats) */ + setODentry(0x1016, 0, & nbHB, 1, 0); + + /* At Index 1016, subindex 1, ... : 32 bit values : msb ... lsb : + 00 - node_consumer (8b) - time_ms (16b) + Put 0 to ignore the entry. + */ + for (i = 0 ; i < nbHeartbeats ; i++) { + data = (((tabHeartbeatConsumer + i)->nodeProducer & 0xFF)<< 16) | ((tabHeartbeatConsumer + i)->time_ms & 0xFFFF); + setODentry(0x1016, i + 1, & data, 4, 0); + } +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterHeartbeatProducer(UNS16 time) +{ + UNS16 hbTime = time; + MSG_WAR(0x3F45, "Configuring heartbeat producer for master", 0); + /* At index 1017, subindex 0, defining the time to send the heartbeat. Put 0 to never send heartbeat */ + setODentry(0x1017, 0, &hbTime, 2, 0); +} + +//------------------------------------------------------------------------------ +/* + */ +void slaveHeartbeatConsumer(UNS8 slaveNode, s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats) +{ + UNS32 data; + UNS8 err; + UNS8 i; + + MSG_WAR(0x3F46, "Configuring heartbeats consumers for node : ", slaveNode); + + /* At Index 1016, subindex 1, ... : 32 bit values : msb ... lsb : + 00 - node_consumer (8b) - time_ms (16b) + Put 0 to ignore the entry. + */ + for (i = 0 ; i < nbHeartbeats ; i++) { + data = (((tabHeartbeatConsumer + i)->nodeProducer & 0xFF)<< 16) | + ((tabHeartbeatConsumer + i)->time_ms & 0xFFFF); + err = writeNetworkDict(0, slaveNode, 0x1016, i + 1, 4, 0, &data); + waitingWriteToSlaveDict(slaveNode, err); + } +} + +//------------------------------------------------------------------------------ +/* + */ + +void slaveHeartbeatProducer(UNS8 slaveNode, UNS16 time) +{ + UNS8 err; + MSG_WAR(0x3F47, "Configuring heartbeat producer for node : ", slaveNode); + /* At index 1017, subindex 0, defining the time to send the heartbeat. Put 0 to never send heartbeat */ + + err = writeNetworkDict(0, slaveNode, 0x1017, 0, 2, 0, &time); + waitingWriteToSlaveDict(slaveNode, err); +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterPDOTransmissionMode(UNS32 indexPDO, UNS8 transType) +{ + MSG_WAR(0x3F48, "Configuring transmission from master, indexPDO : ", indexPDO); + + /* At subindex 2, the transmission type */ + setODentry(indexPDO, 2, &transType, 1, 0); +} + + +//------------------------------------------------------------------------------ +/* + */ + +void slavePDOTransmissionMode(UNS8 slaveNode, UNS32 indexPDO, UNS8 transType) +{ + UNS8 err; + MSG_WAR(0x3F41, "Configuring transmission mode for node : ", slaveNode); + MSG_WAR(0x3F42, " indexPDO : ", indexPDO); + + err = writeNetworkDict(0, slaveNode, indexPDO, 2, 1, 0, &transType); + waitingWriteToSlaveDict(slaveNode, err); +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterSYNCPeriod(UNS32 SYNCPeriod) +{ + UNS32 cobId = 0x40000080; + MSG_WAR(0x3F49, "Configuring master to send SYNC every ... micro-seconds :", SYNCPeriod); + /* At index 0x1006, subindex 0 : the period in ms */ + setODentry(0x1006, 0, &SYNCPeriod , 4, 0); + /* At index 0x1005, subindex 0 : Device generate SYNC signal with CobId 0x80 */ + setODentry(0x1005, 0, &cobId, 4, 0); +} + +//------------------------------------------------------------------------------ + + +//Initialisation of the port B for the leds. +void initLeds(void) +{ + // Port B is output + IO_PORTS_8(DDRB)= 0XFF; + // RAZ + IO_PORTS_8(PORTB) = 0xFF; +} + +//------------------------------------------------------------------------------ + + + +void initCanHCS12 (void) +{ + //Init the HCS12 microcontroler for CanOpen + initHCS12(); + // Init the HCS12 CAN driver + const canBusInit bi0 = { + 0, /* no low power */ + 0, /* no time stamp */ + 1, /* enable MSCAN */ + 0, /* clock source : oscillator (In fact, it is not used) */ + 0, /* no loop back */ + 0, /* no listen only */ + 0, /* no low pass filter for wk up */ + CAN_Baudrates[CAN_BAUDRATE_250K], + { + 0x00, /* Filter on 16 bits. See Motorola Block Guide V02.14 fig 4-3 */ + 0x00, 0xFF, /* filter 0 hight accept all msg */ + 0x00, 0xFF, /* filter 0 low accept all msg */ + 0x00, 0xFF, /* filter 1 hight filter all of msg */ + 0x00, 0xFF, /* filter 1 low filter all of msg */ + 0x00, 0xFF, /* filter 2 hight filter most of msg */ + 0x00, 0xFF, /* filter 2 low filter most of msg */ + 0x00, 0xFF, /* filter 3 hight filter most of msg */ + 0x00, 0xFF, /* filter 3 low filter most of msg */ + } + }; + + canInit(CANOPEN_LINE_NUMBER_USED, bi0); //initialize filters... + unlock(); // Allow interruptions +} + +/*********************************************************************/ +// For Second timer +void incDate(void) +{ + if (sec == 59) + sec = 0; + else + sec++; + + // Toggle the led 4 every seconds + IO_PORTS_8(PORTB) ^= 0x10; + +} + +// Init the time for the second counter +void initTimerClk(void) +{ + + lock(); // Inhibe les interruptions + + // Configuration du Channel 3 + IO_PORTS_8(TIOS) |= 0x08; // Canal 3 en sortie + IO_PORTS_8(TCTL2) &= ~(0xC0); // Canal 3 déconnecté du pin de sortie + IO_PORTS_8(TIE) |= 0x08; // Autorise interruption Canal 3 + IO_PORTS_8(TSCR1) |= 0x80; // Mise en route du timer + unlock(); // Autorise les interruptions +} + + +/*********************************************************************/ +void __attribute__((interrupt)) timer3Hdl(void) +{ + //IO_PORTS_8(PORTB) ^= 0x10; + //IO_PORTS_8(PORTB) &= ~0x20; + IO_PORTS_8(TFLG1) = 0x08; // RAZ du flag interruption timer 3 + // Calcul evt suivant. Clock 8 MHz -> 8000 evt de 1 ms!! Doit tenir sur 16 bits + // Attention, ça change si on utilise la pll + // Lorsque le timer atteindra la valeur de TC3 (16 bits), l'interruption timer3Hdl sera déclenchée + // Si on utilise la PLL à 24 MHZ, alors la vitesse du bus est multipliée par 3. + +/* Assume that our board uses a 16 MHz quartz */ +/* Without pre-division, 8000 counts takes 1 ms. */ +/* We are using a pre-divisor of 32. (register TSCR2) See in CanOpenDriverHC12/timerhw.c */ +/* So 1000 counts takes 4 ms. */ +/* We must have a soft counter of 250 to count a second. */ + +/* + We check in an interrupt handler if a message is arrived. +*/ + receiveMsgHandler(0); + + IO_PORTS_16(TC3H) += (1000); // IT every 4000 count. + softCount++; + if (softCount == 250) { + softCount = 0; + incDate(); + } +} + + + + +/*****************************************************************************/ + + + +/********************************* MAIN ***************************************/ + + +int main() +{ + + UNS8 second_last; + UNS8 minutes_last; + UNS8 sendingResetError = 0; + UNS8 ok, i; + + /* initialisation du bus Can */ + initCanHCS12(); + + /* arrays initialisation, etc */ + initCANopenMain(); + + /* arrays initialisation, etc */ + initCANopenMaster(); + +/* Defining the node Id */ + setNodeId(0x01); + MSG_WAR(0x3F50, "My node ID is : ", getNodeId()); + + /* Put the master in operational mode */ + setState(Operational); + + /* Init the table of connected nodes */ + for (i = 0 ; i < 128 ; i++) + connectedNode[i] = 0; + + /* Initialisation */ + initLeds(); + initTimer( ); + initTimerClk(); + + + + /******************** CONFIGURING THE NETWORK **************************/ + + /* Which nodes are connected ? */ + /* Sending a request Node guard to node 5 and 6 */ + MSG_WAR(0x3F04, "Sending a node guard to node : ", 5); + masterReadNodeState(0, 0x05); + + /* Sending a message to the node 6, only as example */ + MSG_WAR(0x3F04, "Sending a node guard to node : ", 6); + masterReadNodeState(0, 0x06); + /* Waiting for a second the response */ + sec = 0; + while (sec < 2) {}; + + /* Whose node have answered ? */ + connectedNode[5] = stateNode(5); + if (connectedNode[5] != Unknown_state) { + MSG_WAR(0x3F06, "Node 5 connected. Its state is : ", connectedNode[5]); + } + else { + MSG_WAR(0x3F07, "Node 5 NOT connected ", connectedNode[5]); + } + + connectedNode[6] = stateNode(6); + if (connectedNode[6] != Unknown_state) { + MSG_WAR(0x3F08, "Node 6 connected. Its state is : ", connectedNode[6]); + } + else { + MSG_WAR(0x3F09, "Node 6 NOT connected ", connectedNode[6]); + } + + /* Configure the SDO master to communicate with node 5 and node 6 */ + configure_master_SDO(0x1280, 0x05); + /* Configure the SDO of node 5 */ + /* getNodeId() returns my node Id */ + configure_client_SDO(0x05, getNodeId()); + + /* Mapping of the PDO + Chose some COBID in (hexa) 181-1FF, 201-27F, 281-2FF, 301-37F, + 381-3FF, 401-47F, 481-4FF, 501-57F, + without other restriction. + (Of course, you must not define 2 PDO transmit with the same cobId !!) + */ + + /* + *** PDO node 1 <-- node 5 *** + *** cobId 0x181 ************* + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + day [0x6002 - 0x04 - 8] + hour [0x6002 - 0x03 - 8] + second [0x6002 - 0x01 - 8] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bits]: + day [0x2000 - 0x04 - 8] + hour [0x2000 - 0x03 - 8] + second [0x2000 - 0x01 - 8] +*/ + + /* Configuring the first PDO receive, defined at index 0x1400 and 0x1600 */ + { + s_mappedVar tabMappedVar[8] = { {0x6002,4,8}, {0x6002,3,8}, {0x6002,1,8}, }; + masterMappingPDO(0x1400, 0x181, tabMappedVar, 3); + } + + /* Configuring the first PDO transmit, defined at index 0x1800 and 0x1A00 */ + { + s_mappedVar tabMappedVar[8] = { {0x2000,4,8}, {0x2000,3,8}, {0x2000,1,8}, }; + slaveMappingPDO(0x05, 0x1800, 0x181, tabMappedVar, 3); + } + /* + *** PDO node 1 <-- node 5 *** + *** cobId 0x182 ************* + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + minute [0x6002 - 0x02 - 8] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bits]: + minute [0x2000 - 0x02 - 8] + */ + + /* Configuring PDO receive, defined at index 0x1400 and 0x1600 */ + { + s_mappedVar tabMappedVar[8] = { {0x6002,2,8} }; + masterMappingPDO(0x1401, 0x182, tabMappedVar, 1); + } + + /* Configuring PDO transmit, defined at index 0x1800 and 0x1A00 */ + { + s_mappedVar tabMappedVar[8] = { {0x2000,2,8} }; + slaveMappingPDO(0x05, 0x1801, 0x182, tabMappedVar, 1); + } + + + /* + *** PDO node 1 <-- node 5 *** + *** cobId 0x183 ************* + Error management : By this way, The node can send by PDO an error + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + canopenErrNb_node5 [0x6000 - 0x00 - 32] + canopenErrVal_node5 [0x6001 - 0x00 - 32] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bytes]: + canopenErrNb [0x6000 - 0x00 - 32] + canopenErrVal [0x6001 - 0x00 - 32] + */ + + /* Configuring PDO receive, defined at index 0x1402 and 0x1602 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + masterMappingPDO(0x1402, 0x183, tabMappedVar, 2); + } + + /* Configuring PDO transmit, defined at index 0x1802 and 0x1A02 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + slaveMappingPDO(0x05, 0x1802, 0x183, tabMappedVar, 2); + } + + /* + *** PDO node 1 --> node 5 *** + *** cobId 0x184 ************* + Error management : To reset the error + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + canopenErrNb_node5 [0x6000 - 0x00 - 32] + canopenErrVal_node5 [0x6001 - 0x00 - 32] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bytes]: + canopenErrNb [0x6000 - 0x00 - 32] + canopenErrVal [0x6001 - 0x00 - 32] + */ + + /* Configuring PDO transmit, defined at index 0x1803 and 0x1103 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + masterMappingPDO(0x1801, 0x184, tabMappedVar, 2); + } + + /* Configuring PDO transmit, defined at index 0x1403 and 0x1603 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + slaveMappingPDO(0x05, 0x1400, 0x184, tabMappedVar, 2); + } + + /* Configuring the node 5 heartbeat */ + /* Check every 3000 ms if it have received a heartbeat from node 1 */ + { + UNS8 nbHeartbeatsToReceive = 1; + s_heartbeatConsumer tabHeartbeatConsumer[10] = {{1, 0xBB8}}; + slaveHeartbeatConsumer(0x05, tabHeartbeatConsumer, nbHeartbeatsToReceive); + } + /* Sending every 1000 ms an heartbeat */ + slaveHeartbeatProducer(0x05, 0x3E8); + + /* Configuring the master heartbeat */ + /* Check every 3000 ms if it have received a heartbeat from node 5 */ + { + UNS8 nbHeartbeatsToReceive = 1; + s_heartbeatConsumer tabHeartbeatConsumer[10] = {{5, 0xBB8}}; + masterHeartbeatConsumer(tabHeartbeatConsumer, nbHeartbeatsToReceive); + } + + /* Sending every 1000 ms an heartbeat */ + masterHeartbeatProducer(0x3E8); + + + + /* Configuring the transmission mode of the PDO */ + slavePDOTransmissionMode(0x05, 0x1800, TRANS_EVERY_N_SYNC (1)); + slavePDOTransmissionMode(0x05, 0x1801, TRANS_EVENT); + slavePDOTransmissionMode(0x05, 0x1802, TRANS_EVENT); + masterPDOTransmissionMode(0x1801, TRANS_EVENT); + + + /* Configuring the master to send a SYNC message every 1 s */ + /* Note than any other node can send the SYNC instead of the master */ + masterSYNCPeriod(1000000); + + { + // Reading the period of heartbeat which has been written in node 5 dictionary + UNS8 node = 5; + UNS16 index = 0x1017; + UNS8 subindex = 0; + //UNS8 notused = 0; + UNS16 hb = 0; + UNS8 size_data = 0; + UNS8 error; + MSG_WAR(0x3F50, "Reading dictionary noeud 5, 1017/0", 0); + error = readNetworkDict(0, node, index, subindex, 0); + //error = readNetworkDict(0, node, index, subindex, ¬used); + if (error) { + MSG_ERR(0x1F50, "!!! ERROR reading dictionary noeud 5, 1017/0", 0); + exit (-1); + } + /* Waiting until the server has responded */ + error = waitingReadToSlaveDict(node, (UNS16 *)&hb, &size_data, error); + MSG_WAR(0x1F51, "Read dictionary of node 5, index/subindex 1017/0 value = ", hb); + MSG_WAR(0x1F51, " size of data (bytes) = ", size_data); + } + + /* Put the node 5 in operational mode + The mode is changed according to the slave state machine mode : + initialisation ---> pre-operational (Automatic transition) + pre-operational <--> operational + pre-operational <--> stopped + pre-operational, operational, stopped -> initialisation + NMT_Start_Node // Put the node in operational mode + NMT_Stop_Node // Put the node in stopped mode + NMT_Enter_PreOperational // Put the node in pre_operational mode + NMT_Reset_Node // Put the node in initialization mode + NMT_Reset_Comunication // Put the node in initialization mode + */ + masterSendNMTstateChange(0, 0x05, NMT_Start_Node); + + // Note + //----- + // We do not have mapped the variable canopenErrNB and canopenErrVAL. + // We should have done that ! + // the macro MSG_ERR try to send the PDO(s) which contains these two variables. + // While the PDO will not be found, if you are printing the warnings in file pdo.c, + // it will print "0X393B Unable to send variable on event : not mapped in a PDO to send on event" for + // example when you enter the function heartbeatError. + + /******************** END CONFIGURING THE NETWORK **********************/ + + + + /* Init the errors values that may send the node 5 */ + canopenErrNB_node5 = 0; + canopenErrVAL_node5 = 0; + + /***********/ + /* Running */ + /***********/ + + /* SDO test with node 5 */ + /* This code may takes too much room in memory if you are also debugging the file sdo.c */ + { + // Reading string + UNS8 dataW[20]; + UNS8 dataR[20]; + UNS8 size; + UNS8 err; + MSG_WAR(0x3F05, "Test SDO", 0); + + MSG_WAR(0x3F10, "Writing to node 5 at 0x6002-0 ...", 0); + strcpy(dataW, "Au Revoir"); + MSG_WAR(0x3F10, dataW, 0); + size = 20; + err = writeNetworkDict(0, 5, 0x6002, 0, 10, visible_string, dataW); + err = waitingWriteToSlaveDict(5, err); + + err = readNetworkDict(0, 5, 0x6002, 0, visible_string); + err = waitingReadToSlaveDict(5, dataR, &size, err); + MSG_WAR(0x3F08, "Read from node 5 at 0x6002-0" , 0); + MSG_WAR(0x3F08, dataR, 0); + + MSG_WAR(0x3F08, "node 5. Hardware version. (default = compil. date) ...", 0); + err = readNetworkDict(0, 5, 0x1009, 0, visible_string); + + err = waitingReadToSlaveDict(5, dataR, &size, err); + MSG_WAR(0x3F08, dataR, 0); + + MSG_WAR(0x3F08, "node 5. Software version. (default = compil. time) ...", 0); + err = readNetworkDict(0, 5, 0x100A, 0, visible_string); + err = waitingReadToSlaveDict(5, dataR, &size, err); + MSG_WAR(0x3F08, dataR, 0); + } + + // Node identity ? + { + UNS8 *data; + UNS8 size; + UNS8 dataType; + // Manufacturer Device name (default = empty string) + getODentry(0x1008, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Hardware version. (default = compilation. date) + getODentry(0x1009, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Software version. (default = compilation. time) + getODentry(0x100A, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + } + + while(1) { + // To transmit the SYNC if it is time to do. + computeSYNC(); + + // Testing if heartsbeat have been received, and send a heartbeat if it is time. + heartbeatMGR(); + + // Messages received ? + // The function is called in void __attribute__((interrupt)) timer3Hdl (void) + //receiveMsgHandler(0); + + if (minutes != minutes_last) { + MSG_WAR(0x3F80, "Minutes changed :", minutes); + minutes_last = minutes; + } + + if (second != second_last) { + MSG_WAR(0x3F81, "Seconds : ", second); + second_last = second; + + if (canopenErrNB_node5) { + MSG_WAR(0x3F82, "Received an error from node 5, NB : ", canopenErrNB_node5); + MSG_WAR(0x3F83, " VALUE : ", canopenErrVAL_node5); + // Reseting the error + canopenErrNB_node5 = 0; + canopenErrVAL_node5 = 0; + sendingResetError = 1; + } + + if ((second == 00) && sendingResetError) { + MSG_WAR(0x3F84, + "Sending to node 5 a PDO envent to reset the error NB and VAL : ",0); + sendPDOevent(0, &canopenErrNB_node5); + sendingResetError = 0; + } + + + } // end if (second != second_last) + + + } // end while + + + return (0); +} + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/objdict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/objdict.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,642 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "pdo.h" +#include "sdo.h" +#include "sync.h" +#include "lifegrd.h" +#include "nmtSlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ + + + +/*// Copy and uncomment this code to your main file +extern UNS32 canopenErrNB_node5; // Mapped at index 0x6000, subindex 0x00 +extern UNS32 canopenErrVAL_node5; // Mapped at index 0x6001, subindex 0x00 +extern UNS8 second; // Mapped at index 0x6002, subindex 0x01 +extern UNS8 minutes; // Mapped at index 0x6002, subindex 0x02 +extern UNS8 hour; // Mapped at index 0x6002, subindex 0x03 +extern UNS8 day; // Mapped at index 0x6002, subindex 0x04 +extern UNS32 canopenErrNB; // Mapped at index 0x6003, subindex 0x01 +extern UNS32 canopenErrVAL; // Mapped at index 0x6003, subindex 0x02 + +// END copy to main file +*/ + +UNS32 canopenErrNB_node5; // Mapped at index 0x6000, subindex 0x00 +UNS32 canopenErrVAL_node5; // Mapped at index 0x6001, subindex 0x00 +UNS8 second; // Mapped at index 0x6002, subindex 0x01 +UNS8 minutes; // Mapped at index 0x6002, subindex 0x02 +UNS8 hour; // Mapped at index 0x6002, subindex 0x03 +UNS8 day; // Mapped at index 0x6002, subindex 0x04 +UNS32 canopenErrNB; // Mapped at index 0x6003, subindex 0x01 +UNS32 canopenErrVAL; // Mapped at index 0x6003, subindex 0x02 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + + + +UNS32 valueRangeTest (UNS8 typeValue, UNS32 unsValue, REAL32 realValue) +{ + return 0; +} + + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* Computed by strNode */ +/* node_id default value. + This default value is deprecated. + You should always overwrite this by using the function setNodeId(UNS8 nodeId) in your C code. +*/ +#define NODE_ID 0x01 +UNS8 bDeviceNodeId = NODE_ID; + + +//*****************************************************************************/ +/* Computed by strStartDico */ + +/* Array of message processing information */ +/* Should not be modified */ +volatile const proceed_info proceed_infos[] = { + {NMT, "NMT", NULL}, + {SYNC, "SYNC", proceedSYNC}, + {TIME_STAMP, "TStmp", NULL}, + {PDO1tx, "PDO1t", proceedPDO}, + {PDO1rx, "PDO1r", proceedPDO}, + {PDO2tx, "PDO2t", proceedPDO}, + {PDO2rx, "PDO2r", proceedPDO}, + {PDO3tx, "PDO3t", proceedPDO}, + {PDO3rx, "PDO3r", proceedPDO}, + {PDO4tx, "PDO4t", proceedPDO}, + {PDO4rx, "PDO4r", proceedPDO}, + {SDOtx, "SDOt", proceedSDO}, + {SDOrx, "SDOr", proceedSDO}, + {0xD, "Unkw", NULL}, + {NODE_GUARD, "NGrd", proceedNMTerror}, + {0xF, "Unkw", NULL} +}; + + // Macros definition + +/* Beware : +index *must* be writen 4 numbers in hexa +sub_index *must* be writen 2 numbers in hexa +size_variable_in_UNS8 *must* be writen 2 numbers in hexa +*/ +#define PDO_MAP(index, sub_index, size_variable_in_bits)\ +0x ## index ## sub_index ## size_variable_in_bits + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// Make your change, depending of your application + + +/* index 0x1000 : Device type. + You have to change the value below, so + it fits your canopen-slave-module */ + + /* Not used, so, should not be modified */ + + UNS32 obj1000 = 0; + subindex Index1000[] = + { + { RO, uint32, sizeof(UNS32), (void*)&obj1000 } + }; + +/* index 0x1001 : Error register. + Change the entries to fit your application + Not used, so, should not be modified */ + /*const*/ UNS8 obj1001 = 0x0; + /*const*/ subindex Index1001[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1001 } + }; + +/* index 0x1005 : COB_ID SYNC */ + /* Should not be modified */ + UNS32 obj1005 = 0x00000080; // bit 30 = 1 : device can generate a SYNC message + // Beware, it is over written when the node + // enters in reset mode + // See initResetMode() in init.c + /*const*/ subindex Index1005[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1005 } + }; + +/* index 0x1006 : SYNC period */ + // For producing the SYNC signal every n micro-seconds. + // Put O to not producing SYNC + /*const*/ UNS32 obj1006 = 0x0; + // Default 0 to not produce SYNC // + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + /*const*/ subindex Index1006[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1006 } + }; + +/* index 0x1007 : Synchronous Window Length + Seems to be needed by DS401 to generate the SYNC signal ! */ + /*const*/ UNS32 obj1007 = 0x0; /* Default 0 */ + /*const*/ subindex Index1007[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1007 } + }; + +/* index 0x1008 : Manufacturer device name */ + UNS8 obj1008[] = "Appli_Master_HC12"; /* Default 0 */ + subindex Index1008[] = + { + { RO, uint32, sizeof(obj1008), (void*)&obj1008 } + }; + +/* index 0x1009 : Manufacturer hardware version */ + UNS8 obj1009[] = __DATE__; /* Default 0 */ + subindex Index1009[] = + { + { RO, uint32, sizeof(obj1009), (void*)&obj1009 } + }; + +/* index 0x100A : Manufacturer software version */ + UNS8 obj100A[] = __TIME__; /* Default 0 */ + subindex Index100A[] = + { + { RO, uint32, sizeof(obj100A), (void*)&obj100A} + }; + +/* index 0x1016 : HeartBeat consumers + The nodes which can send a heartbeat */ + static UNS32 obj1016[] = {// Consumer time for each node + 0x00000000}; // Format 0x00NNTTTT (N=Node T=time in ms) + + static UNS8 obj1016_cnt = 1; // 1 nodes could send me + // their heartbeat. + subindex Index1016[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1016_cnt }, + { RW, uint32, sizeof(UNS32), (void*)&obj1016[0] } + }; + +/* index 0x1017 : Heartbeat producer + Every HBProducerTime, the node sends its heartbeat */ + static UNS16 obj1017 = 0; //HBProducerTime in ms. If 0 : not activated + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + subindex Index1017[] = + { + { RW, uint16, sizeof(UNS16), &obj1017 } + }; + +/* index 0x1018 : Identity object */ + /** index 1018: identify object. Adjust the entries for your node/company + */ + /* Values can be modified */ + + s_identity obj1018 = + { + 4, // number of supported entries + 0, // Vendor-ID (given by the can-cia) + 0, // Product Code + 0, // Revision number + 0 // serial number + }; + + subindex Index1018[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1018.count }, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.vendor_id}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.product_code}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.revision_number}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.serial_number} + }; + +/* index 0x1200 : The SDO Server parameters */ + /* BEWARE You cannot define more than one SDO server */ + /* The values should not be modified here, + but can be changed at runtime */ + // Beware that the default values that you could put here + // will be over written at the initialisation of the node. + // See setNodeId() in init.c + static s_sdo_parameter obj1200 = + { 3, // Number of entries. Always 3 for the SDO + 0x600 + NODE_ID, // The cob_id transmited in CAN msg to the server + 0x580 + NODE_ID, // The cob_id received in CAN msg from the server + NODE_ID // The node id of the client. Should not be modified + }; + static subindex Index1200[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1200.count }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_client }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_server }, + { RW, uint8, sizeof( UNS8), (void*)&obj1200.node_id } + }; + +/* index 0x1280 : SDO client parameter */ + static s_sdo_parameter obj1280 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1280[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1280.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1280.node_id } + }; + +/* index 0x1281 : SDO client parameter */ + static s_sdo_parameter obj1281 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1281[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1281.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1281.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1281.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1281.node_id } + }; + +/* index 0x1400 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1400 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1400[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1400.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1400.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1400.type }, + }; + +/* index 0x1401 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1401 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1401[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1401.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1401.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1401.type }, + }; + +/* index 0x1402 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1402 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1402[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1402.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1402.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1402.type }, + }; + +/* index 0x1600 : PDO receive mapping parameter of PDO communication index 0x1400 */ + static UNS8 obj1600_cnt = 0; // Number of mapped variables + static UNS32 obj1600_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1600[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1600_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[7]} + }; + +/* index 0x1601 : PDO receive mapping parameter of PDO communication index 0x1401 */ + static UNS8 obj1601_cnt = 0; // Number of mapped variables + static UNS32 obj1601_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1601[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1601_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[7]} + }; + +/* index 0x1602 : PDO receive mapping parameter of PDO communication index 0x1402 */ + static UNS8 obj1602_cnt = 0; // Number of mapped variables + static UNS32 obj1602_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1602[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1602_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[7]} + }; + +/* index 0x1800 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1800 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1800[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1800.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1800.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1800.type }, + }; + +/* index 0x1801 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1801 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1801[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1801.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1801.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1801.type }, + }; + +/* index 0x1802 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1802 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1802[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1802.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1802.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1802.type }, + }; + +/* index 0x1A00 : PDO transmit mapping parameter of PDO communication index 0x1800 */ + static UNS8 obj1A00_cnt = 0; // Number of mapped variables + static UNS32 obj1A00_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A00[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A00_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[7]} + }; + +/* index 0x1A01 : PDO transmit mapping parameter of PDO communication index 0x1801 */ + static UNS8 obj1A01_cnt = 0; // Number of mapped variables + static UNS32 obj1A01_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A01[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A01_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[7]} + }; + +/* index 0x1A02 : PDO transmit mapping parameter of PDO communication index 0x1802 */ + static UNS8 obj1A02_cnt = 0; // Number of mapped variables + static UNS32 obj1A02_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A02[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A02_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[7]} + }; + + +/* index 0x6000 : Mapped variable */ + subindex Index6000[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB_node5 } + }; + +/* index 0x6001 : Mapped variable */ + subindex Index6001[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL_node5 } + }; + +/* index 0x6002 : Mapped variable */ + static UNS8 highestSubIndex_6002 = 4; // number of subindex - 1 + subindex Index6002[] = + { + { RO, uint8, sizeof (UNS8), (void*)&highestSubIndex_6002 }, + { RW, uint8, sizeof (UNS8), (void*)&second }, + { RW, uint8, sizeof (UNS8), (void*)&minutes }, + { RW, uint8, sizeof (UNS8), (void*)&hour }, + { RW, uint8, sizeof (UNS8), (void*)&day } + }; + +/* index 0x6003 : Mapped variable */ + static UNS8 highestSubIndex_6003 = 2; // number of subindex - 1 + subindex Index6003[] = + { + { RO, uint8, sizeof (UNS8), (void*)&highestSubIndex_6003 }, + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB }, + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL } + }; + +const indextable objdict[] = +{ + DeclareIndexTableEntry(Index1000, 0x1000), + DeclareIndexTableEntry(Index1001, 0x1001), + DeclareIndexTableEntry(Index1005, 0x1005), + DeclareIndexTableEntry(Index1006, 0x1006), + DeclareIndexTableEntry(Index1007, 0x1007), + DeclareIndexTableEntry(Index1008, 0x1008), + DeclareIndexTableEntry(Index1009, 0x1009), + DeclareIndexTableEntry(Index100A, 0x100A), + DeclareIndexTableEntry(Index1016, 0x1016), + DeclareIndexTableEntry(Index1017, 0x1017), + DeclareIndexTableEntry(Index1018, 0x1018), + DeclareIndexTableEntry(Index1200, 0x1200), + DeclareIndexTableEntry(Index1280, 0x1280), + DeclareIndexTableEntry(Index1281, 0x1281), + DeclareIndexTableEntry(Index1400, 0x1400), + DeclareIndexTableEntry(Index1401, 0x1401), + DeclareIndexTableEntry(Index1402, 0x1402), + DeclareIndexTableEntry(Index1600, 0x1600), + DeclareIndexTableEntry(Index1601, 0x1601), + DeclareIndexTableEntry(Index1602, 0x1602), + DeclareIndexTableEntry(Index1800, 0x1800), + DeclareIndexTableEntry(Index1801, 0x1801), + DeclareIndexTableEntry(Index1802, 0x1802), + DeclareIndexTableEntry(Index1A00, 0x1A00), + DeclareIndexTableEntry(Index1A01, 0x1A01), + DeclareIndexTableEntry(Index1A02, 0x1A02), + DeclareIndexTableEntry(Index6000, 0x6000), + DeclareIndexTableEntry(Index6001, 0x6001), + DeclareIndexTableEntry(Index6002, 0x6002), + DeclareIndexTableEntry(Index6003, 0x6003), +}; + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 count_sync[1] = {0, }; + +UNS16 firstIndex (enum e_first_object object, UNS16 *lastIndex) +{ + switch (object) { + case FIRST_SDO_SERVER : + *lastIndex = 11; + return 11; + case FIRST_SDO_CLIENT : + *lastIndex = 13; + return 12; + case FIRST_PDO_RCV : + *lastIndex = 16; + return 14; + case FIRST_PDO_RCV_MAP : + *lastIndex = 19; + return 17; + case FIRST_PDO_TRS : + *lastIndex = 22; + return 20; + case FIRST_PDO_TRS_MAP : + *lastIndex = 25; + return 23; + } + *lastIndex = 0; + return 0; +} + +UNS16 getObjdictSize (void) +{ + return sizeof(objdict)/sizeof(objdict[0]); +} diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/objdict.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/objdict.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,154 @@ + + + + +CANOpen object dictionary Configuration + + + +

Object dictionary for Node :

+

+Mastermaster +

+

Overview

+

+ How to make the object dictionary of the node ? + First, use Jaxe (command run_objdict) to edit an xml description file +of the dictionary : objdict.xml. +Then, run the php program : makeobjetdict.php. You can launch php through a web browser +if you have installed a server, or, on Linux, you can launch php in command line : +php-cgi makeobjetdict.php. It compute the file objdict.c. Link it to + your project. +
Note : To define the node id, use in your code the function setNodeId(UNS8 nodeId) +

+

+ Then the node can be connected to the network. The master must configure it + by sending SDO. It will write values in its index, subindex. What to configure ? +

    +
  • Receiving heartbeats from which nodes ? Waiting time ?
  • +
  • Emitting heartbeats or not ? time btw 2 heartbeats ?
  • +
  • Defining a cobId for each PDO receive and transmit
  • +
  • How to transmit a PDO ? on synchro ? request ? event ?
  • +
  • What variables to put in each PDO receive and transmit ?
  • +
  • ...
  • +
+

+ To avoid configuring the node at the connection, you can put the values directly +in the dictionary objdict.c. But it is boring and unsafe because it is too easy to make +a mistake ! + + +

Number of heartbeat consumers : + 1 +

+

This means that the node can expect heartbeats sent by 1 nodes.

+

Number of SDO clients : + 10 +

+

Usualy, a slave node does not have the use of SDO clients, but + today, for the library, you must define one. The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Maximum objects in a PDO (receive or transmit) : + 8 +

+

This is defining how many variables can be transmited in a + PDO. (maximum is 8).

+

For each variable, a table is created, so if you have less room + in memory, put a value under 8.

+

Number of PDO receive : + 3 +

+

The node can receive 3 PDO.

+

The communication parameters are defined at index 0x1400 to 0x1400 + 2

+

The mapping parameters are defined at index 0x1600 to 0x1600 + 2

+

Number of PDO transmit : + 3 +

+

The node can transmit 3 PDO.

+

The communication parameters are defined at index 0x1800 to 0x1800 + 2

+

The mapping parameters are defined at index 0x1A00 to 0x1A00 + 2

+

Mapped variables and tables

+

3 tables are defined for the mapping, starting at index 0x2000, 0x6000 and 0x6200. + You must start the mapping at the beginning of one of a table, without holes in index +or subindex. For example, variables in 0x2000 and 0x2001 is ok, but variables in 0x2000 and 0x2002 is not allowed, because you are loosing room in memory. It is the same for the subindex. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameBitsIndexSub-index
canopenErrNB_node5320x60000x0
canopenErrVAL_node5320x60010x0
second80x60020x1
minutes80x60020x02
hour80x60020x3
day80x60020x4
canopenErrNB320x60030x01
canopenErrVAL320x60030x02
+ + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/objdict.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/objdict.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/trace32_flash_debug.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/trace32_flash_debug.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,43 @@ +; Réinitialisation +SYS.d + +; Effacer l'écran +WinCLEAR + +;Raffraichissement de trace32 toutes les 1 secondes +setup.urate 1 + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Vitesse de commuication debugger / carte HCS12 + SYStem.BdmClock 8.0MHZ + +; initialiser le uc en mode debug +SYStem.UP + +; Reset des registres +r.reset + +; Charger le programme +DATA.LOAD.ELF appliMaster.elf /gnu /nocode /GHILLS + +; Positionner le compteur de programme +r.set PC _start + +; Positionner le pointeur de pile +r.set SP _stack + +; Afficher le code source +data.list + +; Afficher les registres +r + +; Afficher le contenu de la mémoire +DATA.dump 140 + + +; Fin du programme de script +ENDDO + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/trace32_flash_debug_sans_init.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/trace32_flash_debug_sans_init.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,36 @@ +; Réinitialisation +SYS.d + +; Effacer l'écran +;WinCLEAR + +;Raffraichissement de trace32 toutes les 1 secondes +setup.urate 1 + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Vitesse de commuication debugger / carte HCS12 + SYStem.BdmClock 8.0MHZ + +; initialiser le uc en mode debug +SYStem.UP + +; Reset des registres +r.reset + +; Charger le programme +DATA.LOAD.ELF appliMaster.elf /gnu /nocode /GHILLS + +; Positionner le compteur de programme +r.set PC _start + +; Positionner le pointeur de pile +r.set SP _stack + + + + +; Fin du programme de script +ENDDO + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/trace32_flash_programmer.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/trace32_flash_programmer.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,94 @@ +; Programmation de la mémoire flash + + +; Réinitialisation +SYS.d + +; Effacer l'écran +WinCLEAR + +; Vitesse de transmission : +SYStem.BdmClock 8.0MHZ + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Flash page 0X3E accessible entre 0X4000 et 0X7FFF +; cf Motorola, registre MISC + +system.option ROMHM ON + + +; Enlever tous les points d'arrêt +b.res + +; Utiliser les points d'arrêts onchip +map.bonchip + +; Connexion à la carte CS12 +system.up + +flash.reset + + +; Effacement de la flash +PRINT "Effacement de la flash" +FLASH.Erase all + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 1 " +FLASH.Program 0x4000--0x7FFF + +;print "Chargement du programme en flash 1" +DATA.LOAD.ELF appliMaster.elf 0x4000--0x7FFF + + +FLASH.Program off +print "Flash programmée 1" + + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 2" +FLASH.Program 0x308000--0x30BFFF + +;print "Chargement du programme en flash 2" +DATA.LOAD.ELF appliMaster.elf 0x8000--0xBFFF + + +FLASH.Program off +print "Flash programmée 2" + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 3" +FLASH.Program 0xC000--0xFFFF + +;print "Chargement du programme en flash 3" +DATA.LOAD.ELF appliMaster.elf 0xC000--0xFFFF + + +FLASH.Program off +print "Flash programmée 3" + + +;Reset du HCS12 +system.up + +;Reset de trace32 +SYS.d + + +ENDDO + + + + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_HCS12/vectors.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_HCS12/vectors.s Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,214 @@ +;;/* M68HC11 Interrupt vectors table +;; Copyright (C) 1999 Free Software Foundation, Inc. +;; Written by Stephane Carrez (stcarrez@worldnet.fr) +;; +;;This file is free software; you can redistribute it and/or modify it +;;under the terms of the GNU General Public License as published by the +;;Free Software Foundation; either version 2, or (at your option) any +;;later version. +;; +;;In addition to the permissions in the GNU General Public License, the +;;Free Software Foundation gives you unlimited permission to link the +;;compiled version of this file with other programs, and to distribute +;;those programs without any restriction coming from the use of this +;;file. (The General Public License restrictions do apply in other +;;respects; for example, they cover modification of the file, and +;;distribution when not linked into another program.) +;; +;;This file 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 +;;General Public License for more details. +;; +;;You should have received a copy of the GNU General Public License +;;along with this program; see the file COPYING. If not, write to +;;the Free Software Foundation, 59 Temple Place - Suite 330, +;;Boston, MA 02111-1307, USA. +;; ---------------------------------------------- +;; Modified by Francis Dupin for MC9S12DP256. April 2003 +;; francis.dupin@inrets.fr +;;*/ + + .sect .text + .globl _start + .globl can4HdlTra + .globl can4HdlRcv + .globl can4HdlErr + .globl can4HdlWup + .globl can3HdlTra + .globl can3HdlRcv + .globl can3HdlErr + .globl can3HdlWup + .globl can2HdlTra + .globl can2HdlRcv + .globl can2HdlErr + .globl can2HdlWup + .globl can1HdlTra + .globl can1HdlRcv + .globl can1HdlErr + .globl can1HdlWup + .globl can0HdlTra + .globl can0HdlRcv + .globl can0HdlErr + .globl can0HdlWup + .globl timerOvflHdl + .globl timer3IC + .globl timer2IC + .globl timer1IC + .globl timer0IC + +;; Default interrupt handler. + .sect .text +def: + rti + +;; +;; Interrupt vectors are in a specific section that is +;; mapped at 0xff00. For the example program, the reset handler +;; points to the generic crt0 entry point. +;; + .sect .vectors + .globl vectors +vectors: + + .word def ; ff00 + .word def ; ff02 + .word def ; ff04 + .word def ; ff06 + .word def ; ff08 + .word def ; ff0a + .word def ; ff0c + .word def ; ff0e + .word def ; ff10 + .word def ; ff12 + .word def ; ff14 + .word def ; ff16 + .word def ; ff18 + .word def ; ff1a + .word def ; ff1c + .word def ; ff1e + .word def ; ff20 + .word def ; ff22 + .word def ; ff24 + .word def ; ff26 + .word def ; ff28 + .word def ; ff2a + .word def ; ff2c + .word def ; ff2e + .word def ; ff30 + .word def ; ff32 + .word def ; ff34 + .word def ; ff36 + .word def ; ff38 + .word def ; ff3a + .word def ; ff3c + .word def ; ff3e + .word def ; ff40 + .word def ; ff42 + .word def ; ff44 + .word def ; ff46 + .word def ; ff48 + .word def ; ff4a + .word def ; ff4c + .word def ; ff4e + .word def ; ff50 + .word def ; ff52 + .word def ; ff54 + .word def ; ff56 + .word def ; ff58 + .word def ; ff5a + .word def ; ff5c + .word def ; ff5e + .word def ; ff60 + .word def ; ff62 + .word def ; ff64 + .word def ; ff66 + .word def ; ff68 + .word def ; ff6a + .word def ; ff6c + .word def ; ff6e + .word def ; ff70 + .word def ; ff72 + .word def ; ff74 + .word def ; ff76 + .word def ; ff78 + .word def ; ff7a + .word def ; ff7c + .word def ; ff7e + .word def ; ff80 + .word def ; ff82 + .word def ; ff84 + .word def ; ff86 + .word def ; ff88 + .word def ; ff8a + .word def ; ff8c + .word def ; ff8e + + ;; MSCAN + .word can4HdlTra ; ff90 (MSCAN4 Transmit) + .word can4HdlRcv ; ff92 (MSCAN4 Receive) + .word can4HdlErr ; ff94 (MSCAN4 Errors) + .word can4HdlWup ; ff96 (MSCAN4 Wake up) + .word can3HdlTra ; ff98 (MSCAN3 Transmit) + .word can3HdlRcv ; ff9a (MSCAN3 Receive) + .word can3HdlErr ; ff9c (MSCAN3 Errors) + .word can3HdlWup ; ff9e (MSCAN3 Wake up) + .word can2HdlTra ; ffa0 (MSCAN2 Transmit) + .word can2HdlRcv ; ffa2 (MSCAN2 Receive) + .word can2HdlErr ; ffa4 (MSCAN2 Errors) + .word can2HdlWup ; ffa6 (MSCAN2 Wake up) + .word can1HdlTra ; ffa8 (MSCAN1 Transmit) + .word can1HdlRcv ; ffaa (MSCAN1 Receive) + .word can1HdlErr ; ffac (MSCAN1 Errors) + .word can1HdlWup ; ffae (MSCAN1 Wake up) + .word can0HdlTra ; ffb0 (MSCAN0 Transmit) + .word can0HdlRcv ; ffb2 (MSCAN0 Receive) + .word can0HdlErr ; ffb4 (MSCAN0 Errors) + .word can0HdlWup ; ffb6 (MSCAN0 Wake up) + + .word def ; ffb8 + .word def ; ffba + .word def ; ffbc + .word def ; ffbe + + .word def ; ffc0 + .word def ; ffc2 + .word def ; ffc4 + .word def ; ffc6 + .word def ; ffc8 + .word def ; ffca (Modulus Down Counter underflow) + .word def ; ffcc + .word def ; ffce + .word def ; ffd0 + .word def ; ffd2 + .word def ; ffd4 + + ;; SCI + .word def ; ffd6 + + ;; SPI + .word def ; ffd8 + .word def ; ffda (PAII) + .word def ; ffdc (PAOVI) + .word def ;ffde (TOI) + + ;; Timer Output Compare + .word def ; ffe0 Timer Chanel 7 + .word def ; ffe2 Timer Chanel 6 + .word def ; ffe4 Timer Chanel 5 + .word timer4Hdl ; ffe6 Timer Chanel 4 used by Canopen + .word timer3Hdl ; ffe8 Timer Chanel 3 For the date + .word def ; ffea Timer Chanel 2 + .word def ; ffec Timer Chanel 1 + .word def ; ffee Timer Chanel 0 + + ;; Misc + .word def ; fff0 (RTII) + .word def ; fff2 (IRQ) + .word def ; fff4 (XIRQ) + .word def ; fff6 (SWI) + .word def ; fff8 (ILL) + .word def ; fffa (COP Failure) + .word def ; fffc (COP Clock monitor) + .word _start ; fffe (reset) + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_Linux/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_Linux/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_Linux/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_Linux/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,61 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET + +LIBPATH = /usr/lib +LIBINC = /usr/include +LIB = -L$(LIBPATH) -lpcan + +INCLUDES = -I../../include -I../../include/peak + +MASTER_OBJS = objdict.o appli.o + +OBJS = $(MASTER_OBJS) ../../src/peak_pdo.o ../../src/peak_sdo.o ../../src/peak_init.o ../../src/peak_sync.o\ + ../../src/peak_objacces.o ../../src/peak_lifegrd.o ../../src/peak_timer.o ../../src/peak_nmtMaster.o\ + ../../drivers/peak/canOpenDriver.o ../../drivers/peak/timerhw.o + + +all: AppliMaster + +AppliMaster: $(OBJS) + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -lpthread -lstdc++ $(OBJS) $(LIB) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -D_REENTRANT -c $< + +clean: + -rm $(MASTER_OBJS) + +mrproper: clean + -rm AppliMaster + + + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_Linux/appli.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_Linux/appli.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1005 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "objacces.h" +#include "canOpenDriver.h" +#include "sdo.h" +#include "pdo.h" +#include "init.h" +#include "timer.h" +#include "lifegrd.h" +#include "sync.h" + +#include "nmtMaster.h" + + + +// For prototype of exit(); +#define exit _exit + + +// Adlink 7841 or Peak PCI/CAN board +// --------------------------------- + +// Baudrate values for Peak board : +// CAN_BAUD_1M CAN_BAUD_500K CAN_BAUD_250K CAN_BAUD_125K CAN_BAUD_100K CAN_BAUD_50K +// CAN_BAUD_20K CAN_BAUD_10K CAN_BAUD_5K + +#ifdef CAN_BAUD_250K +# define BAUDRATE CAN_BAUD_250K +#else +// Appli have been compiled for Adlink-arbraca. Baudrate not used +# define BAUDRATE 0 +#endif + +s_BOARD board = {"0", BAUDRATE}; + + +// Required definition variables +// ----------------------------- +// The variables that you should define for debugging. +// They are used by the macro MSG_ERR and MSG_WAR in applicfg.h +// if the node is a slave, they can be mapped in the object dictionnary. + +UNS8 printMsgErrToConsole = 1; +UNS8 printMsgWarToConsole = 1; + +// The variables mapped in the object dictionnary +// ---------------------------------------------- +extern UNS32 canopenErrNB_node5; // Mapped at index 0x6000, subindex 0x0 +extern UNS32 canopenErrVAL_node5; // Mapped at index 0x6001, subindex 0x0 +extern UNS8 second; // Mapped at index 0x6002, subindex 0x1 +extern UNS8 minutes; // Mapped at index 0x6002, subindex 0x2 +extern UNS8 hour; // Mapped at index 0x6002, subindex 0x3 +extern UNS8 day; // Mapped at index 0x6002, subindex 0x4 +extern UNS32 canopenErrNB; // Mapped at index 0x6003, subindex 0x1 +extern UNS32 canopenErrVAL; // Mapped at index 0x6003, subindex 0x2 + + +/*************************User's variables declaration**************************/ +pthread_t threadM; +pthread_t threadH; +pthread_t threadS; +UNS8 connectedNode[128]; + +/* The variable to map in a PDO is defined at index and subIndex. Its length is size bytes */ +typedef struct mappedVar +{ + UNS32 index; + UNS8 subIndex; + UNS8 size; // in byte +} s_mappedVar; + +typedef struct heartbeatConsumer +{ + UNS8 nodeProducer; + UNS16 time_ms; +} s_heartbeatConsumer; + +/**************************prototypes*****************************************/ +/* You *must* have these 2 functions in your code*/ +void heartbeatError (UNS8 heartbeatID ); +void SD0timeoutError(UNS8 bus_id, UNS8 line); + +void waitMessage (void ); +void heartBeat (void ); +void transmitSync (void); +e_nodeState stateNode (UNS8 node); +void configure_master_SDO (UNS32 index, UNS8 serverNode); +UNS8 waitingWriteToSlaveDict (UNS8 slaveNode, UNS8 error); +UNS8 waitingReadToSlaveDict (UNS8 slaveNode, void * data, UNS8 * size, UNS8 error); +UNS8 configure_client_SDO (UNS8 slaveNode, UNS8 clientNode); +void masterMappingPDO (UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar); +void slaveMappingPDO (UNS8 slaveNode, UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar); +void masterHeartbeatConsumer (s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats); +void masterHeartbeatProducer (UNS16 time); +void slaveHeartbeatConsumer (UNS8 slaveNode, s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats); +void slaveHeartbeatProducer (UNS8 slaveNode, UNS16 time); +void masterPDOTransmissionMode (UNS32 indexPDO, UNS8 transType); +void slavePDOTransmissionMode (UNS8 slaveNode, UNS32 indexPDO, UNS8 transType); +void masterSYNCPeriod (UNS32 SYNCPeriod); +int main (int argc,char **argv); + +/*****************************************************************************/ +void heartbeatError(UNS8 heartbeatID) +{ + // MSG_ERR should send the values canopenErrNB and canopenErrVAL on event in a PDO, + // But we do not have mapped the variables in a PDO, so it sends nothing. + // See the note at the end of END CONFIGURING THE NETWORK. + MSG_WAR(0x2F00, "HeartBeat, no response from node : ", heartbeatID); +} + +/*****************************************************************************/ +void SD0timeoutError (UNS8 bus_id, UNS8 line) +{ + // Informations on what occurs are in transfers[bus_id][line].... + // See scanSDOtimeout() in sdo.c +} + +/*********************************** THREADS **********************************/ +//------------------------------------------------------------------------------ +// Wait for a received message +void waitMessage(void) +{ + while (1) { + receiveMsgHandler(0); // blocked until new message + } +} + +//------------------------------------------------------------------------------ +/* Sending SYNC */ +void transmitSync(void) +{ + while (1) { + computeSYNC(); // Use the value in the dictionnary + usleep(1000); // Sleep 1 ms + + } +} + +/************************** FUNCTIONS TO CONFIGURE THE NETWORK******************/ + + + +//------------------------------------------------------------------------------ +/* Node mode result after NodeGuard query */ +e_nodeState stateNode(UNS8 node) +{ + e_nodeState state = getNodeState(0, node); + switch (state) { + case Unknown_state: + MSG_WAR(0x3F05, "Not connected (Does not have sent its status) node :", node); + break; + case Operational: + MSG_WAR(0x3F06, "Ok, in operational mode, node : ", node); + break; + case Pre_operational: + MSG_WAR(0x3F07, "OK in pre-operational mode, node : ", node); + break; + default: + MSG_WAR(0x3F08, "OK connected but in curious mode, node : ", node); + } + return state; +} + +//------------------------------------------------------------------------------ +/* The master is writing in its dictionnary to configure the SDO parameters +to communicate with server_node +*/ +void configure_master_SDO(UNS32 index, UNS8 serverNode) +{ + UNS32 data32; + UNS8 data8; + UNS8 sizeData = 4 ; // in bytes + + /* At subindex 1, the cobId of the Can message from the client. + It is always defined inside the server dictionnary as 0x600 + server_node. + So, we have no choice here ! */ + data32 = 0x600 + serverNode; + setODentry(index, 1, &data32, sizeData, 0); + + { + // Test + UNS32 *pbData; + UNS8 length; + UNS32 returnValue; + UNS8 dataType; + // Relecture + MSG_WAR(0x1000, "Reading index : ", index); + MSG_WAR(0x1000, " subindex : ", 1); + returnValue = getODentry(index, 1, (void * *)&pbData, (UNS8 *)&length, &dataType, 0); + MSG_WAR(0x1000, " val : ", *pbData); + } + + + /* At subindex 2, the cobId of the Can message from the server to the client. + It is always defined inside the server dictionnary as 0x580 + client_node. + So, we have no choice here ! */ + data32 = 0x580 + serverNode; + setODentry(index, 2, &data32, sizeData, 0); + + /* At subindex 3, the node of the server */ + data8 = serverNode; + sizeData = 1; + setODentry(index, 3, &data8, sizeData, 0); + + { + UNS8 *pbData; + UNS8 length; + UNS32 returnValue; + UNS8 dataType; + // Relecture + MSG_WAR(0x1000, "Reading index : ", index); + MSG_WAR(0x1000, " subindex : ", 3); + returnValue = getODentry(index, 1, (void * *)&pbData, (UNS8 *)&length, &dataType, 0); + MSG_WAR(0x1000, " val : ", *pbData); + } +} + +//------------------------------------------------------------------------------ +/* + */ +UNS8 waitingWriteToSlaveDict(UNS8 slaveNode, UNS8 error) +{ + UNS8 err; + UNS32 abortCode; + MSG_WAR(0x3F21, "Sending SDO to write in dictionnary of node : ", slaveNode); + if (error) { + MSG_ERR(0x1F22, "Unable to send the SDO to node ", slaveNode); + return -1; + } + /* Waiting until the slave has responded */ + while (getWriteResultNetworkDict (0, slaveNode, &abortCode) == SDO_DOWNLOAD_IN_PROGRESS) { + // Check if some SDO response are missing + scanSDOtimeout(); + } + + err = getWriteResultNetworkDict (0, slaveNode, &abortCode); + if (err == SDO_FINISHED) { + MSG_WAR(0x3F22, "SDO download finished to Node : ", slaveNode); + // Release the line. Don't forget !!! + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + return 0; + } + + if (err == SDO_ABORTED_RCV) { + MSG_WAR(0x2F20, "Received SDO abort from node : ", slaveNode); + } + + if (err == SDO_ABORTED_INTERNAL) { + MSG_WAR(0x2F20, "Internal SDO abort for node : ", slaveNode); + } + // Looking for the line transfert number to read the index, subindex and releasing the line. + { + UNS8 line; + err = getSDOlineOnUse(0, slaveNode, SDO_CLIENT, &line); + if (err) { + MSG_WAR(0x2F21, "No line found for node : ", slaveNode); + exit(-1); + } + MSG_WAR (0x2F22, "while writing at his index : ", transfers[0][line].index); + MSG_WAR (0x2F23, " subIndex : ", transfers[0][line].subIndex); + //Releasing the line. + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + exit(-1); + } + return 0; +} + +//------------------------------------------------------------------------------ +/* + */ +UNS8 waitingReadToSlaveDict(UNS8 slaveNode, void * data, UNS8 * size, UNS8 error) +{ + UNS8 err; + UNS32 abortCode; + MSG_WAR(0x3F2A, "Sending SDO to read in dictionnary of node : ", slaveNode); + if (error) { + MSG_ERR(0x1F2B, "Unable to send the SDO to node ", slaveNode); + return -1; + } + /* Waiting until the slave has responded */ + while (getReadResultNetworkDict (0, slaveNode, data, size, &abortCode) == SDO_UPLOAD_IN_PROGRESS) { + // Check if some SDO response are missing + scanSDOtimeout(); + } + err = getReadResultNetworkDict (0, slaveNode, data, size, &abortCode); + if (err == SDO_FINISHED) { + MSG_WAR(0x3F2C, "SDO upload finished to Node : ", slaveNode); + // Release the line. Don't forget !!! + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + return 0; + } + if (err == SDO_ABORTED_RCV) { + MSG_WAR(0x2F2D, "Received SDO abort from node : ", slaveNode); + } + + if (err == SDO_ABORTED_INTERNAL) { + MSG_WAR(0x2F2E, "Internal SDO abort for node : ", slaveNode); + } + // Looking for the line transfert number to read the index, subindex and releasing the line. + { + UNS8 line; + err = getSDOlineOnUse(0, slaveNode, SDO_CLIENT, &line); + if (err) { + MSG_WAR(0x2F2F, "No line found for node : ", slaveNode); + exit(-1); + } + MSG_WAR (0x2F30, "while writing at his index : ", transfers[0][line].index); + MSG_WAR (0x2F31, " subIndex : ", transfers[0][line].subIndex); + //Releasing the line. + closeSDOtransfer(0, slaveNode, SDO_CLIENT); + exit(-1); + } + + return 0; +} + + +//------------------------------------------------------------------------------ +/* The master is writing in the slave dictionnary to configure the SDO parameters +Remember that the slave is the server, and the master is the client. + */ +UNS8 configure_client_SDO(UNS8 slaveNode, UNS8 clientNode) +{ + UNS8 data; + UNS8 NbDataToWrite = 1 ; // in bytes + UNS8 err = 0; + MSG_WAR(0x3F20, "Configuring SDO by writing in dictionnary Node", slaveNode); + /* It is only to put at subindex 3 the serverNode. It is optionnal. + In the slave dictionary, only one SDO server is defined, at index + 0x1200 */ + data = clientNode; + err = writeNetworkDict(0, slaveNode, 0x1200, 3, NbDataToWrite, 0, &data); + waitingWriteToSlaveDict(slaveNode, err); + + return 0; +} + +//------------------------------------------------------------------------------ + +void masterMappingPDO(UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar) +{ + UNS32 *pbData; + UNS32 data32; + UNS8 i; + UNS8 size = 0; + UNS8 dataType; + + if ((indexPDO >= 0x1400) && (indexPDO <= 0x15FF)) + MSG_WAR(0x3F30, "Configuring MASTER for PDO receive, COBID : ", cobId); + + if ((indexPDO >= 0x1800) && (indexPDO <= 0x19FF)) + MSG_WAR(0x3F31, "Configuring MASTER for PDO transmit, COBID : ", cobId); + + /* At indexPDO, subindex 1, defining the cobId of the PDO */ + setODentry(indexPDO, 1, &cobId, 4, 0); + /* The mapping ... */ + /* ----------------*/ + /* At subindex 0, the number of variables in the PDO */ + setODentry(indexPDO + 0x200, 0, &nbVar, 1, 0); + getODentry(indexPDO + 0x200, 0, (void * *)&pbData, &size, &dataType, 0); + /* At each subindex 1 .. nbVar, The index,subindex and size of the variable to map in + the PDO. The first variable after the COBID is defined at subindex 1, ... + The data to write is the concatenation on 32 bits of (msb ... lsb) : + index(16b),subIndex(8b),sizeVariable(8b) +*/ + for (i = 0 ; i < nbVar ; i++) { + data32 = ((tabMappedVar + i)->index << 16) | + (((tabMappedVar + i)->subIndex & 0xFF) << 8) | + ((tabMappedVar + i)->size & 0xFF); + // Write dictionary + setODentry(indexPDO + 0x200, i + 1, &data32, 4, 0); + +# ifdef MORE_COMMENTS + printf("Mapped variable defined at index 0x%X, subIndex 0x%X, %d bits\n", + (tabMappedVar + i)->index, (tabMappedVar + i)->subIndex, 8 * (tabMappedVar + i)->size); + // Only to verify. + // Read dictionnary + getODentry(indexPDO + 0x200, i + 1, (void * *)&pbData, &size, &dataType, 0); + printf("Writen à index 0x%X, subIndex 0x%X, %d bits : 0x%08X\n", + indexPDO + 0x200, i + 1, 8 * size, *pbData); +# endif + + } +} + +//------------------------------------------------------------------------------ +/* + */ + +void slaveMappingPDO(UNS8 slaveNode, UNS32 indexPDO, UNS32 cobId, + s_mappedVar *tabMappedVar, UNS8 nbVar) +{ + UNS32 data32; + UNS8 i; + UNS8 err; + UNS8 nbBytes = 1; + if ((indexPDO >= 0x1400) && (indexPDO <= 0x15FF)) + MSG_WAR(0x3F32, "Configuring slave for PDO receive, COBID : ", cobId); + + if ((indexPDO >= 0x1800) && (indexPDO <= 0x19FF)) + MSG_WAR(0x3F33, "Configuring slave for PDO transmit, COBID : ", cobId); + + /* At indexPDO, subindex 1, defining the cobId of the PDO */ + err = writeNetworkDict(0, slaveNode, indexPDO, 1, 4, 0, &cobId); + waitingWriteToSlaveDict(slaveNode, err); + + /* The mapping ... */ + /* ----------------*/ + /* At subindex 0, the number of variables in the PDO */ + err = writeNetworkDict(0, slaveNode, indexPDO + 0x200, 0, nbBytes, 0, &nbVar); + waitingWriteToSlaveDict(slaveNode, err); + + /* At each subindex 1 .. nbVar, The index,subindex and size of the variable to map in + the PDO. The first variable after the COBID is defined at subindex 1, ... + The data to write is the concatenation on 32 bits of (msb ... lsb) : + index(16b),subIndex(8b),sizeVariable(8b) +*/ + for (i = 0 ; i < nbVar ; i++) { + data32 = ((tabMappedVar + i)->index << 16) | + (((tabMappedVar + i)->subIndex & 0xFF) << 8) | + ((tabMappedVar + i)->size & 0xFF); + + // Write dictionary + err = writeNetworkDict(0, slaveNode, indexPDO + 0x200, i + 1, 4, 0, &data32); + waitingWriteToSlaveDict(slaveNode, err); + +# ifdef MORE_COMMENTS + printf("Mapped variable defined at index 0x%X, subIndex 0x%X, %d bits\n", + (tabMappedVar + i)->index, (tabMappedVar + i)->subIndex, 8 * (tabMappedVar + i)->size); + + printf("At node 0x%X Writen at index 0x%X, subIndex 0x%X, %d bits : 0x%08X\n", + slaveNode, indexPDO + 0x200, i + 1, 32, data32); +# endif + + } +} + +//------------------------------------------------------------------------------ +/* + */ +void masterHeartbeatConsumer(s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats) +{ + UNS32 data; + UNS8 i; + UNS8 nbHB = nbHeartbeats; + + MSG_WAR(0x3F40, "Configuring heartbeats consumers for master", 0); + /* At index 1016, subindex 0 : the nb of consumers (ie nb of nodes of which are expecting heartbeats) */ + setODentry(0x1016, 0, & nbHB, 1, 0); + + /* At Index 1016, subindex 1, ... : 32 bit values : msb ... lsb : + 00 - node_consumer (8b) - time_ms (16b) + Put 0 to ignore the entry. + */ + for (i = 0 ; i < nbHeartbeats ; i++) { + data = (((tabHeartbeatConsumer + i)->nodeProducer & 0xFF)<< 16) | ((tabHeartbeatConsumer + i)->time_ms & 0xFFFF); + setODentry(0x1016, i + 1, & data, 4, 0); + } +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterHeartbeatProducer(UNS16 time) +{ + UNS16 hbTime = time; + MSG_WAR(0x3F45, "Configuring heartbeat producer for master", 0); + /* At index 1017, subindex 0, defining the time to send the heartbeat. Put 0 to never send heartbeat */ + setODentry(0x1017, 0, &hbTime, 2, 0); +} + +//------------------------------------------------------------------------------ +/* + */ +void slaveHeartbeatConsumer(UNS8 slaveNode, s_heartbeatConsumer + *tabHeartbeatConsumer, UNS8 nbHeartbeats) +{ + UNS32 data; + UNS8 err; + UNS8 i; + + MSG_WAR(0x3F46, "Configuring heartbeats consumers for node : ", slaveNode); + + /* At Index 1016, subindex 1, ... : 32 bit values : msb ... lsb : + 00 - node_consumer (8b) - time_ms (16b) + Put 0 to ignore the entry. + */ + for (i = 0 ; i < nbHeartbeats ; i++) { + data = (((tabHeartbeatConsumer + i)->nodeProducer & 0xFF)<< 16) | + ((tabHeartbeatConsumer + i)->time_ms & 0xFFFF); + err = writeNetworkDict(0, slaveNode, 0x1016, i + 1, 4, 0, &data); + waitingWriteToSlaveDict(slaveNode, err); + } +} + +//------------------------------------------------------------------------------ +/* + */ + +void slaveHeartbeatProducer(UNS8 slaveNode, UNS16 time) +{ + UNS8 err; + MSG_WAR(0x3F47, "Configuring heartbeat producer for node : ", slaveNode); + /* At index 1017, subindex 0, defining the time to send the heartbeat. Put 0 to never send heartbeat */ + + err = writeNetworkDict(0, slaveNode, 0x1017, 0, 2, 0, &time); + waitingWriteToSlaveDict(slaveNode, err); +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterPDOTransmissionMode(UNS32 indexPDO, UNS8 transType) +{ + MSG_WAR(0x3F48, "Configuring transmission from master, indexPDO : ", indexPDO); + + /* At subindex 2, the transmission type */ + setODentry(indexPDO, 2, &transType, 1, 0); +} + + +//------------------------------------------------------------------------------ +/* + */ + +void slavePDOTransmissionMode(UNS8 slaveNode, UNS32 indexPDO, UNS8 transType) +{ + UNS8 err; + MSG_WAR(0x3F41, "Configuring transmission mode for node : ", slaveNode); + MSG_WAR(0x3F42, " indexPDO : ", indexPDO); + + err = writeNetworkDict(0, slaveNode, indexPDO, 2, 1, 0, &transType); + waitingWriteToSlaveDict(slaveNode, err); + +} + +//------------------------------------------------------------------------------ +/* + */ + +void masterSYNCPeriod(UNS32 SYNCPeriod) +{ + UNS32 cobId = 0x40000080; + MSG_WAR(0x3F49, "Configuring master to send SYNC every ... micro-seconds :", SYNCPeriod); + /* At index 0x1006, subindex 0 : the period in ms */ + setODentry(0x1006, 0, &SYNCPeriod , 4, 0); + /* At index 0x1005, subindex 0 : Device generate SYNC signal with CobId 0x80 */ + setODentry(0x1005, 0, &cobId, 4, 0); +} + +void help() +{ + printf("**************************************************************\n"); + printf("* AppliMaster *\n"); + printf("* [-b b] *\n"); + printf("* *\n"); + printf("* b : bus [default 0] *\n"); + printf("* *\n"); + printf("* This exemple run AppliMaster on bus 0 *\n"); + printf("* AppliMaster -b 0 *\n"); + printf("* *\n"); + printf("**************************************************************\n"); +} + +/****************************************************************************/ +/*************************** MAIN *****************************************/ +/****************************************************************************/ +int main(int argc,char **argv) +{ + UNS8 second_last; + UNS8 minutes_last; + UNS8 sendingResetError = 0; + int i; + HANDLE ok; + char c; + extern char *optarg; + + while ((c = getopt(argc, argv, "-b:")) != EOF) + { + switch(c) + { + case 'b' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + board.busname = optarg; + break; + default: + help(); + exit(1); + } + } + + /****************************** INITIALISATION *******************************/ + + /* Launch the timer*/ + initTimer( ); + + /* arrays initialisation, etc */ + initCANopenMain(); + + /* arrays initialisation, etc */ + initCANopenMaster(); + + /* Defining the node Id */ + setNodeId(0x01); + MSG_WAR(0x3F50, "My node ID is : ", getNodeId()); + + /* Put the master in operational mode */ + setState(Operational); + + + /* Init the table of connected nodes */ + for (i = 0 ; i < 128 ; i++) + connectedNode[i] = 0; + + + ok = f_can_open(& board); + if (ok == NULL) { + MSG_ERR(0x1F02,"Unable to open the board", 0); + MSG_ERR(0x1F03,"Edit includeMakefileLinux to verify that the application is configured for the good board", 0); + exit (-1); + } + else { + MSG_WAR(0x3F03, "Board 0 opened ", 0); + } + + + /* Launch the thread to receive the messages */ + pthread_create( &threadM, NULL, (void *)&waitMessage, NULL); + + + + + + + + + + + + + + + + /******************** CONFIGURING THE NETWORK **************************/ + + /* Which nodes are connected ? */ + /* Sending a request Node guard to node 5 and 6 */ + MSG_WAR(0x3F04, "Sending a node guard to node : ", 5); + masterReadNodeState(0, 0x05); + /* Sending a message to the node 6, only as example */ + MSG_WAR(0x3F04, "Sending a node guard to node : ", 6); + masterReadNodeState(0, 0x06); + /* Waiting for a second the response */ + sleep(1); + + /* Whose node have answered ? */ + connectedNode[5] = stateNode(5); + connectedNode[6] = stateNode(6); + + /* Configure the SDO master to communicate with node 5 and node 6 */ + configure_master_SDO(0x1280, 0x05); + + + /* Configure the SDO of node 5 */ + /* getNodeId() returns my node Id */ + configure_client_SDO(0x05, getNodeId()); + /* Mapping of the PDO + Chose some COBID in (hexa) 181-1FF, 201-27F, 281-2FF, 301-37F, + 381-3FF, 401-47F, 481-4FF, 501-57F, + without other restriction. + (Of course, you must not define 2 PDO transmit with the same cobId !!) + */ + + /* + *** PDO node 1 <-- node 5 *** + *** cobId 0x181 ************* + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + day [0x6002 - 0x04 - 8] + hour [0x6002 - 0x03 - 8] + second [0x6002 - 0x01 - 8] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bits]: + day [0x2000 - 0x04 - 8] + hour [0x2000 - 0x03 - 8] + second [0x2000 - 0x01 - 8] +*/ + + /* Configuring the first PDO receive, defined at index 0x1400 and 0x1600 */ + { + s_mappedVar tabMappedVar[8] = { {0x6002,4,8}, {0x6002,3,8}, {0x6002,1,8}, }; + masterMappingPDO(0x1400, 0x181, tabMappedVar, 3); + } + + /* Configuring the first PDO transmit, defined at index 0x1800 and 0x1A00 */ + { + s_mappedVar tabMappedVar[8] = { {0x2000,4,8}, {0x2000,3,8}, {0x2000,1,8}, }; + slaveMappingPDO(0x05, 0x1800, 0x181, tabMappedVar, 3); + } + /* + *** PDO node 1 <-- node 5 *** + *** cobId 0x182 ************* + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + minute [0x6002 - 0x02 - 8] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bits]: + minute [0x2000 - 0x02 - 8] + */ + + /* Configuring PDO receive, defined at index 0x1400 and 0x1600 */ + { + s_mappedVar tabMappedVar[8] = { {0x6002,2,8} }; + masterMappingPDO(0x1401, 0x182, tabMappedVar, 1); + } + + /* Configuring PDO transmit, defined at index 0x1800 and 0x1A00 */ + { + s_mappedVar tabMappedVar[8] = { {0x2000,2,8} }; + slaveMappingPDO(0x05, 0x1801, 0x182, tabMappedVar, 1); + } + + + /* + *** PDO node 1 <-- node 5 *** + *** cobId 0x183 ************* + Error management : By this way, The node can send by PDO an error + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + canopenErrNb_node5 [0x6000 - 0x00 - 32] + canopenErrVal_node5 [0x6001 - 0x00 - 32] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bytes]: + canopenErrNb [0x6000 - 0x00 - 32] + canopenErrVal [0x6001 - 0x00 - 32] + */ + + /* Configuring PDO receive, defined at index 0x1402 and 0x1602 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + masterMappingPDO(0x1402, 0x183, tabMappedVar, 2); + } + + /* Configuring PDO transmit, defined at index 0x1802 and 0x1A02 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + slaveMappingPDO(0x05, 0x1802, 0x183, tabMappedVar, 2); + } + + /* + *** PDO node 1 --> node 5 *** + *** cobId 0x184 ************* + Error management : To reset the error + MASTER (node 1) + Mapped to variables (node1) [index-subindex-size_bits]: + canopenErrNb_node5 [0x6000 - 0x00 - 32] + canopenErrVal_node5 [0x6001 - 0x00 - 32] + + SLAVE (node 5) + Mapped to variables (node5) [index-subindex-size_bytes]: + canopenErrNb [0x6000 - 0x00 - 32] + canopenErrVal [0x6001 - 0x00 - 32] + */ + + /* Configuring PDO transmit, defined at index 0x1803 and 0x1103 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + masterMappingPDO(0x1801, 0x184, tabMappedVar, 2); + } + + /* Configuring PDO transmit, defined at index 0x1403 and 0x1603 */ + { + s_mappedVar tabMappedVar[8] = { {0x6000,0,32}, {0x6001, 0, 32}}; + slaveMappingPDO(0x05, 0x1400, 0x184, tabMappedVar, 2); + } + + /* Configuring the node 5 heartbeat */ + /* Check every 3000 ms if it have received a heartbeat from node 1 */ + { + UNS8 nbHeartbeatsToReceive = 1; + s_heartbeatConsumer tabHeartbeatConsumer[10] = {{1, 0xBB8}}; + slaveHeartbeatConsumer(0x05, tabHeartbeatConsumer, nbHeartbeatsToReceive); + } + /* Sending every 1000 ms an heartbeat */ + slaveHeartbeatProducer(0x05, 0x3E8); + + /* Configuring the master heartbeat */ + /* Check every 3000 ms if it have received a heartbeat from node 5 */ + { + UNS8 nbHeartbeatsToReceive = 1; + s_heartbeatConsumer tabHeartbeatConsumer[10] = {{5, 0xBB8}}; + masterHeartbeatConsumer(tabHeartbeatConsumer, nbHeartbeatsToReceive); + } + + /* Sending every 1000 ms an heartbeat */ + masterHeartbeatProducer(0x3E8); + + + + /* Configuring the transmission mode of the PDO */ + slavePDOTransmissionMode(0x05, 0x1800, TRANS_EVERY_N_SYNC (1)); + slavePDOTransmissionMode(0x05, 0x1801, TRANS_EVENT); + slavePDOTransmissionMode(0x05, 0x1802, TRANS_EVENT); + masterPDOTransmissionMode(0x1801, TRANS_EVENT); + + /* Configuring the master to send a SYNC message every 1 s */ + /* Note than any other node can send the SYNC instead of the master */ + masterSYNCPeriod(1000000); + + { + // Reading the period of heartbeat which has been written in node 5 dictionary + UNS8 node = 5; + UNS16 index = 0x1017; + UNS8 subindex = 0; + //UNS8 notused = 0; + UNS16 hb = 0; + UNS8 size_data = 0; + UNS8 error; + MSG_WAR(0x3F50, "Reading dictionary noeud 5, 1017/0", 0); + error = readNetworkDict(0, node, index, subindex, 0); + //error = readNetworkDict(0, node, index, subindex, ¬used); + if (error) { + MSG_ERR(0x1F50, "!!! ERROR reading dictionary noeud 5, 1017/0", 0); + exit (-1); + } + /* Waiting until the server has responded */ + error = waitingReadToSlaveDict(node, (UNS16 *)&hb, &size_data, error); + MSG_WAR(0x1F51, "Read dictionary of node 5, index/subindex 1017/0 value = ", hb); + MSG_WAR(0x1F51, " size of data (bytes) = ", size_data); + } + + + + /* Put the node 5 in operational mode + The mode is changed according to the slave state machine mode : + initialisation ---> pre-operational (Automatic transition) + pre-operational <--> operational + pre-operational <--> stopped + pre-operational, operational, stopped -> initialisation + NMT_Start_Node // Put the node in operational mode + NMT_Stop_Node // Put the node in stopped mode + NMT_Enter_PreOperational // Put the node in pre_operational mode + NMT_Reset_Node // Put the node in initialization mode + NMT_Reset_Comunication // Put the node in initialization mode + */ + masterSendNMTstateChange(0, 0x05, NMT_Start_Node); + + + // Note + //----- + // We do not have mapped the variable canopenErrNB and canopenErrVAL. + // We should have done that ! + // the macro MSG_ERR try to send the PDO(s) which contains these two variables. + // While the PDO will not be found, if you are printing the warnings in file pdo.c, + // it will print "0X393B Unable to send variable on event : not mapped in a PDO to send on event" for + // example when you enter the function heartbeatError. + + /******************** END CONFIGURING THE NETWORK **********************/ + + /* Launch the thread to send the SYNC message */ + pthread_create( &threadS, NULL, (void *)&transmitSync , NULL); + /* Init the errors values that may send the node 5 */ + canopenErrNB_node5 = 0; + canopenErrVAL_node5 = 0; + + /****************************** RUNNING *******************************/ + + /* SDO test with node 5 */ + { + // Reading string + UNS8 dataW[20]; + UNS8 dataR[20]; + UNS8 size; + UNS8 err; + MSG_WAR(0x3F05, "Test SDO", 0); + + MSG_WAR(0x3F10, "Writing string to node 5 index 0x6002, subindex 0 ...", 0); + strcpy(dataW, "Au Revoir"); + MSG_WAR(0x3F10, dataW, 0); + size = 20; + err = writeNetworkDict(0, 5, 0x6002, 0, 10, visible_string, dataW); + err = waitingWriteToSlaveDict(5, err); + + err = readNetworkDict(0, 5, 0x6002, 0, visible_string); + err = waitingReadToSlaveDict(5, dataR, &size, err); + MSG_WAR(0x3F08, "Data read from node 5 index 0x6002, subindex 0 ..." , 0); + MSG_WAR(0x3F08, dataR, 0); + + MSG_WAR(0x3F08, "node 5. Hardware version. (default = compil. date) ...", 0); + err = readNetworkDict(0, 5, 0x1009, 0, visible_string); + err = waitingReadToSlaveDict(5, dataR, &size, err); + MSG_WAR(0x3F08, dataR, 0); + + MSG_WAR(0x3F08, "node 5. Software version. (default = compil. time) ...", 0); + err = readNetworkDict(0, 5, 0x100A, 0, visible_string); + err = waitingReadToSlaveDict(5, dataR, &size, err); + MSG_WAR(0x3F08, dataR, 0); + } + + // Node identity ? + { + UNS8 *data; + UNS8 size; + UNS8 dataType; + // Manufacturer Device name (default = empty string) + getODentry(0x1008, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Hardware version. (default = compilation. date) + getODentry(0x1009, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Software version. (default = compilation. time) + getODentry(0x100A, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + } + + while (1) { + if (minutes != minutes_last) { + printf("Minutes changed\n"); + minutes_last = minutes; + } + + if (second != second_last) { + printf("Date : %d, %02dH%02d-%02d\n", day, hour, minutes, second); + second_last = second; + + if (canopenErrNB_node5) { + printf("Received an error from node 5, NB : 0x%X, value : 0x%X\n", + canopenErrNB_node5 , canopenErrVAL_node5); + // Resetting the error + canopenErrNB_node5 = 0; + canopenErrVAL_node5 = 0; + sendingResetError = 1; + } + + if ((second < 5) && sendingResetError) { + printf("Sending to node 5 a PDO event to reset the error NB: 0x%X and VAL: 0x%X\n", + canopenErrNB_node5, canopenErrVAL_node5); + + sendPDOevent(0, &canopenErrNB_node5); + sendingResetError = 0; + } + + + } // end if (second != second_last) + + // Testing if heartsbeat have been received, and send a heartbeat if it is time. + // I have put that in a thread, but I don't know why, on HB not received, + // it doesn't returns from heartbeatError() to the thread. + heartbeatMGR(); + + usleep(10000); + + } + return 0; +} diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_Linux/objdict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_Linux/objdict.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,770 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "pdo.h" +#include "sdo.h" +#include "sync.h" +#include "lifegrd.h" +#include "nmtSlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ + + + +/*// Copy and uncomment this code to your main file +extern UNS32 canopenErrNB_node5; // Mapped at index 0x6000, subindex 0x00 +extern UNS32 canopenErrVAL_node5; // Mapped at index 0x6001, subindex 0x00 +extern UNS8 second; // Mapped at index 0x6002, subindex 0x01 +extern UNS8 minutes; // Mapped at index 0x6002, subindex 0x02 +extern UNS8 hour; // Mapped at index 0x6002, subindex 0x03 +extern UNS8 day; // Mapped at index 0x6002, subindex 0x04 +extern UNS32 canopenErrNB; // Mapped at index 0x6003, subindex 0x01 +extern UNS32 canopenErrVAL; // Mapped at index 0x6003, subindex 0x02 + +// END copy to main file +*/ + +UNS32 canopenErrNB_node5; // Mapped at index 0x6000, subindex 0x00 +UNS32 canopenErrVAL_node5; // Mapped at index 0x6001, subindex 0x00 +UNS8 second; // Mapped at index 0x6002, subindex 0x01 +UNS8 minutes; // Mapped at index 0x6002, subindex 0x02 +UNS8 hour; // Mapped at index 0x6002, subindex 0x03 +UNS8 day; // Mapped at index 0x6002, subindex 0x04 +UNS32 canopenErrNB; // Mapped at index 0x6003, subindex 0x01 +UNS32 canopenErrVAL; // Mapped at index 0x6003, subindex 0x02 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + + + +UNS32 valueRangeTest (UNS8 typeValue, UNS32 unsValue, REAL32 realValue) +{ + return 0; +} + + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* Computed by strNode */ +/* node_id default value. + This default value is deprecated. + You should always overwrite this by using the function setNodeId(UNS8 nodeId) in your C code. +*/ +#define NODE_ID 0x01 +UNS8 bDeviceNodeId = NODE_ID; + + +//*****************************************************************************/ +/* Computed by strStartDico */ + +/* Array of message processing information */ +/* Should not be modified */ +volatile const proceed_info proceed_infos[] = { + {NMT, "NMT", NULL}, + {SYNC, "SYNC", proceedSYNC}, + {TIME_STAMP, "TStmp", NULL}, + {PDO1tx, "PDO1t", proceedPDO}, + {PDO1rx, "PDO1r", proceedPDO}, + {PDO2tx, "PDO2t", proceedPDO}, + {PDO2rx, "PDO2r", proceedPDO}, + {PDO3tx, "PDO3t", proceedPDO}, + {PDO3rx, "PDO3r", proceedPDO}, + {PDO4tx, "PDO4t", proceedPDO}, + {PDO4rx, "PDO4r", proceedPDO}, + {SDOtx, "SDOt", proceedSDO}, + {SDOrx, "SDOr", proceedSDO}, + {0xD, "Unkw", NULL}, + {NODE_GUARD, "NGrd", proceedNMTerror}, + {0xF, "Unkw", NULL} +}; + + // Macros definition + +/* Beware : +index *must* be writen 4 numbers in hexa +sub_index *must* be writen 2 numbers in hexa +size_variable_in_UNS8 *must* be writen 2 numbers in hexa +*/ +#define PDO_MAP(index, sub_index, size_variable_in_bits)\ +0x ## index ## sub_index ## size_variable_in_bits + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// Make your change, depending of your application + + +/* index 0x1000 : Device type. + You have to change the value below, so + it fits your canopen-slave-module */ + + /* Not used, so, should not be modified */ + + UNS32 obj1000 = 0; + subindex Index1000[] = + { + { RO, uint32, sizeof(UNS32), (void*)&obj1000 } + }; + +/* index 0x1001 : Error register. + Change the entries to fit your application + Not used, so, should not be modified */ + /*const*/ UNS8 obj1001 = 0x0; + /*const*/ subindex Index1001[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1001 } + }; + +/* index 0x1005 : COB_ID SYNC */ + /* Should not be modified */ + UNS32 obj1005 = 0x00000080; // bit 30 = 1 : device can generate a SYNC message + // Beware, it is over written when the node + // enters in reset mode + // See initResetMode() in init.c + /*const*/ subindex Index1005[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1005 } + }; + +/* index 0x1006 : SYNC period */ + // For producing the SYNC signal every n micro-seconds. + // Put O to not producing SYNC + /*const*/ UNS32 obj1006 = 0x0; + // Default 0 to not produce SYNC // + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + /*const*/ subindex Index1006[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1006 } + }; + +/* index 0x1007 : Synchronous Window Length + Seems to be needed by DS401 to generate the SYNC signal ! */ + /*const*/ UNS32 obj1007 = 0x0; /* Default 0 */ + /*const*/ subindex Index1007[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1007 } + }; + +/* index 0x1008 : Manufacturer device name */ + UNS8 obj1008[] = "Appli_Master_Linux"; /* Default 0 */ + subindex Index1008[] = + { + { RO, uint32, sizeof(obj1008), (void*)&obj1008 } + }; + +/* index 0x1009 : Manufacturer hardware version */ + UNS8 obj1009[] = __DATE__; /* Default 0 */ + subindex Index1009[] = + { + { RO, uint32, sizeof(obj1009), (void*)&obj1009 } + }; + +/* index 0x100A : Manufacturer software version */ + UNS8 obj100A[] = __TIME__; /* Default 0 */ + subindex Index100A[] = + { + { RO, uint32, sizeof(obj100A), (void*)&obj100A} + }; + +/* index 0x1016 : HeartBeat consumers + The nodes which can send a heartbeat */ + static UNS32 obj1016[] = {// Consumer time for each node + 0x00000000}; // Format 0x00NNTTTT (N=Node T=time in ms) + + static UNS8 obj1016_cnt = 1; // 1 nodes could send me + // their heartbeat. + subindex Index1016[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1016_cnt }, + { RW, uint32, sizeof(UNS32), (void*)&obj1016[0] } + }; + +/* index 0x1017 : Heartbeat producer + Every HBProducerTime, the node sends its heartbeat */ + static UNS16 obj1017 = 0; //HBProducerTime in ms. If 0 : not activated + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + subindex Index1017[] = + { + { RW, uint16, sizeof(UNS16), &obj1017 } + }; + +/* index 0x1018 : Identity object */ + /** index 1018: identify object. Adjust the entries for your node/company + */ + /* Values can be modified */ + + s_identity obj1018 = + { + 4, // number of supported entries + 0, // Vendor-ID (given by the can-cia) + 0, // Product Code + 0, // Revision number + 0 // serial number + }; + + subindex Index1018[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1018.count }, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.vendor_id}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.product_code}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.revision_number}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.serial_number} + }; + +/* index 0x1200 : The SDO Server parameters */ + /* BEWARE You cannot define more than one SDO server */ + /* The values should not be modified here, + but can be changed at runtime */ + // Beware that the default values that you could put here + // will be over written at the initialisation of the node. + // See setNodeId() in init.c + static s_sdo_parameter obj1200 = + { 3, // Number of entries. Always 3 for the SDO + 0x600 + NODE_ID, // The cob_id transmited in CAN msg to the server + 0x580 + NODE_ID, // The cob_id received in CAN msg from the server + NODE_ID // The node id of the client. Should not be modified + }; + static subindex Index1200[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1200.count }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_client }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_server }, + { RW, uint8, sizeof( UNS8), (void*)&obj1200.node_id } + }; + +/* index 0x1280 : SDO client parameter */ + static s_sdo_parameter obj1280 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1280[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1280.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1280.node_id } + }; + +/* index 0x1281 : SDO client parameter */ + static s_sdo_parameter obj1281 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1281[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1281.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1281.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1281.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1281.node_id } + }; + +/* index 0x1282 : SDO client parameter */ + static s_sdo_parameter obj1282 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1282[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1282.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1282.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1282.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1282.node_id } + }; + +/* index 0x1283 : SDO client parameter */ + static s_sdo_parameter obj1283 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1283[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1283.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1283.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1283.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1283.node_id } + }; + +/* index 0x1284 : SDO client parameter */ + static s_sdo_parameter obj1284 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1284[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1284.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1284.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1284.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1284.node_id } + }; + +/* index 0x1285 : SDO client parameter */ + static s_sdo_parameter obj1285 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1285[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1285.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1285.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1285.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1285.node_id } + }; + +/* index 0x1286 : SDO client parameter */ + static s_sdo_parameter obj1286 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1286[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1286.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1286.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1286.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1286.node_id } + }; + +/* index 0x1287 : SDO client parameter */ + static s_sdo_parameter obj1287 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1287[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1287.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1287.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1287.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1287.node_id } + }; + +/* index 0x1288 : SDO client parameter */ + static s_sdo_parameter obj1288 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1288[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1288.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1288.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1288.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1288.node_id } + }; + +/* index 0x1289 : SDO client parameter */ + static s_sdo_parameter obj1289 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1289[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1289.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1289.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1289.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1289.node_id } + }; + +/* index 0x1400 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1400 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1400[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1400.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1400.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1400.type }, + }; + +/* index 0x1401 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1401 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1401[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1401.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1401.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1401.type }, + }; + +/* index 0x1402 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1402 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1402[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1402.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1402.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1402.type }, + }; + +/* index 0x1600 : PDO receive mapping parameter of PDO communication index 0x1400 */ + static UNS8 obj1600_cnt = 0; // Number of mapped variables + static UNS32 obj1600_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1600[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1600_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[7]} + }; + +/* index 0x1601 : PDO receive mapping parameter of PDO communication index 0x1401 */ + static UNS8 obj1601_cnt = 0; // Number of mapped variables + static UNS32 obj1601_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1601[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1601_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[7]} + }; + +/* index 0x1602 : PDO receive mapping parameter of PDO communication index 0x1402 */ + static UNS8 obj1602_cnt = 0; // Number of mapped variables + static UNS32 obj1602_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1602[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1602_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[7]} + }; + +/* index 0x1800 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1800 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1800[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1800.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1800.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1800.type }, + }; + +/* index 0x1801 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1801 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1801[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1801.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1801.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1801.type }, + }; + +/* index 0x1802 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1802 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1802[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1802.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1802.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1802.type }, + }; + +/* index 0x1A00 : PDO transmit mapping parameter of PDO communication index 0x1800 */ + static UNS8 obj1A00_cnt = 0; // Number of mapped variables + static UNS32 obj1A00_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A00[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A00_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[7]} + }; + +/* index 0x1A01 : PDO transmit mapping parameter of PDO communication index 0x1801 */ + static UNS8 obj1A01_cnt = 0; // Number of mapped variables + static UNS32 obj1A01_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A01[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A01_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[7]} + }; + +/* index 0x1A02 : PDO transmit mapping parameter of PDO communication index 0x1802 */ + static UNS8 obj1A02_cnt = 0; // Number of mapped variables + static UNS32 obj1A02_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A02[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A02_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[7]} + }; + + +/* index 0x6000 : Mapped variable */ + subindex Index6000[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB_node5 } + }; + +/* index 0x6001 : Mapped variable */ + subindex Index6001[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL_node5 } + }; + +/* index 0x6002 : Mapped variable */ + static UNS8 highestSubIndex_6002 = 4; // number of subindex - 1 + subindex Index6002[] = + { + { RO, uint8, sizeof (UNS8), (void*)&highestSubIndex_6002 }, + { RW, uint8, sizeof (UNS8), (void*)&second }, + { RW, uint8, sizeof (UNS8), (void*)&minutes }, + { RW, uint8, sizeof (UNS8), (void*)&hour }, + { RW, uint8, sizeof (UNS8), (void*)&day } + }; + +/* index 0x6003 : Mapped variable */ + static UNS8 highestSubIndex_6003 = 2; // number of subindex - 1 + subindex Index6003[] = + { + { RO, uint8, sizeof (UNS8), (void*)&highestSubIndex_6003 }, + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB }, + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL } + }; + +const indextable objdict[] = +{ + DeclareIndexTableEntry(Index1000, 0x1000), + DeclareIndexTableEntry(Index1001, 0x1001), + DeclareIndexTableEntry(Index1005, 0x1005), + DeclareIndexTableEntry(Index1006, 0x1006), + DeclareIndexTableEntry(Index1007, 0x1007), + DeclareIndexTableEntry(Index1008, 0x1008), + DeclareIndexTableEntry(Index1009, 0x1009), + DeclareIndexTableEntry(Index100A, 0x100A), + DeclareIndexTableEntry(Index1016, 0x1016), + DeclareIndexTableEntry(Index1017, 0x1017), + DeclareIndexTableEntry(Index1018, 0x1018), + DeclareIndexTableEntry(Index1200, 0x1200), + DeclareIndexTableEntry(Index1280, 0x1280), + DeclareIndexTableEntry(Index1281, 0x1281), + DeclareIndexTableEntry(Index1282, 0x1282), + DeclareIndexTableEntry(Index1283, 0x1283), + DeclareIndexTableEntry(Index1284, 0x1284), + DeclareIndexTableEntry(Index1285, 0x1285), + DeclareIndexTableEntry(Index1286, 0x1286), + DeclareIndexTableEntry(Index1287, 0x1287), + DeclareIndexTableEntry(Index1288, 0x1288), + DeclareIndexTableEntry(Index1289, 0x1289), + DeclareIndexTableEntry(Index1400, 0x1400), + DeclareIndexTableEntry(Index1401, 0x1401), + DeclareIndexTableEntry(Index1402, 0x1402), + DeclareIndexTableEntry(Index1600, 0x1600), + DeclareIndexTableEntry(Index1601, 0x1601), + DeclareIndexTableEntry(Index1602, 0x1602), + DeclareIndexTableEntry(Index1800, 0x1800), + DeclareIndexTableEntry(Index1801, 0x1801), + DeclareIndexTableEntry(Index1802, 0x1802), + DeclareIndexTableEntry(Index1A00, 0x1A00), + DeclareIndexTableEntry(Index1A01, 0x1A01), + DeclareIndexTableEntry(Index1A02, 0x1A02), + DeclareIndexTableEntry(Index6000, 0x6000), + DeclareIndexTableEntry(Index6001, 0x6001), + DeclareIndexTableEntry(Index6002, 0x6002), + DeclareIndexTableEntry(Index6003, 0x6003), +}; + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 count_sync[1] = {0, }; + +UNS16 firstIndex (enum e_first_object object, UNS16 *lastIndex) +{ + switch (object) { + case FIRST_SDO_SERVER : + *lastIndex = 11; + return 11; + case FIRST_SDO_CLIENT : + *lastIndex = 21; + return 12; + case FIRST_PDO_RCV : + *lastIndex = 24; + return 22; + case FIRST_PDO_RCV_MAP : + *lastIndex = 27; + return 25; + case FIRST_PDO_TRS : + *lastIndex = 30; + return 28; + case FIRST_PDO_TRS_MAP : + *lastIndex = 33; + return 31; + } + *lastIndex = 0; + return 0; +} + +UNS16 getObjdictSize (void) +{ + return sizeof(objdict)/sizeof(objdict[0]); +} diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_Linux/objdict.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_Linux/objdict.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,154 @@ + + + + +CANOpen object dictionary Configuration + + + +

Object dictionary for Node :

+

+Mastermaster +

+

Overview

+

+ How to make the object dictionary of the node ? + First, use Jaxe (command run_objdict) to edit an xml description file +of the dictionary : objdict.xml. +Then, run the php program : makeobjetdict.php. You can launch php through a web browser +if you have installed a server, or, on Linux, you can launch php in command line : +php-cgi makeobjetdict.php. It compute the file objdict.c. Link it to + your project. +
Note : To define the node id, use in your code the function setNodeId(UNS8 nodeId) +

+

+ Then the node can be connected to the network. The master must configure it + by sending SDO. It will write values in its index, subindex. What to configure ? +

    +
  • Receiving heartbeats from which nodes ? Waiting time ?
  • +
  • Emitting heartbeats or not ? time btw 2 heartbeats ?
  • +
  • Defining a cobId for each PDO receive and transmit
  • +
  • How to transmit a PDO ? on synchro ? request ? event ?
  • +
  • What variables to put in each PDO receive and transmit ?
  • +
  • ...
  • +
+

+ To avoid configuring the node at the connection, you can put the values directly +in the dictionary objdict.c. But it is boring and unsafe because it is too easy to make +a mistake ! + + +

Number of heartbeat consumers : + 1 +

+

This means that the node can expect heartbeats sent by 1 nodes.

+

Number of SDO clients : + 10 +

+

Usualy, a slave node does not have the use of SDO clients, but + today, for the library, you must define one. The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Maximum objects in a PDO (receive or transmit) : + 8 +

+

This is defining how many variables can be transmited in a + PDO. (maximum is 8).

+

For each variable, a table is created, so if you have less room + in memory, put a value under 8.

+

Number of PDO receive : + 3 +

+

The node can receive 3 PDO.

+

The communication parameters are defined at index 0x1400 to 0x1400 + 2

+

The mapping parameters are defined at index 0x1600 to 0x1600 + 2

+

Number of PDO transmit : + 3 +

+

The node can transmit 3 PDO.

+

The communication parameters are defined at index 0x1800 to 0x1800 + 2

+

The mapping parameters are defined at index 0x1A00 to 0x1A00 + 2

+

Mapped variables and tables

+

3 tables are defined for the mapping, starting at index 0x2000, 0x6000 and 0x6200. + You must start the mapping at the beginning of one of a table, without holes in index +or subindex. For example, variables in 0x2000 and 0x2001 is ok, but variables in 0x2000 and 0x2002 is not allowed, because you are loosing room in memory. It is the same for the subindex. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameBitsIndexSub-index
canopenErrNB_node5320x60000x0
canopenErrVAL_node5320x60010x0
second80x60020x1
minutes80x60020x02
hour80x60020x3
day80x60020x4
canopenErrNB320x60030x01
canopenErrVAL320x60030x02
+ + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliMaster_Linux/objdict.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliMaster_Linux/objdict.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,84 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -Os +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +BINUTILS_PREFIX = SUB_BINUTILS_PREFIX +TARGET = SUB_TARGET + +INCLUDES = -I../../include -I../../include/hcs12 +MEMORY_X = ../../include/hcs12/board/arch + +OBJCOPY = $(BINUTILS_PREFIX)objcopy +OBJCOPY_FLAGS = --only-section=.text --only-section=.rodata --only-section=.vectors --only-section=.data + +PROGDEFINES = -mnoshort -Wall -Wmissing-prototypes -fno-strict-aliasing -g + +PGR=AppliSlave + +SLAVE_OBJS = objdict.o appli.o vectors.o + +OBJS = ../../src/hc12_pdo.o ../../src/hc12_sdo.o ../../src/hc12_init.o ../../src/hc12_sync.o\ + ../../src/hc12_objacces.o ../../src/hc12_lifegrd.o ../../src/hc12_timer.o ../../src/hc12_nmtSlave.o\ + ../../drivers/hc12/canOpenDriver.o ../../drivers/hc12/ports.o ../../drivers/hc12/interrupt.o\ + ../../drivers/hc12/timerhw.o ../../drivers/hc12/variahw.o $(SLAVE_OBJS) + +LDFLAGS= -Wl,-m,m68hc12elfb -L$(MEMORY_X) + +all: $(PGR).elf $(PGR).s19 $(PGR).b $(PGR).s MSG + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -c -o $@ $< + +%o: %s + $(CC) -c -x assembler-with-cpp $(PROG_CFLAGS) -o $@ $< + +$(PGR).elf: $(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) + +$(PGR).s19: $(PGR).elf + $(OBJCOPY) --output-target=srec $(OBJCOPY_FLAGS) $< $@ + +$(PGR).b: $(PGR).elf + $(OBJCOPY) --output-target=binary --gap-fill=255 --only-section=.data $(OBJCOPY_FLAGS) $< $@ + +$(PGR).s: $(PGR).elf + @echo "Desassemble" + $(BINUTILS_PREFIX)objdump -D $(PGR).elf > $(PGR).s + +MSG: + $(BINUTILS_PREFIX)readelf -S $(PGR).elf + @echo + $(BINUTILS_PREFIX)size $(PGR).elf + +clean: + -\rm $(SLAVE_OBJS) + +mrproper: clean + -\rm $(PGR).elf $(PGR).s19 $(PGR).b $(PGR).s + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/appli.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/appli.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,514 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include /* for NULL */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "../include/def.h" +#include "../include/can.h" +#include "../include/objdictdef.h" +#include "../include/objacces.h" +#include "../include/canOpenDriver.h" +#include "../include/sdo.h" +#include "../include/pdo.h" +#include "../include/init.h" +#include "../include/timer.h" +#include "../include/lifegrd.h" +#include "../include/sync.h" + +#include "../include/nmtSlave.h" + + + +// HCS12 configuration +// ----------------------------------------------------- + +enum E_CanBaudrate +{ + CAN_BAUDRATE_250K, + CAN_BAUDRATE_500K, + CAN_BAUDRATE_1M, + CAN_BAUDRATE_OLD_VALUE +}; + +const canBusTime CAN_Baudrates[] = +{ + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 3, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 13 tq for the TIME 1 segment (tseg1 = 12) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 4 MHZ (brp = 3+1), and there are 16 tq in the bit time, + so the freq of the bit time is 250 kHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 13 tq for the TIME 1 segment (tseg1 = 12) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 8 MHZ (brp = 1+1), and there are 16 tq in the bit time, + so the freq of the bit time is 500 kHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 4, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 5 tq for the TIME 1 segment (tseg1 = 4) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 8 MHZ (brp = 1+1), and there are 8 tq in the bit time, + so the freq of the bit time is 1 MHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 0, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 1, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 1, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 4, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 9, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 10 tq for the TIME 1 segment (tseg1 = 9) + - 5 tq for the TIME 2 segment (tseg2 = 4) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 16 MHZ (brp = 0), and there are 16 tq in the bit time, + so the freq of the bit time is 1 MHz. + */ + } +}; + + +// The variables sent or updated by PDO +// ----------------------------------------------------- +extern UNS8 seconds; // Mapped at index 0x2000, subindex 0x1 +extern UNS8 minutes; // Mapped at index 0x2000, subindex 0x2 +extern UNS8 hours; // Mapped at index 0x2000, subindex 0x3 +extern UNS8 day; // Mapped at index 0x2000, subindex 0x4 +extern UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x0 +extern UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x0 + +// Required definition variables +// ----------------------------- +// The variables that you should define for debugging. +// They are used by the macro MSG_ERR and MSG_WAR in applicfg.h +// if the node is a slave, they can be mapped in the object dictionnary. +// if not null, allow the printing of message to the console +// Could be managed by PDO +UNS8 printMsgErrToConsole = 1; +UNS8 printMsgWarToConsole = 1; + + + +/*************************User's variables declaration**************************/ +UNS8 softCount = 0; +UNS8 lastMinute = 0; +UNS8 lastSecond = 0; +UNS8 sendingError = 0; +//--------------------------------FONCTIONS------------------------------------- +/* You *must* have these 2 functions in your code*/ +void heartbeatError(UNS8 heartbeatID); +void SD0timeoutError(UNS8 bus_id, UNS8 line); + +// Interruption timer 3. (The timer 4 is used by CanOpen) +void __attribute__((interrupt)) timer3Hdl (void); + +void incDate(void); +void initLeds(void); +void initTimerClk(void); +void initCanHCS12 (void); +void initialisation(void); +void preOperational(void); +void operational(void); +void stopped(void); +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Interruption timer 3 +void __attribute__((interrupt)) timer3Hdl (void) +{ + //IO_PORTS_8(PORTB) ^= 0x10; + //IO_PORTS_8(PORTB) &= ~0x20; + IO_PORTS_8(TFLG1) = 0x08; // RAZ du flag interruption timer 3 + // Calcul evt suivant. Clock 8 MHz -> 8000 evt de 1 ms!! Doit tenir sur 16 bits + // Attention, ça change si on utilise la pll + // Lorsque le timer atteindra la valeur de TC3 (16 bits), l'interruption timer3Hdl sera déclenchée + // Si on utilise la PLL à 24 MHZ, alors la vitesse du bus est multipliée par 3. + +/* Assume that our board uses a 16 MHz quartz */ +/* Without pre-division, 8000 counts takes 1 ms. */ +/* We are using a pre-divisor of 32. (register TSCR2) See in CanOpenDriverHC12/timerhw.c */ +/* So 10000 counts takes 40 ms. */ +/* We must have a soft counter of 25 to count a second. */ + + IO_PORTS_16(TC3H) += (10000); // IT every 40000 count. + softCount++; + if (softCount == 25) { + softCount = 0; + incDate(); + } +} + +//------------------------------------------------------------------------------ +void heartbeatError(UNS8 heartbeatID) +{ + MSG_ERR(0x1F00, "!!! No heart beat received from node : ", heartbeatID); +} + +//------------------------------------------------------------------------------ +void SD0timeoutError (UNS8 bus_id, UNS8 line) +{ + // Informations on what occurs are in transfers[bus_id][line].... + // See scanSDOtimeout() in sdo.c +} + +//------------------------------------------------------------------------------ +// Incrementation of the date, every second +void incDate(void) +{ + if (seconds == 59) { + seconds = 0; + if (minutes == 59) { + minutes = 0; + if (hours == 23) { + hours = 0; + day++; + } + else + hours++; + } + else + minutes++; + } + else + seconds++; + + // Toggle the led 4 every seconds + IO_PORTS_8(PORTB) ^= 0x10; + +} + +//Initialisation of the port B for the leds. +void initLeds(void) +{ + // Port B is output + IO_PORTS_8(DDRB)= 0XFF; + // RAZ + IO_PORTS_8(PORTB) = 0xFF; +} + + + +//------------------------------------------------------------------------------ +// Init the timer for the clock demo +void initTimerClk(void) +{ + + lock(); // Inhibe les interruptions + + // Configuration du Channel 3 + IO_PORTS_8(TIOS) |= 0x08; // Canal 3 en sortie + IO_PORTS_8(TCTL2) &= ~(0xC0); // Canal 3 déconnecté du pin de sortie + IO_PORTS_8(TIE) |= 0x08; // Autorise interruption Canal 3 + IO_PORTS_8(TSCR1) |= 0x80; // Mise en route du timer + unlock(); // Autorise les interruptions +} + + +//------------------------------------------------------------------------------ + +// A placer avant initTimer de la bibliothèque CanOpen +/* void initTimerbis(void) */ +/* { */ + +/* lock(); // Inhibe les interruptions */ +/* // Configuration des IT Channels (0..3) */ +/* IO_PORTS_8(TIOS) &= 0xF0; // Canals 0->3 en entrées. */ +/* IO_PORTS_8(TCTL4) &= 0XFD; // Canal 0 détection sur front montant. */ +/* IO_PORTS_8(TCTL4) |= 0X01; */ +/* IO_PORTS_8(TCTL4) &= 0XF7; // Canal 1 détection sur front montant. */ +/* IO_PORTS_8(TCTL4) |= 0X04; */ +/* IO_PORTS_8(TCTL4) &= 0XDF; // Canal 2 détection sur front montant. */ +/* IO_PORTS_8(TCTL4) |= 0X10; */ +/* IO_PORTS_8(TCTL4) &= 0X7F; // Canal 3 détection sur front montant. */ +/* IO_PORTS_8(TCTL4) |= 0X40; */ +/* IO_PORTS_8(TSCR2) |= 0X05; // Pre-scaler = 32. */ + +/* IO_PORTS_8(ICOVW) |= 0x0F; // La sauvgrade des valeures de TC0 et TC0H */ +/* // correspondant aux canals (0..3) jusqu'a la */ +/* // prochaine lecture dans ces registres. */ +/* MASK = IO_PORTS_8(ICSYS); */ +/* MASK &= 0xFE; // Canals (0..3) en IC QUEUE MODE. */ +/* MASK |= 0x08; // Canals (0..3) : génére une interruption aprés */ +/* // la capture de deux valeures du timer sur detection */ +/* // d'un front montant à l'entrée des canals (0..3). */ +/* MASK |= 0x02; */ +/* IO_PORTS_8(ICSYS) = MASK; */ +/* IO_PORTS_16(TC0HH); // Vider le registre holding correspondant au canal0. */ +/* IO_PORTS_8(TSCR1) |= 0x10; // RAZ automatique des flags d'interruption aprés lecture */ +/* // dans les registres correspondant. */ + +/* IO_PORTS_8(TIE) |= 0x0F; // Autorise interruption Canals (0..3). */ +/* IO_PORTS_8(TSCR2) |= 0X80; // Autorise interruption sur l'Overflow. */ +/* unlock(); // Autorise les interruptions */ + +/* } */ + +//------------------------------------------------------------------------------ + + + +void initCanHCS12 (void) +{ + //Init the HCS12 microcontroler for CanOpen + initHCS12(); + // Init the HCS12 CAN driver + const canBusInit bi0 = { + 0, /* no low power */ + 0, /* no time stamp */ + 1, /* enable MSCAN */ + 0, /* clock source : oscillator (In fact, it is not used) */ + 0, /* no loop back */ + 0, /* no listen only */ + 0, /* no low pass filter for wk up */ + CAN_Baudrates[CAN_BAUDRATE_250K], + { + 0x00, /* Filter on 16 bits. See Motorola Block Guide V02.14 fig 4-3 */ + 0x00, 0xFF, /* filter 0 hight accept all msg */ + 0x00, 0xFF, /* filter 0 low accept all msg */ + 0x00, 0xFF, /* filter 1 hight filter all of msg */ + 0x00, 0xFF, /* filter 1 low filter all of msg */ + 0x00, 0xFF, /* filter 2 hight filter most of msg */ + 0x00, 0xFF, /* filter 2 low filter most of msg */ + 0x00, 0xFF, /* filter 3 hight filter most of msg */ + 0x00, 0xFF, /* filter 3 low filter most of msg */ + } + }; + + canInit(CANOPEN_LINE_NUMBER_USED, bi0); //initialize filters... + unlock(); // Allow interruptions +} + + +/*********************************************************************/ +void initialisation( void ) +{ + //initcapteur(); //initialisation du capteur, timer, compteurs logiciels + initCanHCS12(); //initialisation du bus Can + MSG_WAR(0X3F05, "I am in INITIALISATION mode ", 0); + /* Defining the node Id */ + setNodeId(0x05); + MSG_WAR(0x3F06, "My node ID is : ", getNodeId()); + { + UNS8 *data; + UNS8 size; + UNS8 dataType; + // Manufacturer Device name (default = empty string) + getODentry(0x1008, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Hardware version. (default = compilation. date) + getODentry(0x1009, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Software version. (default = compilation. time) + getODentry(0x100A, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + } + initCANopenMain(); //initialisation du canopen + heartbeatInit(); //initialisation du lifeguarding + initResetMode(); + initTimer(); //initialisation of the timer used by Canopen + initTimerClk(); +} + + +/*********************************************************************/ +void preOperational(void) +{ + // Test if the heartBeat have been received. Send headbeat + heartbeatMGR(); + // Read message + receiveMsgHandler(0); +} + + +/********************************************************************/ +void operational( void ) +{ + + // Init the errors + canopenErrNB = 0; + canopenErrVAL = 0; + + // Test if the heartBeat have been received. Send headbeat + heartbeatMGR(); + // Read message + receiveMsgHandler(0); + + if (lastMinute != minutes) { + MSG_WAR(0x3F00, "event : minutes change -> node decides to send it. Value : ", minutes); + sendPDOevent( 0, &minutes ); + lastMinute = minutes; + } + + if (canopenErrNB == 0) + sendingError = 0; + + + if (lastSecond != seconds) { + MSG_WAR (0x3F50, "Seconds = ", seconds); + if ((seconds == 50) && (sendingError == 0)) + { + MSG_ERR(0x1F55, "DEMO of ERROR. Sent by PDO. Value : ", 0xABCD); + sendingError = 1; + } + + if (canopenErrNB) { + MSG_WAR(0x3F56, "ERROR nb : ", canopenErrNB); + } + lastSecond = seconds; + + } + +} + + +/*****************************************************************************/ +void stopped( void ) +{ + heartbeatMGR(); + // Read message + receiveMsgHandler(0); +} + + +/*****************************************************************************/ + + + +/********************************* MAIN ***************************************/ + + +int main () +{ + e_nodeState lastState = Unknown_state; + + /* CanOpen slave state machine */ + /* ------------------------------------*/ + + while(1) { /* slave's state machine */ + + switch( getState() ) { + case Initialisation: + if (lastState != getState()) { + initLeds(); + IO_PORTS_8(PORTB) &= ~ 0x01; // led 0 : ON + IO_PORTS_8(PORTB) |= 0x0E; // leds 1, 2, 3 : OFF + MSG_WAR(0X3F10, "Entering in INITIALISATION mode ", 0); + } + initialisation(); + /* change automatically into pre_operational state */ + lastState = Initialisation; + setState(Pre_operational); + break; + + case Pre_operational: + if (lastState != getState()) { + IO_PORTS_8(PORTB) &= ~ 0x03; // leds 0, 1 : ON + IO_PORTS_8(PORTB) |= 0x0C; // leds 2, 3 : OFF + MSG_WAR(0X3F11, "Entering in PRE_OPERATIONAL mode ", 0); + initPreOperationalMode(); + } + preOperational(); + if (lastState == Initialisation) + slaveSendBootUp(0); + lastState = Pre_operational; + break; + + case Operational: + if (lastState != getState()) { + IO_PORTS_8(PORTB) &= ~ 0x07; // leds 0, 1, 2 : ON + IO_PORTS_8(PORTB) |= 0x08; // leds 3 : OFF + MSG_WAR(0X3F12, "Entering in OPERATIONAL mode ", 0); + } + operational(); + lastState = Operational; + break; + + case Stopped: + if (lastState != getState()) { + IO_PORTS_8(PORTB) |= 0x0F; // leds 0, 1, 2, 3 : OFF + MSG_WAR(0X3F13, "Entering in STOPPED mode", 0); + } + stopped(); + lastState = Stopped; + break; + }//end switch case + + } + return (0); +} + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/objdict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/objdict.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,621 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "pdo.h" +#include "sdo.h" +#include "sync.h" +#include "lifegrd.h" +#include "nmtSlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ + + + +/*// Copy and uncomment this code to your main file +extern UNS8 seconds; // Mapped at index 0x2000, subindex 0x01 +extern UNS8 minutes; // Mapped at index 0x2000, subindex 0x02 +extern UNS8 hours; // Mapped at index 0x2000, subindex 0x03 +extern UNS8 day; // Mapped at index 0x2000, subindex 0x04 +extern UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x00 +extern UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x00 +extern UNS8 strTest[10]; // Mapped at index 0x6002, subindex 0x00 + +// END copy to main file +*/ + +UNS8 seconds; // Mapped at index 0x2000, subindex 0x01 +UNS8 minutes; // Mapped at index 0x2000, subindex 0x02 +UNS8 hours; // Mapped at index 0x2000, subindex 0x03 +UNS8 day; // Mapped at index 0x2000, subindex 0x04 +UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x00 +UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x00 +UNS8 strTest[10]; // Mapped at index 0x6002, subindex 0x00 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + + + +UNS32 valueRangeTest (UNS8 typeValue, UNS32 unsValue, REAL32 realValue) +{ + return 0; +} + + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* Computed by strNode */ +/* node_id default value. + This default value is deprecated. + You should always overwrite this by using the function setNodeId(UNS8 nodeId) in your C code. +*/ +#define NODE_ID 0x01 +UNS8 bDeviceNodeId = NODE_ID; + + +//*****************************************************************************/ +/* Computed by strStartDico */ + +/* Array of message processing information */ +/* Should not be modified */ +volatile const proceed_info proceed_infos[] = { + {NMT, "NMT", proceedNMTstateChange}, + {SYNC, "SYNC", proceedSYNC}, + {TIME_STAMP, "TStmp", NULL}, + {PDO1tx, "PDO1t", proceedPDO}, + {PDO1rx, "PDO1r", proceedPDO}, + {PDO2tx, "PDO2t", proceedPDO}, + {PDO2rx, "PDO2r", proceedPDO}, + {PDO3tx, "PDO3t", proceedPDO}, + {PDO3rx, "PDO3r", proceedPDO}, + {PDO4tx, "PDO4t", proceedPDO}, + {PDO4rx, "PDO4r", proceedPDO}, + {SDOtx, "SDOt", proceedSDO}, + {SDOrx, "SDOr", proceedSDO}, + {0xD, "Unkw", NULL}, + {NODE_GUARD, "NGrd", proceedNMTerror}, + {0xF, "Unkw", NULL} +}; + + // Macros definition + +/* Beware : +index *must* be writen 4 numbers in hexa +sub_index *must* be writen 2 numbers in hexa +size_variable_in_UNS8 *must* be writen 2 numbers in hexa +*/ +#define PDO_MAP(index, sub_index, size_variable_in_bits)\ +0x ## index ## sub_index ## size_variable_in_bits + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// Make your change, depending of your application + + +/* index 0x1000 : Device type. + You have to change the value below, so + it fits your canopen-slave-module */ + + /* Not used, so, should not be modified */ + + UNS32 obj1000 = 0; + subindex Index1000[] = + { + { RO, uint32, sizeof(UNS32), (void*)&obj1000 } + }; + +/* index 0x1001 : Error register. + Change the entries to fit your application + Not used, so, should not be modified */ + /*const*/ UNS8 obj1001 = 0x0; + /*const*/ subindex Index1001[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1001 } + }; + +/* index 0x1005 : COB_ID SYNC */ + /* Should not be modified */ + UNS32 obj1005 = 0x00000080; // bit 30 = 1 : device can generate a SYNC message + // Beware, it is over written when the node + // enters in reset mode + // See initResetMode() in init.c + /*const*/ subindex Index1005[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1005 } + }; + +/* index 0x1006 : SYNC period */ + // For producing the SYNC signal every n micro-seconds. + // Put O to not producing SYNC + /*const*/ UNS32 obj1006 = 0x0; + // Default 0 to not produce SYNC // + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + /*const*/ subindex Index1006[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1006 } + }; + +/* index 0x1007 : Synchronous Window Length + Seems to be needed by DS401 to generate the SYNC signal ! */ + /*const*/ UNS32 obj1007 = 0x0; /* Default 0 */ + /*const*/ subindex Index1007[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1007 } + }; + +/* index 0x1008 : Manufacturer device name */ + UNS8 obj1008[] = "Appli_Slave_HC12"; /* Default 0 */ + subindex Index1008[] = + { + { RO, uint32, sizeof(obj1008), (void*)&obj1008 } + }; + +/* index 0x1009 : Manufacturer hardware version */ + UNS8 obj1009[] = __DATE__; /* Default 0 */ + subindex Index1009[] = + { + { RO, uint32, sizeof(obj1009), (void*)&obj1009 } + }; + +/* index 0x100A : Manufacturer software version */ + UNS8 obj100A[] = __TIME__; /* Default 0 */ + subindex Index100A[] = + { + { RO, uint32, sizeof(obj100A), (void*)&obj100A} + }; + +/* index 0x1016 : HeartBeat consumers + The nodes which can send a heartbeat */ + static UNS32 obj1016[] = {// Consumer time for each node + 0x00000000}; // Format 0x00NNTTTT (N=Node T=time in ms) + + static UNS8 obj1016_cnt = 1; // 1 nodes could send me + // their heartbeat. + subindex Index1016[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1016_cnt }, + { RW, uint32, sizeof(UNS32), (void*)&obj1016[0] } + }; + +/* index 0x1017 : Heartbeat producer + Every HBProducerTime, the node sends its heartbeat */ + static UNS16 obj1017 = 0; //HBProducerTime in ms. If 0 : not activated + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + subindex Index1017[] = + { + { RW, uint16, sizeof(UNS16), &obj1017 } + }; + +/* index 0x1018 : Identity object */ + /** index 1018: identify object. Adjust the entries for your node/company + */ + /* Values can be modified */ + + s_identity obj1018 = + { + 4, // number of supported entries + 0, // Vendor-ID (given by the can-cia) + 0, // Product Code + 0, // Revision number + 0 // serial number + }; + + subindex Index1018[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1018.count }, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.vendor_id}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.product_code}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.revision_number}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.serial_number} + }; + +/* index 0x1200 : The SDO Server parameters */ + /* BEWARE You cannot define more than one SDO server */ + /* The values should not be modified here, + but can be changed at runtime */ + // Beware that the default values that you could put here + // will be over written at the initialisation of the node. + // See setNodeId() in init.c + static s_sdo_parameter obj1200 = + { 3, // Number of entries. Always 3 for the SDO + 0x600 + NODE_ID, // The cob_id transmited in CAN msg to the server + 0x580 + NODE_ID, // The cob_id received in CAN msg from the server + NODE_ID // The node id of the client. Should not be modified + }; + static subindex Index1200[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1200.count }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_client }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_server }, + { RW, uint8, sizeof( UNS8), (void*)&obj1200.node_id } + }; + +/* index 0x1280 : SDO client parameter */ + static s_sdo_parameter obj1280 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1280[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1280.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1280.node_id } + }; + +/* index 0x1400 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1400 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1400[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1400.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1400.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1400.type }, + }; + +/* index 0x1401 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1401 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1401[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1401.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1401.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1401.type }, + }; + +/* index 0x1402 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1402 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1402[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1402.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1402.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1402.type }, + }; + +/* index 0x1600 : PDO receive mapping parameter of PDO communication index 0x1400 */ + static UNS8 obj1600_cnt = 0; // Number of mapped variables + static UNS32 obj1600_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1600[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1600_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[7]} + }; + +/* index 0x1601 : PDO receive mapping parameter of PDO communication index 0x1401 */ + static UNS8 obj1601_cnt = 0; // Number of mapped variables + static UNS32 obj1601_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1601[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1601_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[7]} + }; + +/* index 0x1602 : PDO receive mapping parameter of PDO communication index 0x1402 */ + static UNS8 obj1602_cnt = 0; // Number of mapped variables + static UNS32 obj1602_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1602[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1602_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[7]} + }; + +/* index 0x1800 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1800 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1800[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1800.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1800.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1800.type }, + }; + +/* index 0x1801 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1801 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1801[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1801.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1801.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1801.type }, + }; + +/* index 0x1802 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1802 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1802[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1802.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1802.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1802.type }, + }; + +/* index 0x1A00 : PDO transmit mapping parameter of PDO communication index 0x1800 */ + static UNS8 obj1A00_cnt = 0; // Number of mapped variables + static UNS32 obj1A00_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A00[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A00_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[7]} + }; + +/* index 0x1A01 : PDO transmit mapping parameter of PDO communication index 0x1801 */ + static UNS8 obj1A01_cnt = 0; // Number of mapped variables + static UNS32 obj1A01_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A01[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A01_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[7]} + }; + +/* index 0x1A02 : PDO transmit mapping parameter of PDO communication index 0x1802 */ + static UNS8 obj1A02_cnt = 0; // Number of mapped variables + static UNS32 obj1A02_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A02[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A02_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[7]} + }; + + +/* index 0x2000 : Mapped variable */ + static UNS8 highestSubIndex_2000 = 4; // number of subindex - 1 + subindex Index2000[] = + { + { RO, uint8, sizeof (UNS8), (void*)&highestSubIndex_2000 }, + { RW, uint8, sizeof (UNS8), (void*)&seconds }, + { RW, uint8, sizeof (UNS8), (void*)&minutes }, + { RW, uint8, sizeof (UNS8), (void*)&hours }, + { RW, uint8, sizeof (UNS8), (void*)&day } + }; + +/* index 0x6000 : Mapped variable */ + subindex Index6000[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB } + }; + +/* index 0x6001 : Mapped variable */ + subindex Index6001[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL } + }; + +/* index 0x6002 : Mapped variable */ + subindex Index6002[] = + { + { RW, visible_string, sizeof (strTest), (void*)&strTest } + }; + +const indextable objdict[] = +{ + DeclareIndexTableEntry(Index1000, 0x1000), + DeclareIndexTableEntry(Index1001, 0x1001), + DeclareIndexTableEntry(Index1005, 0x1005), + DeclareIndexTableEntry(Index1006, 0x1006), + DeclareIndexTableEntry(Index1007, 0x1007), + DeclareIndexTableEntry(Index1008, 0x1008), + DeclareIndexTableEntry(Index1009, 0x1009), + DeclareIndexTableEntry(Index100A, 0x100A), + DeclareIndexTableEntry(Index1016, 0x1016), + DeclareIndexTableEntry(Index1017, 0x1017), + DeclareIndexTableEntry(Index1018, 0x1018), + DeclareIndexTableEntry(Index1200, 0x1200), + DeclareIndexTableEntry(Index1280, 0x1280), + DeclareIndexTableEntry(Index1400, 0x1400), + DeclareIndexTableEntry(Index1401, 0x1401), + DeclareIndexTableEntry(Index1402, 0x1402), + DeclareIndexTableEntry(Index1600, 0x1600), + DeclareIndexTableEntry(Index1601, 0x1601), + DeclareIndexTableEntry(Index1602, 0x1602), + DeclareIndexTableEntry(Index1800, 0x1800), + DeclareIndexTableEntry(Index1801, 0x1801), + DeclareIndexTableEntry(Index1802, 0x1802), + DeclareIndexTableEntry(Index1A00, 0x1A00), + DeclareIndexTableEntry(Index1A01, 0x1A01), + DeclareIndexTableEntry(Index1A02, 0x1A02), + DeclareIndexTableEntry(Index2000, 0x2000), + DeclareIndexTableEntry(Index6000, 0x6000), + DeclareIndexTableEntry(Index6001, 0x6001), + DeclareIndexTableEntry(Index6002, 0x6002), +}; + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 count_sync[1] = {0, }; + +UNS16 firstIndex (enum e_first_object object, UNS16 *lastIndex) +{ + switch (object) { + case FIRST_SDO_SERVER : + *lastIndex = 11; + return 11; + case FIRST_SDO_CLIENT : + *lastIndex = 12; + return 12; + case FIRST_PDO_RCV : + *lastIndex = 15; + return 13; + case FIRST_PDO_RCV_MAP : + *lastIndex = 18; + return 16; + case FIRST_PDO_TRS : + *lastIndex = 21; + return 19; + case FIRST_PDO_TRS_MAP : + *lastIndex = 24; + return 22; + } + *lastIndex = 0; + return 0; +} + +UNS16 getObjdictSize (void) +{ + return sizeof(objdict)/sizeof(objdict[0]); +} diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/objdict.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/objdict.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,158 @@ + + + + +CANOpen object dictionary Configuration + + + +

Object dictionary for Node :

+

+Linux_slaveslave +

+

Overview

+

+ How to make the object dictionary of the node ? + First, use Jaxe (command run_objdict) to edit an xml description file +of the dictionary : objdict.xml. +Then, run the php program : makeobjetdict.php. You can launch php through a web browser +if you have installed a server, or, on Linux, you can launch php in command line : +php-cgi makeobjetdict.php. It compute the file objdict.c. Link it to + your project. +
Note : To define the node id, use in your code the function setNodeId(UNS8 nodeId) +

+

+ Then the node can be connected to the network. The master must configure it + by sending SDO. It will write values in its index, subindex. What to configure ? +

    +
  • Receiving heartbeats from which nodes ? Waiting time ?
  • +
  • Emitting heartbeats or not ? time btw 2 heartbeats ?
  • +
  • Defining a cobId for each PDO receive and transmit
  • +
  • How to transmit a PDO ? on synchro ? request ? event ?
  • +
  • What variables to put in each PDO receive and transmit ?
  • +
  • ...
  • +
+

+ To avoid configuring the node at the connection, you can put the values directly +in the dictionary objdict.c. But it is boring and unsafe because it is too easy to make +a mistake ! + + +

Number of heartbeat consumers : + 1 +

+

This means that the node can expect heartbeats sent by 1 nodes.

+

Number of SDO clients : + 1 +

+

Usualy, a slave node does not have the use of SDO clients, but + today, for the library, you must define one. The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Maximum objects in a PDO (receive or transmit) : + 8 +

+

This is defining how many variables can be transmited in a + PDO. (maximum is 8).

+

For each variable, a table is created, so if you have less room + in memory, put a value under 8.

+

Number of PDO receive : + 3 +

+

The node can receive 3 PDO.

+

The communication parameters are defined at index 0x1400 to 0x1400 + 2

+

The mapping parameters are defined at index 0x1600 to 0x1600 + 2

+

Number of PDO transmit : + 3 +

+

The node can transmit 3 PDO.

+

The communication parameters are defined at index 0x1800 to 0x1800 + 2

+

The mapping parameters are defined at index 0x1A00 to 0x1A00 + 2

+

Mapped variables and tables

+

3 tables are defined for the mapping, starting at index 0x2000, 0x6000 and 0x6200. + You must start the mapping at the beginning of one of a table, without holes in index +or subindex. For example, variables in 0x2000 and 0x2001 is ok, but variables in 0x2000 and 0x2002 is not allowed, because you are loosing room in memory. It is the same for the subindex. +

+

+ The access of the variable is by default "rw" (read-write) or "ro" (read-only). A read-only variable cannot be mapped in a PDO receive. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + +
Var NameBitsIndexSub-indexaccess
seconds80x20000x1rw
minutes80x20000x02rw
hours80x20000x3rw
day80x20000x4rw
canopenErrNB320x60000x0rw
canopenErrVAL320x60010x0rw
Table NameBitsIndexSub-indexaccess
+ + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/objdict.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/objdict.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/trace32_flash_debug.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/trace32_flash_debug.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,43 @@ +; Réinitialisation +SYS.d + +; Effacer l'écran +WinCLEAR + +;Raffraichissement de trace32 toutes les 1 secondes +setup.urate 1 + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Vitesse de commuication debugger / carte HCS12 + SYStem.BdmClock 8.0MHZ + +; initialiser le uc en mode debug +SYStem.UP + +; Reset des registres +r.reset + +; Charger le programme +DATA.LOAD.ELF appliSlave.elf /gnu /nocode /GHILLS + +; Positionner le compteur de programme +r.set PC _start + +; Positionner le pointeur de pile +r.set SP _stack + +; Afficher le code source +data.list + +; Afficher les registres +;r + +; Afficher le contenu de la mémoire +;DATA.dump 140 + + +; Fin du programme de script +ENDDO + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/trace32_flash_debug_sans_init.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/trace32_flash_debug_sans_init.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,36 @@ +; Réinitialisation +SYS.d + +; Effacer l'écran +;WinCLEAR + +;Raffraichissement de trace32 toutes les 1 secondes +setup.urate 1 + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Vitesse de commuication debugger / carte HCS12 + SYStem.BdmClock 8.0MHZ + +; initialiser le uc en mode debug +SYStem.UP + +; Reset des registres +r.reset + +; Charger le programme +DATA.LOAD.ELF appliSlave.elf /gnu /nocode /GHILLS + +; Positionner le compteur de programme +r.set PC _start + +; Positionner le pointeur de pile +r.set SP _stack + + + + +; Fin du programme de script +ENDDO + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/trace32_flash_programmer.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/trace32_flash_programmer.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,94 @@ +; Programmation de la mémoire flash + + +; Réinitialisation +SYS.d + +; Effacer l'écran +WinCLEAR + +; Vitesse de transmission : +SYStem.BdmClock 8.0MHZ + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Flash page 0X3E accessible entre 0X4000 et 0X7FFF +; cf Motorola, registre MISC + +system.option ROMHM ON + + +; Enlever tous les points d'arrêt +b.res + +; Utiliser les points d'arrêts onchip +map.bonchip + +; Connexion à la carte CS12 +system.up + +flash.reset + + +; Effacement de la flash +PRINT "Effacement de la flash" +FLASH.Erase all + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 1 " +FLASH.Program 0x4000--0x7FFF + +;print "Chargement du programme en flash 1" +DATA.LOAD.ELF appliSlave.elf 0x4000--0x7FFF + + +FLASH.Program off +print "Flash programmée 1" + + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 2" +FLASH.Program 0x308000--0x30BFFF + +;print "Chargement du programme en flash 2" +DATA.LOAD.ELF appliSlave.elf 0x8000--0xBFFF + + +FLASH.Program off +print "Flash programmée 2" + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 3" +FLASH.Program 0xC000--0xFFFF + +;print "Chargement du programme en flash 3" +DATA.LOAD.ELF appliSlave.elf 0xC000--0xFFFF + + +FLASH.Program off +print "Flash programmée 3" + + +;Reset du HCS12 +system.up + +;Reset de trace32 +SYS.d + + +ENDDO + + + + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_HCS12/vectors.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_HCS12/vectors.s Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,214 @@ +;;/* M68HC11 Interrupt vectors table +;; Copyright (C) 1999 Free Software Foundation, Inc. +;; Written by Stephane Carrez (stcarrez@worldnet.fr) +;; +;;This file is free software; you can redistribute it and/or modify it +;;under the terms of the GNU General Public License as published by the +;;Free Software Foundation; either version 2, or (at your option) any +;;later version. +;; +;;In addition to the permissions in the GNU General Public License, the +;;Free Software Foundation gives you unlimited permission to link the +;;compiled version of this file with other programs, and to distribute +;;those programs without any restriction coming from the use of this +;;file. (The General Public License restrictions do apply in other +;;respects; for example, they cover modification of the file, and +;;distribution when not linked into another program.) +;; +;;This file 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 +;;General Public License for more details. +;; +;;You should have received a copy of the GNU General Public License +;;along with this program; see the file COPYING. If not, write to +;;the Free Software Foundation, 59 Temple Place - Suite 330, +;;Boston, MA 02111-1307, USA. +;; ---------------------------------------------- +;; Modified by Francis Dupin for MC9S12DP256. April 2003 +;; francis.dupin@inrets.fr +;;*/ + + .sect .text + .globl _start + .globl can4HdlTra + .globl can4HdlRcv + .globl can4HdlErr + .globl can4HdlWup + .globl can3HdlTra + .globl can3HdlRcv + .globl can3HdlErr + .globl can3HdlWup + .globl can2HdlTra + .globl can2HdlRcv + .globl can2HdlErr + .globl can2HdlWup + .globl can1HdlTra + .globl can1HdlRcv + .globl can1HdlErr + .globl can1HdlWup + .globl can0HdlTra + .globl can0HdlRcv + .globl can0HdlErr + .globl can0HdlWup + .globl timerOvflHdl + .globl timer3IC + .globl timer2IC + .globl timer1IC + .globl timer0IC + +;; Default interrupt handler. + .sect .text +def: + rti + +;; +;; Interrupt vectors are in a specific section that is +;; mapped at 0xff00. For the example program, the reset handler +;; points to the generic crt0 entry point. +;; + .sect .vectors + .globl vectors +vectors: + + .word def ; ff00 + .word def ; ff02 + .word def ; ff04 + .word def ; ff06 + .word def ; ff08 + .word def ; ff0a + .word def ; ff0c + .word def ; ff0e + .word def ; ff10 + .word def ; ff12 + .word def ; ff14 + .word def ; ff16 + .word def ; ff18 + .word def ; ff1a + .word def ; ff1c + .word def ; ff1e + .word def ; ff20 + .word def ; ff22 + .word def ; ff24 + .word def ; ff26 + .word def ; ff28 + .word def ; ff2a + .word def ; ff2c + .word def ; ff2e + .word def ; ff30 + .word def ; ff32 + .word def ; ff34 + .word def ; ff36 + .word def ; ff38 + .word def ; ff3a + .word def ; ff3c + .word def ; ff3e + .word def ; ff40 + .word def ; ff42 + .word def ; ff44 + .word def ; ff46 + .word def ; ff48 + .word def ; ff4a + .word def ; ff4c + .word def ; ff4e + .word def ; ff50 + .word def ; ff52 + .word def ; ff54 + .word def ; ff56 + .word def ; ff58 + .word def ; ff5a + .word def ; ff5c + .word def ; ff5e + .word def ; ff60 + .word def ; ff62 + .word def ; ff64 + .word def ; ff66 + .word def ; ff68 + .word def ; ff6a + .word def ; ff6c + .word def ; ff6e + .word def ; ff70 + .word def ; ff72 + .word def ; ff74 + .word def ; ff76 + .word def ; ff78 + .word def ; ff7a + .word def ; ff7c + .word def ; ff7e + .word def ; ff80 + .word def ; ff82 + .word def ; ff84 + .word def ; ff86 + .word def ; ff88 + .word def ; ff8a + .word def ; ff8c + .word def ; ff8e + + ;; MSCAN + .word can4HdlTra ; ff90 (MSCAN4 Transmit) + .word can4HdlRcv ; ff92 (MSCAN4 Receive) + .word can4HdlErr ; ff94 (MSCAN4 Errors) + .word can4HdlWup ; ff96 (MSCAN4 Wake up) + .word can3HdlTra ; ff98 (MSCAN3 Transmit) + .word can3HdlRcv ; ff9a (MSCAN3 Receive) + .word can3HdlErr ; ff9c (MSCAN3 Errors) + .word can3HdlWup ; ff9e (MSCAN3 Wake up) + .word can2HdlTra ; ffa0 (MSCAN2 Transmit) + .word can2HdlRcv ; ffa2 (MSCAN2 Receive) + .word can2HdlErr ; ffa4 (MSCAN2 Errors) + .word can2HdlWup ; ffa6 (MSCAN2 Wake up) + .word can1HdlTra ; ffa8 (MSCAN1 Transmit) + .word can1HdlRcv ; ffaa (MSCAN1 Receive) + .word can1HdlErr ; ffac (MSCAN1 Errors) + .word can1HdlWup ; ffae (MSCAN1 Wake up) + .word can0HdlTra ; ffb0 (MSCAN0 Transmit) + .word can0HdlRcv ; ffb2 (MSCAN0 Receive) + .word can0HdlErr ; ffb4 (MSCAN0 Errors) + .word can0HdlWup ; ffb6 (MSCAN0 Wake up) + + .word def ; ffb8 + .word def ; ffba + .word def ; ffbc + .word def ; ffbe + + .word def ; ffc0 + .word def ; ffc2 + .word def ; ffc4 + .word def ; ffc6 + .word def ; ffc8 + .word def ; ffca (Modulus Down Counter underflow) + .word def ; ffcc + .word def ; ffce + .word def ; ffd0 + .word def ; ffd2 + .word def ; ffd4 + + ;; SCI + .word def ; ffd6 + + ;; SPI + .word def ; ffd8 + .word def ; ffda (PAII) + .word def ; ffdc (PAOVI) + .word def ;ffde (TOI) + + ;; Timer Output Compare + .word def ; ffe0 Timer Chanel 7 + .word def ; ffe2 Timer Chanel 6 + .word def ; ffe4 Timer Chanel 5 + .word timer4Hdl ; ffe6 Timer Chanel 4 used by Canopen + .word timer3Hdl ; ffe8 Timer Chanel 3 For the date + .word def ; ffea Timer Chanel 2 + .word def ; ffec Timer Chanel 1 + .word def ; ffee Timer Chanel 0 + + ;; Misc + .word def ; fff0 (RTII) + .word def ; fff2 (IRQ) + .word def ; fff4 (XIRQ) + .word def ; fff6 (SWI) + .word def ; fff8 (ILL) + .word def ; fffa (COP Failure) + .word def ; fffc (COP Clock monitor) + .word _start ; fffe (reset) + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_Linux/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_Linux/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_Linux/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_Linux/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,60 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET + +LIBPATH = /usr/lib +LIBINC = /usr/include +LIB = -L$(LIBPATH) -lpcan + +INCLUDES = -I../../include -I../../include/peak + +SLAVE_OBJS = objdict.o appli.o + +OBJS = $(SLAVE_OBJS) ../../src/peak_pdo.o ../../src/peak_sdo.o ../../src/peak_init.o ../../src/peak_sync.o\ + ../../src/peak_objacces.o ../../src/peak_lifegrd.o ../../src/peak_timer.o ../../src/peak_nmtSlave.o\ + ../../drivers/peak/canOpenDriver.o ../../drivers/peak/timerhw.o + + +all: AppliSlave + +AppliSlave: $(OBJS) + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -lpthread -lstdc++ $(OBJS) $(LIB) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -D_REENTRANT -c $< + +clean: + -rm $(SLAVE_OBJS) + +mrproper: clean + -rm AppliSlave + + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_Linux/appli.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_Linux/appli.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,344 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "def.h" +#include "can.h" +#include "canOpenDriver.h" +#include "sdo.h" +#include "pdo.h" +#include "init.h" +#include "timer.h" +#include "lifegrd.h" + +#include "nmtSlave.h" + +// Adlink 7841 or Peak PCI/CAN board +// --------------------------------- + +// Baudrate values for Peak board : +// CAN_BAUD_1M CAN_BAUD_500K CAN_BAUD_250K CAN_BAUD_125K CAN_BAUD_100K CAN_BAUD_50K +// CAN_BAUD_20K CAN_BAUD_10K CAN_BAUD_5K + +#ifdef CAN_BAUD_250K +# define BAUDRATE CAN_BAUD_250K +#else +// Appli have been compiled for Adlink-arbraca. Baudrate not used +# define BAUDRATE 0 +#endif + +s_BOARD board = {"1", BAUDRATE}; + + +// The variables sent or updated by PDO +// ----------------------------------------------------- +extern UNS8 seconds; // Mapped at index 0x2000, subindex 0x1 +extern UNS8 minutes; // Mapped at index 0x2000, subindex 0x2 +extern UNS8 hours; // Mapped at index 0x2000, subindex 0x3 +extern UNS8 day; // Mapped at index 0x2000, subindex 0x4 +extern UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x0 +extern UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x0 + +// Required definition variables +// ----------------------------- +// The variables that you should define for debugging. +// They are used by the macro MSG_ERR and MSG_WAR in applicfg.h +// if the node is a slave, they can be mapped in the object dictionnary. +// if not null, allow the printing of message to the console +// Could be managed by PDO +UNS8 printMsgErrToConsole = 1; +UNS8 printMsgWarToConsole = 1; + + + +/*************************User's variables declaration**************************/ +struct tm date; +struct tm *ptrdate; +struct tm date_prec; +time_t tme; +UNS8 lastSecond; +e_nodeState lastState; +pthread_t threadRcvMsg; +pthread_t threadHeartbeatAndSDO; +UNS8 sendingError = 0; + + +/******************************prototypes*****************************/ +/* You *must* have these 2 functions in your code*/ +void heartbeatError(UNS8 heartbeatID); +void SD0timeoutError(UNS8 bus_id, UNS8 line); + +UNS8 scanSDOtimeout(void); +void preOperational(void); +void operational(void); +void stopped(void); +void waitMessage(void); +void waitMessage_heartbeat(void); + +/*********************************************************************/ +void heartbeatError(UNS8 heartbeatID) +{ + MSG_ERR(0x1F00, "!!! No heart beat received from node : ", heartbeatID); +} + +/*****************************************************************************/ +void SD0timeoutError (UNS8 bus_id, UNS8 line) +{ + // Informations on what occurs are in transfers[bus_id][line].... + // See scanSDOtimeout() in sdo.c +} + +/*********************************** THREADS **********************************/ +//------------------------------------------------------------------------------ +// Wait for a received message +void waitMessage( void ) +{ + while (1) { + receiveMsgHandler(0); // blocked until new message + } +} + +//------------------------------------------------------------------------------ +// Heartbeat Manager (sending and receiving) and test SDO timeout +void heartbeatAndSDO(void) +{ + while (1) { + heartbeatMGR(); + // Check if some SDO response are missing + scanSDOtimeout(); + // Sleep 10 ms + usleep(10000); + } +} + +/*********************************************************************/ +void preOperational( void ) +{ + /* Init some variables */ + canopenErrNB = 0; + canopenErrVAL = 0; +} + + +/********************************************************************/ +void operational( void ) +{ + /* read systeme date */ + tme = time (&tme); + ptrdate = gmtime(&tme); + date = *ptrdate; + + /* Update the dictionary */ + day = date.tm_mday; + hours = date.tm_hour; + minutes = date.tm_min; + seconds = date.tm_sec; + + + if ( date_prec.tm_min != date.tm_min ) { + MSG_WAR(0x3F00, "event : minutes change -> node decides to send it. Value : ", date.tm_min); + sendPDOevent( 0, &minutes ); + date_prec = date; + } + if (canopenErrNB == 0) + sendingError = 0; + + if (lastSecond != seconds) { + MSG_WAR (0x3F50, "Seconds = ", seconds); + if ((seconds == 50) && (sendingError == 0)) + { + MSG_ERR(0x1F55, "DEMO of ERROR. Sent by PDO. Value : ", 0xABCD); + sendingError = 1; + } + + if (canopenErrNB) { + MSG_WAR(0x3F56, "ERROR nb : ", canopenErrNB); + } + lastSecond = seconds; + + } +} + + +/*****************************************************************************/ +void stopped( void ) +{ +} + +void help() +{ + printf("**************************************************************\n"); + printf("* AppliSlave *\n"); + printf("* [-b b] *\n"); + printf("* *\n"); + printf("* b : bus [default 1] *\n"); + printf("* *\n"); + printf("* This exemple run AppliSlave on bus 0 *\n"); + printf("* AppliSlave -b 0 *\n"); + printf("* *\n"); + printf("**************************************************************\n"); +} + +/****************************************************************************/ +/*************************** MAIN *****************************************/ +/****************************************************************************/ +int main(int argc,char **argv) +{ + + HANDLE ok; + UNS32 * pSize; + UNS32 size; + pSize = &size; + char c; + extern char *optarg; + + while ((c = getopt(argc, argv, "-b:")) != EOF) + { + switch(c) + { + case 'b' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + board.busname = optarg; + break; + default: + help(); + exit(1); + } + } + + // Global initialization before launching the threads. (also done in init mode. + /* Defining the node Id */ + setNodeId(0x05); + MSG_WAR(0x3F06, "My node ID is : ", getNodeId()); + initCANopenMain(); + initTimer( ); + heartbeatInit(); + initResetMode(); + + /* Launch the thread to receive the messages */ + pthread_create( &threadRcvMsg, NULL, (void *)&waitMessage, NULL); + /* Launch the thread to manage the heartbeat */ + pthread_create( &threadHeartbeatAndSDO, NULL, (void *)&heartbeatAndSDO, NULL); + + /* open the communication with the board */ + ok = f_can_open(& board); + if (ok == NULL) { + MSG_ERR(0x1F02,"Unable to open the board", 0); + MSG_ERR(0x1F03,"Edit includeMakefileLinux to verify that the application is configured for the good board", 0); + exit (-1); + } + else { + MSG_WAR(0x3F03, "Board 1 opened ", 0); + /* slave's state initialization */ + setState(Initialisation); + lastState = Unknown_state; + + + while(1) { /* slave's state machine */ + switch( getState() ) { + case Initialisation: + if (lastState != getState()) + MSG_WAR(0X3F05, "I am in INITIALISATION mode ", 0); + /* Defining the node Id */ + setNodeId(0x05); + MSG_WAR(0x3F06, "My node ID is : ", getNodeId()); + // Node identity ? + { + UNS8 *data; + UNS8 size; + UNS8 dataType; + // Manufacturer Device name (default = empty string) + getODentry(0x1008, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Hardware version. (default = compilation. date) + getODentry(0x1009, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + // Manufacturer Software version. (default = compilation. time) + getODentry(0x100A, 0x0, (void **)&data, &size, &dataType, 0); + MSG_WAR(0x3F09, data, 0); + } + + initCANopenMain(); + initTimer( ); + heartbeatInit(); + initResetMode(); + /* the slave send an NMT trame to say to the master + that it is going to enter into operational state + In fact, you must send the boot-up when you are in + operational mode ! + */ + + /* change automatically into pre_operational state */ + lastState = getState(); + setState(Pre_operational); + break; + + case Pre_operational: + if (lastState != getState()) + { + MSG_WAR(0X3F11, "I am in PRE_OPERATIONAL mode ", 0); + // Some stuff to do when the node enter in pre-operational mode + initPreOperationalMode(); + } + if (lastState == Initialisation) + slaveSendBootUp(0); + lastState = getState(); + preOperational( ); + break; + + case Operational: + if (lastState != getState()) + MSG_WAR(0X3F12, "I am in OPERATIONAL mode ", 0); + lastState = getState(); + operational( ); + break; + + case Stopped: + if (lastState != getState()) + MSG_WAR(0X3F13, "I am in STOPPED mode", 0); + lastState = getState(); + stopped( ); + break; + }//end switch case + // Sleep 10 ms + usleep(10000); + }//end while + }//end else + + + return 0; +} + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_Linux/objdict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_Linux/objdict.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,621 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +#include +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "pdo.h" +#include "sdo.h" +#include "sync.h" +#include "lifegrd.h" +#include "nmtSlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ + + + +/*// Copy and uncomment this code to your main file +extern UNS8 seconds; // Mapped at index 0x2000, subindex 0x01 +extern UNS32 minutes; // Mapped at index 0x2000, subindex 0x02 +extern UNS8 hours; // Mapped at index 0x2000, subindex 0x03 +extern UNS8 day; // Mapped at index 0x2000, subindex 0x04 +extern UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x00 +extern UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x00 +extern UNS8 strTest[10]; // Mapped at index 0x6002, subindex 0x00 + +// END copy to main file +*/ + +UNS8 seconds; // Mapped at index 0x2000, subindex 0x01 +UNS32 minutes; // Mapped at index 0x2000, subindex 0x02 +UNS8 hours; // Mapped at index 0x2000, subindex 0x03 +UNS8 day; // Mapped at index 0x2000, subindex 0x04 +UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x00 +UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x00 +UNS8 strTest[10]; // Mapped at index 0x6002, subindex 0x00 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + + + +UNS32 valueRangeTest (UNS8 typeValue, UNS32 unsValue, REAL32 realValue) +{ + return 0; +} + + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* Computed by strNode */ +/* node_id default value. + This default value is deprecated. + You should always overwrite this by using the function setNodeId(UNS8 nodeId) in your C code. +*/ +#define NODE_ID 0x01 +UNS8 bDeviceNodeId = NODE_ID; + + +//*****************************************************************************/ +/* Computed by strStartDico */ + +/* Array of message processing information */ +/* Should not be modified */ +volatile const proceed_info proceed_infos[] = { + {NMT, "NMT", proceedNMTstateChange}, + {SYNC, "SYNC", proceedSYNC}, + {TIME_STAMP, "TStmp", NULL}, + {PDO1tx, "PDO1t", proceedPDO}, + {PDO1rx, "PDO1r", proceedPDO}, + {PDO2tx, "PDO2t", proceedPDO}, + {PDO2rx, "PDO2r", proceedPDO}, + {PDO3tx, "PDO3t", proceedPDO}, + {PDO3rx, "PDO3r", proceedPDO}, + {PDO4tx, "PDO4t", proceedPDO}, + {PDO4rx, "PDO4r", proceedPDO}, + {SDOtx, "SDOt", proceedSDO}, + {SDOrx, "SDOr", proceedSDO}, + {0xD, "Unkw", NULL}, + {NODE_GUARD, "NGrd", proceedNMTerror}, + {0xF, "Unkw", NULL} +}; + + // Macros definition + +/* Beware : +index *must* be writen 4 numbers in hexa +sub_index *must* be writen 2 numbers in hexa +size_variable_in_UNS8 *must* be writen 2 numbers in hexa +*/ +#define PDO_MAP(index, sub_index, size_variable_in_bits)\ +0x ## index ## sub_index ## size_variable_in_bits + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// Make your change, depending of your application + + +/* index 0x1000 : Device type. + You have to change the value below, so + it fits your canopen-slave-module */ + + /* Not used, so, should not be modified */ + + UNS32 obj1000 = 0; + subindex Index1000[] = + { + { RO, uint32, sizeof(UNS32), (void*)&obj1000 } + }; + +/* index 0x1001 : Error register. + Change the entries to fit your application + Not used, so, should not be modified */ + /*const*/ UNS8 obj1001 = 0x0; + /*const*/ subindex Index1001[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1001 } + }; + +/* index 0x1005 : COB_ID SYNC */ + /* Should not be modified */ + UNS32 obj1005 = 0x00000080; // bit 30 = 1 : device can generate a SYNC message + // Beware, it is over written when the node + // enters in reset mode + // See initResetMode() in init.c + /*const*/ subindex Index1005[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1005 } + }; + +/* index 0x1006 : SYNC period */ + // For producing the SYNC signal every n micro-seconds. + // Put O to not producing SYNC + /*const*/ UNS32 obj1006 = 0x0; + // Default 0 to not produce SYNC // + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + /*const*/ subindex Index1006[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1006 } + }; + +/* index 0x1007 : Synchronous Window Length + Seems to be needed by DS401 to generate the SYNC signal ! */ + /*const*/ UNS32 obj1007 = 0x0; /* Default 0 */ + /*const*/ subindex Index1007[] = + { + { RW, uint32, sizeof(UNS32), (void*)&obj1007 } + }; + +/* index 0x1008 : Manufacturer device name */ + UNS8 obj1008[] = "Appli_Slave_Linux"; /* Default 0 */ + subindex Index1008[] = + { + { RO, uint32, sizeof(obj1008), (void*)&obj1008 } + }; + +/* index 0x1009 : Manufacturer hardware version */ + UNS8 obj1009[] = __DATE__; /* Default 0 */ + subindex Index1009[] = + { + { RO, uint32, sizeof(obj1009), (void*)&obj1009 } + }; + +/* index 0x100A : Manufacturer software version */ + UNS8 obj100A[] = __TIME__; /* Default 0 */ + subindex Index100A[] = + { + { RO, uint32, sizeof(obj100A), (void*)&obj100A} + }; + +/* index 0x1016 : HeartBeat consumers + The nodes which can send a heartbeat */ + static UNS32 obj1016[] = {// Consumer time for each node + 0x00000000}; // Format 0x00NNTTTT (N=Node T=time in ms) + + static UNS8 obj1016_cnt = 1; // 1 nodes could send me + // their heartbeat. + subindex Index1016[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1016_cnt }, + { RW, uint32, sizeof(UNS32), (void*)&obj1016[0] } + }; + +/* index 0x1017 : Heartbeat producer + Every HBProducerTime, the node sends its heartbeat */ + static UNS16 obj1017 = 0; //HBProducerTime in ms. If 0 : not activated + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + subindex Index1017[] = + { + { RW, uint16, sizeof(UNS16), &obj1017 } + }; + +/* index 0x1018 : Identity object */ + /** index 1018: identify object. Adjust the entries for your node/company + */ + /* Values can be modified */ + + s_identity obj1018 = + { + 4, // number of supported entries + 0, // Vendor-ID (given by the can-cia) + 0, // Product Code + 0, // Revision number + 0 // serial number + }; + + subindex Index1018[] = + { + { RO, uint8, sizeof(UNS8), (void*)&obj1018.count }, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.vendor_id}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.product_code}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.revision_number}, + { RO, uint32, sizeof(UNS32), (void*)&obj1018.serial_number} + }; + +/* index 0x1200 : The SDO Server parameters */ + /* BEWARE You cannot define more than one SDO server */ + /* The values should not be modified here, + but can be changed at runtime */ + // Beware that the default values that you could put here + // will be over written at the initialisation of the node. + // See setNodeId() in init.c + static s_sdo_parameter obj1200 = + { 3, // Number of entries. Always 3 for the SDO + 0x600 + NODE_ID, // The cob_id transmited in CAN msg to the server + 0x580 + NODE_ID, // The cob_id received in CAN msg from the server + NODE_ID // The node id of the client. Should not be modified + }; + static subindex Index1200[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1200.count }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_client }, + { RO, uint32, sizeof( UNS32), (void*)&obj1200.cob_id_server }, + { RW, uint8, sizeof( UNS8), (void*)&obj1200.node_id } + }; + +/* index 0x1280 : SDO client parameter */ + static s_sdo_parameter obj1280 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x0 // server NodeId + }; + static subindex Index1280[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1280.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1280.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1280.node_id } + }; + +/* index 0x1400 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1400 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1400[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1400.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1400.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1400.type }, + }; + +/* index 0x1401 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1401 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1401[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1401.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1401.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1401.type }, + }; + +/* index 0x1402 : PDO receive communication parameter */ + static s_pdo_communication_parameter obj1402 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1402[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1402.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1402.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1402.type }, + }; + +/* index 0x1600 : PDO receive mapping parameter of PDO communication index 0x1400 */ + static UNS8 obj1600_cnt = 0; // Number of mapped variables + static UNS32 obj1600_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1600[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1600_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1600_mappedVar[7]} + }; + +/* index 0x1601 : PDO receive mapping parameter of PDO communication index 0x1401 */ + static UNS8 obj1601_cnt = 0; // Number of mapped variables + static UNS32 obj1601_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1601[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1601_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1601_mappedVar[7]} + }; + +/* index 0x1602 : PDO receive mapping parameter of PDO communication index 0x1402 */ + static UNS8 obj1602_cnt = 0; // Number of mapped variables + static UNS32 obj1602_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1602[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1602_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1602_mappedVar[7]} + }; + +/* index 0x1800 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1800 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1800[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1800.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1800.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1800.type }, + }; + +/* index 0x1801 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1801 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1801[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1801.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1801.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1801.type }, + }; + +/* index 0x1802 : PDO transmit communication parameter */ + static s_pdo_communication_parameter obj1802 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + static subindex Index1802[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&obj1802.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&obj1802.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&obj1802.type }, + }; + +/* index 0x1A00 : PDO transmit mapping parameter of PDO communication index 0x1800 */ + static UNS8 obj1A00_cnt = 0; // Number of mapped variables + static UNS32 obj1A00_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A00[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A00_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A00_mappedVar[7]} + }; + +/* index 0x1A01 : PDO transmit mapping parameter of PDO communication index 0x1801 */ + static UNS8 obj1A01_cnt = 0; // Number of mapped variables + static UNS32 obj1A01_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A01[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A01_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A01_mappedVar[7]} + }; + +/* index 0x1A02 : PDO transmit mapping parameter of PDO communication index 0x1802 */ + static UNS8 obj1A02_cnt = 0; // Number of mapped variables + static UNS32 obj1A02_mappedVar[] = { + // Example to map a variable of 16 bits defined at index 0x6035, subindex 0x12 : + // PDO_MAP(6035,12,16) + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00), + PDO_MAP(0000, 00, 00) + }; + subindex Index1A02[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&obj1A02_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&obj1A02_mappedVar[7]} + }; + + +/* index 0x2000 : Mapped variable */ + static UNS8 highestSubIndex_2000 = 4; // number of subindex - 1 + subindex Index2000[] = + { + { RO, uint8, sizeof (UNS8), (void*)&highestSubIndex_2000 }, + { RW, uint8, sizeof (UNS8), (void*)&seconds }, + { RW, uint32, sizeof (UNS32), (void*)&minutes }, + { RW, uint8, sizeof (UNS8), (void*)&hours }, + { RW, uint8, sizeof (UNS8), (void*)&day } + }; + +/* index 0x6000 : Mapped variable */ + subindex Index6000[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB } + }; + +/* index 0x6001 : Mapped variable */ + subindex Index6001[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL } + }; + +/* index 0x6002 : Mapped variable */ + subindex Index6002[] = + { + { RW, visible_string, sizeof (strTest), (void*)&strTest } + }; + +const indextable objdict[] = +{ + DeclareIndexTableEntry(Index1000, 0x1000), + DeclareIndexTableEntry(Index1001, 0x1001), + DeclareIndexTableEntry(Index1005, 0x1005), + DeclareIndexTableEntry(Index1006, 0x1006), + DeclareIndexTableEntry(Index1007, 0x1007), + DeclareIndexTableEntry(Index1008, 0x1008), + DeclareIndexTableEntry(Index1009, 0x1009), + DeclareIndexTableEntry(Index100A, 0x100A), + DeclareIndexTableEntry(Index1016, 0x1016), + DeclareIndexTableEntry(Index1017, 0x1017), + DeclareIndexTableEntry(Index1018, 0x1018), + DeclareIndexTableEntry(Index1200, 0x1200), + DeclareIndexTableEntry(Index1280, 0x1280), + DeclareIndexTableEntry(Index1400, 0x1400), + DeclareIndexTableEntry(Index1401, 0x1401), + DeclareIndexTableEntry(Index1402, 0x1402), + DeclareIndexTableEntry(Index1600, 0x1600), + DeclareIndexTableEntry(Index1601, 0x1601), + DeclareIndexTableEntry(Index1602, 0x1602), + DeclareIndexTableEntry(Index1800, 0x1800), + DeclareIndexTableEntry(Index1801, 0x1801), + DeclareIndexTableEntry(Index1802, 0x1802), + DeclareIndexTableEntry(Index1A00, 0x1A00), + DeclareIndexTableEntry(Index1A01, 0x1A01), + DeclareIndexTableEntry(Index1A02, 0x1A02), + DeclareIndexTableEntry(Index2000, 0x2000), + DeclareIndexTableEntry(Index6000, 0x6000), + DeclareIndexTableEntry(Index6001, 0x6001), + DeclareIndexTableEntry(Index6002, 0x6002), +}; + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 count_sync[1] = {0, }; + +UNS16 firstIndex (enum e_first_object object, UNS16 *lastIndex) +{ + switch (object) { + case FIRST_SDO_SERVER : + *lastIndex = 11; + return 11; + case FIRST_SDO_CLIENT : + *lastIndex = 12; + return 12; + case FIRST_PDO_RCV : + *lastIndex = 15; + return 13; + case FIRST_PDO_RCV_MAP : + *lastIndex = 18; + return 16; + case FIRST_PDO_TRS : + *lastIndex = 21; + return 19; + case FIRST_PDO_TRS_MAP : + *lastIndex = 24; + return 22; + } + *lastIndex = 0; + return 0; +} + +UNS16 getObjdictSize (void) +{ + return sizeof(objdict)/sizeof(objdict[0]); +} diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_Linux/objdict.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_Linux/objdict.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,146 @@ + + + + +CANOpen object dictionary Configuration + + + +

Object dictionary for Node :

+

+Linux_slaveslave +

+

Overview

+

+ How to make the object dictionary of the node ? + First, use Jaxe (command run_objdict) to edit an xml description file +of the dictionary : objdict.xml. +Then, run the php program : makeobjetdict.php. You can launch php through a web browser +if you have installed a server, or, on Linux, you can launch php in command line : +php-cgi makeobjetdict.php. It compute the file objdict.c. Link it to + your project. +
Note : To define the node id, use in your code the function setNodeId(UNS8 nodeId) +

+

+ Then the node can be connected to the network. The master must configure it + by sending SDO. It will write values in its index, subindex. What to configure ? +

    +
  • Receiving heartbeats from which nodes ? Waiting time ?
  • +
  • Emitting heartbeats or not ? time btw 2 heartbeats ?
  • +
  • Defining a cobId for each PDO receive and transmit
  • +
  • How to transmit a PDO ? on synchro ? request ? event ?
  • +
  • What variables to put in each PDO receive and transmit ?
  • +
  • ...
  • +
+

+ To avoid configuring the node at the connection, you can put the values directly +in the dictionary objdict.c. But it is boring and unsafe because it is too easy to make +a mistake ! + + +

Number of heartbeat consumers : + 1 +

+

This means that the node can expect heartbeats sent by 1 nodes.

+

Number of SDO clients : + 1 +

+

Usualy, a slave node does not have the use of SDO clients, but + today, for the library, you must define one. The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Maximum objects in a PDO (receive or transmit) : + 8 +

+

This is defining how many variables can be transmited in a + PDO. (maximum is 8).

+

For each variable, a table is created, so if you have less room + in memory, put a value under 8.

+

Mapped variables and tables

+

3 tables are defined for the mapping, starting at index 0x2000, 0x6000 and 0x6200. + You must start the mapping at the beginning of one of a table, without holes in index +or subindex. For example, variables in 0x2000 and 0x2001 is ok, but variables in 0x2000 and 0x2002 is not allowed, because you are loosing room in memory. It is the same for the subindex. +

+

+ The access of the variable is by default "rw" (read-write) or "ro" (read-only). A read-only variable cannot be mapped in a PDO receive. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + +
Var NameBitsIndexSub-indexaccess
seconds80x20000x1rw
minutes80x20000x02rw
hours80x20000x3rw
day80x20000x4rw
canopenErrNB320x60000x0rw
canopenErrVAL320x60010x0rw
Table NameBitsIndexSub-indexaccess
+ + diff -r 000000000000 -r 4472ee7c6c3e examples/AppliSlave_Linux/objdict.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/AppliSlave_Linux/objdict.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,56 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +TARGET = SUB_TARGET + +all: +ifeq ($(TARGET),hc12) + $(MAKE) -C AppliMaster_HCS12 $@ + $(MAKE) -C AppliSlave_HCS12 $@ + $(MAKE) -C gene_SYNC_HCS12 $@ +endif +ifeq ($(TARGET),generic) + $(MAKE) -C TestMasterSlave $@ +endif + +clean: +ifeq ($(TARGET),hc12) + $(MAKE) -C AppliMaster_HCS12 $@ + $(MAKE) -C AppliSlave_HCS12 $@ + $(MAKE) -C gene_SYNC_HCS12 $@ +endif +ifeq ($(TARGET),generic) + $(MAKE) -C TestMasterSlave $@ +endif + +mrproper: clean +ifeq ($(TARGET),hc12) + $(MAKE) -C AppliMaster_HCS12 $@ + $(MAKE) -C AppliSlave_HCS12 $@ + $(MAKE) -C gene_SYNC_HCS12 $@ +endif +ifeq ($(TARGET),generic) + $(MAKE) -C TestMasterSlave $@ +endif + + diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,3 @@ +Makefile +TestMasterSlave +result.txt diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,65 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +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) + +MASTER_OBJS = TestSlave.o TestMaster.o TestMasterSlave.o Slave.o Master.o + +OBJS = $(MASTER_OBJS) ../../drivers/$(TARGET)/libcanfestival_$(TARGET).a ../../src/libcanfestival.a + +ifeq ($(TIMERS_DRIVER),timers_xeno) + PROGDEFINES = -DUSE_XENO +endif + +all: TestMasterSlave + +../../drivers/$(TARGET)/libcanfestival_$(TARGET).a: + $(MAKE) -C ../../drivers/$(TARGET) libcanfestival_$(TARGET).a + + +TestMasterSlave: $(OBJS) + $(CC) $(CFLAGS) $(PROG_CFLAGS) $(EXE_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +clean: + -rm $(MASTER_OBJS) + -rm TestMasterSlave + +mrproper: clean + + + diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/Master.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/Master.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,132 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Master.h" +#include "Slave.h" +#include "TestMasterSlave.h" + +/*****************************************************************************/ +void TestMaster_heartbeatError(UNS8 heartbeatID) +{ + eprintf("TestMaster_heartbeatError %d\n", heartbeatID); +} + +/*****************************************************************************/ +void TestMaster_SDOtimeoutError (UNS8 line) +{ + eprintf("TestMaster_SDOtimeoutError %d\n", line); +} + +/*****************************************************************************/ +// CanSend store message in a FIFO, for Slave +UNS8 TestMaster_canSend(Message *m) +{ + eprintf("M->S "); + print_message(m); + canSend(MasterCanHandle, m); + return 0; +} + +void TestMaster_initialisation() +{ + eprintf("TestMaster_initialisation\n"); +} + +void TestMaster_preOperational() +{ + eprintf("TestMaster_preOperational\n"); +} + +void TestMaster_operational() +{ + eprintf("TestMaster_operational\n"); +} + +void TestMaster_stopped() +{ + eprintf("TestMaster_stopped\n"); +} + +void TestMaster_post_sync() +{ + eprintf("TestMaster_post_sync\n"); + eprintf("Master: %d %d %d %d\n",MasterMap1, MasterMap2, MasterMap3, MasterMap4); +} + +char query_result = 0; +char waiting_answer = 0; + +void TestMaster_post_TPDO() +{ + eprintf("TestMaster_post_TPDO\n"); + +// { +// char zero = 0; +// if(MasterMap4 > 0x80){ +// writeNetworkDict ( +// &TestMaster_Data, +// TestSlave_Data->bDeviceNodeId, +// 0x2002, +// 0x00, +// 1, +// 0, +// &zero); +// } +// } + + if(waiting_answer){ + UNS32 abortCode; + UNS8 size; + switch(getReadResultNetworkDict ( + &TestMaster_Data, + *TestSlave_Data.bDeviceNodeId, + &query_result, + &size, + &abortCode)) + { + case SDO_FINISHED: + /* Do something with result here !!*/ + eprintf("Got SDO answer (0x2002, 0x00), %d %d\n",query_result,size); + case SDO_ABORTED_RCV: + case SDO_ABORTED_INTERNAL: + case SDO_RESET: + waiting_answer = 0; + closeSDOtransfer( + &TestMaster_Data, + *TestSlave_Data. bDeviceNodeId, + SDO_CLIENT); + break; + case SDO_DOWNLOAD_IN_PROGRESS: + case SDO_UPLOAD_IN_PROGRESS: + break; + } + }else if(MasterMap1 % 10 == 0){ + readNetworkDict ( + &TestMaster_Data, + *TestSlave_Data.bDeviceNodeId, + 0x2002, + 0x00, + 0); + waiting_answer = 1; + } + +} diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/Master.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/Master.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +#include "TestMaster.h" diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/Slave.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/Slave.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,81 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "Slave.h" +#include "Master.h" +#include "TestMasterSlave.h" + +/*****************************************************************************/ +void TestSlave_heartbeatError(UNS8 heartbeatID) +{ + eprintf("TestSlave_heartbeatError %d\n", heartbeatID); +} + +/*****************************************************************************/ +void TestSlave_SDOtimeoutError (UNS8 line) +{ + eprintf("TestSlave_SDOtimeoutError %d\n", line); +} + +/*****************************************************************************/ +UNS8 TestSlave_canSend(Message *m) +{ + eprintf("S->M "); + print_message(m); + canSend(SlaveCanHandle, m); + return 0; +} + +void TestSlave_initialisation() +{ + eprintf("TestSlave_initialisation\n"); +} + +void TestSlave_preOperational() +{ + eprintf("TestSlave_preOperational\n"); +} + +void TestSlave_operational() +{ + eprintf("TestSlave_operational\n"); +} + +void TestSlave_stopped() +{ + eprintf("TestSlave_stopped\n"); +} + +void TestSlave_post_sync() +{ + eprintf("TestSlave_post_sync\n"); + SlaveMap1+=1; + SlaveMap2+=2; + SlaveMap3+=3; + SlaveMap4+=4; + eprintf("Slave: %d %d %d %d\n",SlaveMap1, SlaveMap2, SlaveMap3, SlaveMap4); +} + +void TestSlave_post_TPDO() +{ + eprintf("TestSlave_post_TPDO\n"); +} diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/Slave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/Slave.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +#include "TestSlave.h" diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestMaster.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestMaster.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,306 @@ +/* +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 generated by gen_cfile.py. Should not be modified. */ + +#include "TestMaster.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ +UNS8 MasterMap1 = 0x0; // Mapped at index 0x2000, subindex 0x00 +UNS8 MasterMap2 = 0x0; // Mapped at index 0x2001, subindex 0x00 +UNS8 MasterMap3 = 0x0; // Mapped at index 0x2002, subindex 0x00 +UNS8 MasterMap4 = 0x0; // Mapped at index 0x2003, subindex 0x00 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + +UNS32 TestMaster_valueRangeTest (UNS8 typeValue, void * value) +{ + switch (typeValue) { + } + return 0; +} + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* node_id default value.*/ +UNS8 TestMaster_bDeviceNodeId = 0x00; + +//*****************************************************************************/ +/* Array of message processing information */ + +const UNS8 TestMaster_iam_a_slave = 0; + +TIMER_HANDLE TestMaster_heartBeatTimers[1] = {TIMER_NONE,}; + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + +/* index 0x1000 : Device Type. */ + UNS32 TestMaster_obj1000 = 0x12D; + subindex TestMaster_Index1000[] = + { + { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1000 } + }; + +/* index 0x1001 : Error Register. */ + UNS8 TestMaster_obj1001 = 0x0; + subindex TestMaster_Index1001[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_obj1001 } + }; + +/* index 0x1005 : SYNC COB ID. */ + UNS32 TestMaster_obj1005 = 0x40000080; + ODCallback_t TestMaster_Index1005_callbacks[] = + { + NULL, + }; + subindex TestMaster_Index1005[] = + { + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1005 } + }; + +/* index 0x1006 : Communication / Cycle Period. */ + UNS32 TestMaster_obj1006 = 0xC350; + ODCallback_t TestMaster_Index1006_callbacks[] = + { + NULL, + }; + subindex TestMaster_Index1006[] = + { + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1006 } + }; + +/* index 0x1016 : Consumer Heartbeat Time. */ + UNS8 TestMaster_highestSubIndex_obj1016 = 1; // number of subindex - 1 + UNS32 TestMaster_obj1016[] = + { + 133122 + }; + subindex TestMaster_Index1016[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1016 }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1016[0] } + }; + +/* index 0x1017 : Producer Heartbeat Time */ + UNS16 TestMaster_obj1017 = 0; + +/* index 0x1018 : Identity. */ + UNS8 TestMaster_highestSubIndex_obj1018 = 4; // number of subindex - 1 + UNS32 TestMaster_obj1018_Vendor_ID = 0x0; + UNS32 TestMaster_obj1018_Product_Code = 0x0; + UNS32 TestMaster_obj1018_Revision_Number = 0x0; + UNS32 TestMaster_obj1018_Serial_Number = 0x0; + subindex TestMaster_Index1018[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1018 }, + { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Vendor_ID }, + { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Product_Code }, + { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Revision_Number }, + { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Serial_Number } + }; + +/* index 0x1280 : Client SDO 1 Parameter. */ + UNS8 TestMaster_highestSubIndex_obj1280 = 3; // number of subindex - 1 + UNS32 TestMaster_obj1280_COB_ID_Client_to_Server_Transmit_SDO = 0x602; + UNS32 TestMaster_obj1280_COB_ID_Server_to_Client_Receive_SDO = 0x582; + UNS32 TestMaster_obj1280_Node_ID_of_the_SDO_Server = 0x2; + subindex TestMaster_Index1280[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1280 }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1280_COB_ID_Client_to_Server_Transmit_SDO }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1280_COB_ID_Server_to_Client_Receive_SDO }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1280_Node_ID_of_the_SDO_Server } + }; + +/* index 0x1400 : Receive PDO 1 Parameter. */ + UNS8 TestMaster_highestSubIndex_obj1400 = 5; // number of subindex - 1 + UNS32 TestMaster_obj1400_COB_ID_used_by_PDO = 0x182; + UNS8 TestMaster_obj1400_Transmission_Type = 0x1; + UNS16 TestMaster_obj1400_Inhibit_Time = 0x0; + UNS16 TestMaster_obj1400_Compatibility_Entry = 0x0; + UNS16 TestMaster_obj1400_Event_Timer = 0x0; + subindex TestMaster_Index1400[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1400 }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1400_COB_ID_used_by_PDO }, + { RW, uint8, sizeof (UNS8), (void*)&TestMaster_obj1400_Transmission_Type }, + { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1400_Inhibit_Time }, + { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1400_Compatibility_Entry }, + { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1400_Event_Timer } + }; + +/* index 0x1401 : Receive PDO 2 Parameter. */ + UNS8 TestMaster_highestSubIndex_obj1401 = 5; // number of subindex - 1 + UNS32 TestMaster_obj1401_COB_ID_used_by_PDO = 0x282; + UNS8 TestMaster_obj1401_Transmission_Type = 0x1; + UNS16 TestMaster_obj1401_Inhibit_Time = 0x0; + UNS16 TestMaster_obj1401_Compatibility_Entry = 0x0; + UNS16 TestMaster_obj1401_Event_Timer = 0x0; + subindex TestMaster_Index1401[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1401 }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1401_COB_ID_used_by_PDO }, + { RW, uint8, sizeof (UNS8), (void*)&TestMaster_obj1401_Transmission_Type }, + { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1401_Inhibit_Time }, + { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1401_Compatibility_Entry }, + { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1401_Event_Timer } + }; + +/* index 0x1600 : Receive PDO 1 Mapping. */ + UNS8 TestMaster_highestSubIndex_obj1600 = 2; // number of subindex - 1 + UNS32 TestMaster_obj1600[] = + { + 536870920, + 536936456 + }; + subindex TestMaster_Index1600[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1600 }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1600[0] }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1600[1] } + }; + +/* index 0x1601 : Receive PDO 2 Mapping. */ + UNS8 TestMaster_highestSubIndex_obj1601 = 2; // number of subindex - 1 + UNS32 TestMaster_obj1601[] = + { + 537001992, + 537067528 + }; + subindex TestMaster_Index1601[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1601 }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1601[0] }, + { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1601[1] } + }; + +/* index 0x2000 : Mapped variable MasterMap1 */ + ODCallback_t MasterMap1_callbacks[] = + { + NULL, + }; + subindex TestMaster_Index2000[] = + { + { RW, uint8, sizeof (UNS8), (void*)&MasterMap1 } + }; + +/* index 0x2001 : Mapped variable MasterMap2 */ + subindex TestMaster_Index2001[] = + { + { RW, uint8, sizeof (UNS8), (void*)&MasterMap2 } + }; + +/* index 0x2002 : Mapped variable MasterMap3 */ + subindex TestMaster_Index2002[] = + { + { RW, uint8, sizeof (UNS8), (void*)&MasterMap3 } + }; + +/* index 0x2003 : Mapped variable MasterMap4 */ + subindex TestMaster_Index2003[] = + { + { RW, uint8, sizeof (UNS8), (void*)&MasterMap4 } + }; + +const indextable TestMaster_objdict[] = +{ + { (subindex*)TestMaster_Index1000,sizeof(TestMaster_Index1000)/sizeof(TestMaster_Index1000[0]), 0x1000}, + { (subindex*)TestMaster_Index1001,sizeof(TestMaster_Index1001)/sizeof(TestMaster_Index1001[0]), 0x1001}, + { (subindex*)TestMaster_Index1005,sizeof(TestMaster_Index1005)/sizeof(TestMaster_Index1005[0]), 0x1005}, + { (subindex*)TestMaster_Index1006,sizeof(TestMaster_Index1006)/sizeof(TestMaster_Index1006[0]), 0x1006}, + { (subindex*)TestMaster_Index1016,sizeof(TestMaster_Index1016)/sizeof(TestMaster_Index1016[0]), 0x1016}, + { (subindex*)TestMaster_Index1018,sizeof(TestMaster_Index1018)/sizeof(TestMaster_Index1018[0]), 0x1018}, + { (subindex*)TestMaster_Index1280,sizeof(TestMaster_Index1280)/sizeof(TestMaster_Index1280[0]), 0x1280}, + { (subindex*)TestMaster_Index1400,sizeof(TestMaster_Index1400)/sizeof(TestMaster_Index1400[0]), 0x1400}, + { (subindex*)TestMaster_Index1401,sizeof(TestMaster_Index1401)/sizeof(TestMaster_Index1401[0]), 0x1401}, + { (subindex*)TestMaster_Index1600,sizeof(TestMaster_Index1600)/sizeof(TestMaster_Index1600[0]), 0x1600}, + { (subindex*)TestMaster_Index1601,sizeof(TestMaster_Index1601)/sizeof(TestMaster_Index1601[0]), 0x1601}, + { (subindex*)TestMaster_Index2000,sizeof(TestMaster_Index2000)/sizeof(TestMaster_Index2000[0]), 0x2000}, + { (subindex*)TestMaster_Index2001,sizeof(TestMaster_Index2001)/sizeof(TestMaster_Index2001[0]), 0x2001}, + { (subindex*)TestMaster_Index2002,sizeof(TestMaster_Index2002)/sizeof(TestMaster_Index2002[0]), 0x2002}, + { (subindex*)TestMaster_Index2003,sizeof(TestMaster_Index2003)/sizeof(TestMaster_Index2003[0]), 0x2003}, +}; + +const indextable * TestMaster_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks) +{ + int i; + switch(wIndex){ + case 0x1000: i = 0; *callbacks = NULL; break; + case 0x1001: i = 1; *callbacks = NULL; break; + case 0x1005: i = 2; *callbacks = TestMaster_Index1005_callbacks; break; + case 0x1006: i = 3; *callbacks = TestMaster_Index1006_callbacks; break; + case 0x1016: i = 4; *callbacks = NULL; break; + case 0x1018: i = 5; *callbacks = NULL; break; + case 0x1280: i = 6; *callbacks = NULL; break; + case 0x1400: i = 7; *callbacks = NULL; break; + case 0x1401: i = 8; *callbacks = NULL; break; + case 0x1600: i = 9; *callbacks = NULL; break; + case 0x1601: i = 10; *callbacks = NULL; break; + case 0x2000: i = 11; *callbacks = MasterMap1_callbacks; break; + case 0x2001: i = 12; *callbacks = NULL; break; + case 0x2002: i = 13; *callbacks = NULL; break; + case 0x2003: i = 14; *callbacks = NULL; break; + default: + *errorCode = OD_NO_SUCH_OBJECT; + return NULL; + } + *errorCode = OD_SUCCESSFUL; + return &TestMaster_objdict[i]; +} + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 TestMaster_count_sync[1] = {0,}; + +quick_index TestMaster_firstIndex = { + SDO_SVR : 0, + SDO_CLT : 6, + PDO_RCV : 7, + PDO_RCV_MAP : 9, + PDO_TRS : 0, + PDO_TRS_MAP : 0 +}; + +quick_index TestMaster_lastIndex = { + SDO_SVR : 0, + SDO_CLT : 6, + PDO_RCV : 8, + PDO_RCV_MAP : 10, + PDO_TRS : 0, + PDO_TRS_MAP : 0 +}; + +UNS16 TestMaster_ObjdictSize = sizeof(TestMaster_objdict)/sizeof(TestMaster_objdict[0]); + +CO_Data TestMaster_Data = CANOPEN_NODE_DATA_INITIALIZER(TestMaster); + diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestMaster.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestMaster.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,48 @@ +/* +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 generated by gen_cfile.py. Should not be modified. */ + +#include "data.h" + +// prototypes of function to be filled by app +void TestMaster_SDOtimeoutError(UNS8 line); +void TestMaster_heartbeatError(UNS8); + +UNS8 TestMaster_canSend(Message *); + +void TestMaster_initialisation(); +void TestMaster_preOperational(); +void TestMaster_operational(); +void TestMaster_stopped(); + +void TestMaster_post_sync(); +void TestMaster_post_TPDO(); + +// Master node data struct +extern CO_Data TestMaster_Data; + +extern UNS8 MasterMap1; // Mapped at index 0x2000, subindex 0x00 +extern ODCallback_t MasterMap1_callbacks[]; // Callbacks of index0x2000 +extern UNS8 MasterMap2; // Mapped at index 0x2001, subindex 0x00 +extern UNS8 MasterMap3; // Mapped at index 0x2002, subindex 0x00 +extern UNS8 MasterMap4; // Mapped at index 0x2003, subindex 0x00 diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestMaster.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestMaster.od Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,278 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestMasterSlave.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestMasterSlave.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,200 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Master.h" +#include "Slave.h" +#include "TestMasterSlave.h" + +#define MyCase(fc) case fc: eprintf(#fc);break; +void print_message(Message *m) +{ + int i; + switch(m->cob_id.w >> 7) + { + MyCase(SYNC) + MyCase(TIME_STAMP) + MyCase(PDO1tx) + MyCase(PDO1rx) + MyCase(PDO2tx) + MyCase(PDO2rx) + MyCase(PDO3tx) + MyCase(PDO3rx) + MyCase(PDO4tx) + MyCase(PDO4rx) + MyCase(SDOtx) + MyCase(SDOrx) + MyCase(NODE_GUARD) + MyCase(NMT) + } + eprintf(" rtr:%d", m->rtr); + eprintf(" len:%d", m->len); + for (i = 0 ; i < m->len ; i++) + eprintf(" %02x", m->data[i]); + eprintf("\n"); +} + +UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) +{ + eprintf("OnSlaveMap1Update:%d\n", SlaveMap1); +} + + + +void InitNodes(CO_Data* d, UNS32 id) +{ +// TestSlave_Index2000_callbacks[0] = &OnMasterMap1Update; + RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update); + + /****************************** INITIALISATION MASTER *******************************/ + /* Defining the node Id */ + setNodeId(&TestMaster_Data, 0x01); + + /* init */ + setState(&TestMaster_Data, Initialisation); + + /****************************** INITIALISATION SLAVE *******************************/ + /* Defining the node Id */ + setNodeId(&TestSlave_Data, 0x02); + + /* init */ + setState(&TestSlave_Data, Initialisation); + + /****************************** START *******************************/ + /* Put the master in operational mode */ + setState(&TestMaster_Data, Operational); + + masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Start_Node); + +} + +CAN_HANDLE SlaveCanHandle; +CAN_HANDLE MasterCanHandle; + +// Baudrate values for Peak board : +// CAN_BAUD_1M CAN_BAUD_500K CAN_BAUD_250K CAN_BAUD_125K CAN_BAUD_100K CAN_BAUD_50K +// CAN_BAUD_20K CAN_BAUD_10K CAN_BAUD_5K + +#ifdef CAN_BAUD_500K +// Appli have been compiled for Peak. Baudrate is defined +# define BAUDRATE CAN_BAUD_500K +#else +// Appli have been compiled for Generic. Baudrate not used +# define BAUDRATE 0 +#endif + +void catch_signal(int sig) +{ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); + stopTimer(); + eprintf("Got Sigterm - Finishing.\n"); +} + + +void help() +{ + printf("**************************************************************\n"); + printf("* TestMasterSlave *\n"); + printf("* *\n"); + printf("* A simple example for PC. It does implement 2 CanOpen *\n"); + printf("* nodes in the same process. A master and a slave. Both *\n"); + printf("* communicate together, exchanging periodically NMT, SYNC, *\n"); + printf("* SDO and PDO. *\n"); + printf("* *\n"); + printf("* If you have chosen virtual CAN driver, just type *\n"); + printf("* ./TestMasterSlave *\n"); + printf("* *\n"); + printf("* Else you need to sepcify bus: *\n"); + printf("* *\n"); + printf("* -s : slave CAN bus [default 0, peak first PCI] *\n"); + printf("* -m : master CAN bus [default 1, peak second PCI] *\n"); + printf("* *\n"); + printf("**************************************************************\n"); +} + +/****************************************************************************/ +/*************************** MAIN *****************************************/ +/****************************************************************************/ +int main(int argc,char **argv) +{ + s_BOARD SlaveBoard = {"0", BAUDRATE, &TestSlave_Data}; + s_BOARD MasterBoard = {"1", BAUDRATE, &TestMaster_Data}; + + + char c; + extern char *optarg; + + while ((c = getopt(argc, argv, "-m:s:")) != EOF) + { + switch(c) + { + case 's' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + SlaveBoard.busname = optarg; + break; + case 'm' : + if (optarg[0] == 0) + { + help(); + exit(1); + } + MasterBoard.busname = optarg; + break; + default: + help(); + exit(1); + } + } + + /* install signal handler for manual break */ + signal(SIGTERM, catch_signal); + signal(SIGINT, catch_signal); + + // Open CAN devices + SlaveCanHandle = canOpen(&SlaveBoard); + MasterCanHandle = canOpen(&MasterBoard); + + // Will call InitNodes, and wait and handle next timer events. + TimerLoop(&InitNodes); + + // Close CAN devices + canClose(SlaveCanHandle); + canClose(MasterCanHandle); + + + return 0; +} diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestMasterSlave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestMasterSlave.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,59 @@ +/* +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 +*/ +#ifdef USE_XENO +#define eprintf(...) +#else +#define eprintf(...) printf (__VA_ARGS__) +#endif +void print_message(Message *m); + +extern CAN_HANDLE SlaveCanHandle; +extern CAN_HANDLE MasterCanHandle; + + +/* +#define CAN_FIFO_LENGTH 100 + +#define DECLARE_A_CAN_FIFO \ +static Message FIFO[CAN_FIFO_LENGTH];\ +static int FIFO_First = 0;\ +static int FIFO_Last = 0;\ +\ +static void PutInFIFO(Message *m)\ +{\ + FIFO[FIFO_Last++] = *m;\ + FIFO_Last %= CAN_FIFO_LENGTH;\ +}\ +\ +static void GetFromFIFO(Message *m)\ +{\ + *m = FIFO[FIFO_First++];\ + FIFO_First %= CAN_FIFO_LENGTH;\ +}\ +\ +static void TransmitMessage(CO_Data* d, UNS32 id)\ +{\ + Message m;\ + GetFromFIFO(&m);\ + canDispatch(d, &m);\ +} +*/ diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestSlave.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestSlave.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,297 @@ +/* +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 generated by gen_cfile.py. Should not be modified. */ + +#include "TestSlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ +UNS8 SlaveMap1 = 0x0; // Mapped at index 0x2000, subindex 0x00 +UNS8 SlaveMap2 = 0x0; // Mapped at index 0x2001, subindex 0x00 +UNS8 SlaveMap3 = 0x0; // Mapped at index 0x2002, subindex 0x00 +UNS8 SlaveMap4 = 0x0; // Mapped at index 0x2003, subindex 0x00 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + +UNS32 TestSlave_valueRangeTest (UNS8 typeValue, void * value) +{ + switch (typeValue) { + } + return 0; +} + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* node_id default value.*/ +UNS8 TestSlave_bDeviceNodeId = 0x00; + +//*****************************************************************************/ +/* Array of message processing information */ + +const UNS8 TestSlave_iam_a_slave = 1; + +TIMER_HANDLE TestSlave_heartBeatTimers[0]; + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + +/* index 0x1000 : Device Type. */ + UNS32 TestSlave_obj1000 = 0x12D; + subindex TestSlave_Index1000[] = + { + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1000 } + }; + +/* index 0x1001 : Error Register. */ + UNS8 TestSlave_obj1001 = 0x0; + subindex TestSlave_Index1001[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_obj1001 } + }; + +/* index 0x1005 : SYNC COB ID. */ + UNS32 TestSlave_obj1005 = 0x80; + ODCallback_t TestSlave_Index1005_callbacks[] = + { + NULL, + }; + subindex TestSlave_Index1005[] = + { + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1005 } + }; + +/* index 0x1006 : Communication / Cycle Period. */ + UNS32 TestSlave_obj1006 = 0x0; + ODCallback_t TestSlave_Index1006_callbacks[] = + { + NULL, + }; + subindex TestSlave_Index1006[] = + { + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1006 } + }; + +/* index 0x1016 : Consumer Heartbeat Time */ + UNS8 TestSlave_highestSubIndex_obj1016 = 0; + UNS32 TestSlave_obj1016[0]; + subindex TestSlave_Index1016[0]; + +/* index 0x1017 : Producer Heartbeat Time. */ + UNS16 TestSlave_obj1017 = 0x3E8; + subindex TestSlave_Index1017[] = + { + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1017 } + }; + +/* index 0x1018 : Identity. */ + UNS8 TestSlave_highestSubIndex_obj1018 = 4; // number of subindex - 1 + UNS32 TestSlave_obj1018_Vendor_ID = 0x0; + UNS32 TestSlave_obj1018_Product_Code = 0x0; + UNS32 TestSlave_obj1018_Revision_Number = 0x0; + UNS32 TestSlave_obj1018_Serial_Number = 0x0; + subindex TestSlave_Index1018[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1018 }, + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Vendor_ID }, + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Product_Code }, + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Revision_Number }, + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Serial_Number } + }; + +/* index 0x1200 : Server SDO Parameter. */ + UNS8 TestSlave_highestSubIndex_obj1200 = 2; // number of subindex - 1 + UNS32 TestSlave_obj1200_COB_ID_Client_to_Server_Receive_SDO = 0x601; + UNS32 TestSlave_obj1200_COB_ID_Server_to_Client_Transmit_SDO = 0x581; + subindex TestSlave_Index1200[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1200 }, + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1200_COB_ID_Client_to_Server_Receive_SDO }, + { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1200_COB_ID_Server_to_Client_Transmit_SDO } + }; + +/* index 0x1800 : Transmit PDO 1 Parameter. */ + UNS8 TestSlave_highestSubIndex_obj1800 = 5; // number of subindex - 1 + UNS32 TestSlave_obj1800_COB_ID_used_by_PDO = 0x182; + UNS8 TestSlave_obj1800_Transmission_Type = 0x1; + UNS16 TestSlave_obj1800_Inhibit_Time = 0x0; + UNS16 TestSlave_obj1800_Compatibility_Entry = 0x0; + UNS16 TestSlave_obj1800_Event_Timer = 0x0; + subindex TestSlave_Index1800[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1800 }, + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1800_COB_ID_used_by_PDO }, + { RW, uint8, sizeof (UNS8), (void*)&TestSlave_obj1800_Transmission_Type }, + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1800_Inhibit_Time }, + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1800_Compatibility_Entry }, + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1800_Event_Timer } + }; + +/* index 0x1801 : Transmit PDO 2 Parameter. */ + UNS8 TestSlave_highestSubIndex_obj1801 = 5; // number of subindex - 1 + UNS32 TestSlave_obj1801_COB_ID_used_by_PDO = 0x282; + UNS8 TestSlave_obj1801_Transmission_Type = 0x1; + UNS16 TestSlave_obj1801_Inhibit_Time = 0x0; + UNS16 TestSlave_obj1801_Compatibility_Entry = 0x0; + UNS16 TestSlave_obj1801_Event_Timer = 0x0; + subindex TestSlave_Index1801[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1801 }, + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1801_COB_ID_used_by_PDO }, + { RW, uint8, sizeof (UNS8), (void*)&TestSlave_obj1801_Transmission_Type }, + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1801_Inhibit_Time }, + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1801_Compatibility_Entry }, + { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1801_Event_Timer } + }; + +/* index 0x1A00 : Transmit PDO 1 Mapping. */ + UNS8 TestSlave_highestSubIndex_obj1A00 = 2; // number of subindex - 1 + UNS32 TestSlave_obj1A00[] = + { + 536870920, + 536936456 + }; + subindex TestSlave_Index1A00[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1A00 }, + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A00[0] }, + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A00[1] } + }; + +/* index 0x1A01 : Transmit PDO 2 Mapping. */ + UNS8 TestSlave_highestSubIndex_obj1A01 = 2; // number of subindex - 1 + UNS32 TestSlave_obj1A01[] = + { + 537001992, + 537067528 + }; + subindex TestSlave_Index1A01[] = + { + { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1A01 }, + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A01[0] }, + { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A01[1] } + }; + +/* index 0x2000 : Mapped variable SlaveMap1 */ + subindex TestSlave_Index2000[] = + { + { RW, uint8, sizeof (UNS8), (void*)&SlaveMap1 } + }; + +/* index 0x2001 : Mapped variable SlaveMap2 */ + subindex TestSlave_Index2001[] = + { + { RW, uint8, sizeof (UNS8), (void*)&SlaveMap2 } + }; + +/* index 0x2002 : Mapped variable SlaveMap3 */ + subindex TestSlave_Index2002[] = + { + { RW, uint8, sizeof (UNS8), (void*)&SlaveMap3 } + }; + +/* index 0x2003 : Mapped variable SlaveMap4 */ + subindex TestSlave_Index2003[] = + { + { RW, uint8, sizeof (UNS8), (void*)&SlaveMap4 } + }; + +const indextable TestSlave_objdict[] = +{ + { (subindex*)TestSlave_Index1000,sizeof(TestSlave_Index1000)/sizeof(TestSlave_Index1000[0]), 0x1000}, + { (subindex*)TestSlave_Index1001,sizeof(TestSlave_Index1001)/sizeof(TestSlave_Index1001[0]), 0x1001}, + { (subindex*)TestSlave_Index1005,sizeof(TestSlave_Index1005)/sizeof(TestSlave_Index1005[0]), 0x1005}, + { (subindex*)TestSlave_Index1006,sizeof(TestSlave_Index1006)/sizeof(TestSlave_Index1006[0]), 0x1006}, + { (subindex*)TestSlave_Index1017,sizeof(TestSlave_Index1017)/sizeof(TestSlave_Index1017[0]), 0x1017}, + { (subindex*)TestSlave_Index1018,sizeof(TestSlave_Index1018)/sizeof(TestSlave_Index1018[0]), 0x1018}, + { (subindex*)TestSlave_Index1200,sizeof(TestSlave_Index1200)/sizeof(TestSlave_Index1200[0]), 0x1200}, + { (subindex*)TestSlave_Index1800,sizeof(TestSlave_Index1800)/sizeof(TestSlave_Index1800[0]), 0x1800}, + { (subindex*)TestSlave_Index1801,sizeof(TestSlave_Index1801)/sizeof(TestSlave_Index1801[0]), 0x1801}, + { (subindex*)TestSlave_Index1A00,sizeof(TestSlave_Index1A00)/sizeof(TestSlave_Index1A00[0]), 0x1A00}, + { (subindex*)TestSlave_Index1A01,sizeof(TestSlave_Index1A01)/sizeof(TestSlave_Index1A01[0]), 0x1A01}, + { (subindex*)TestSlave_Index2000,sizeof(TestSlave_Index2000)/sizeof(TestSlave_Index2000[0]), 0x2000}, + { (subindex*)TestSlave_Index2001,sizeof(TestSlave_Index2001)/sizeof(TestSlave_Index2001[0]), 0x2001}, + { (subindex*)TestSlave_Index2002,sizeof(TestSlave_Index2002)/sizeof(TestSlave_Index2002[0]), 0x2002}, + { (subindex*)TestSlave_Index2003,sizeof(TestSlave_Index2003)/sizeof(TestSlave_Index2003[0]), 0x2003}, +}; + +const indextable * TestSlave_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks) +{ + int i; + switch(wIndex){ + case 0x1000: i = 0; *callbacks = NULL; break; + case 0x1001: i = 1; *callbacks = NULL; break; + case 0x1005: i = 2; *callbacks = TestSlave_Index1005_callbacks; break; + case 0x1006: i = 3; *callbacks = TestSlave_Index1006_callbacks; break; + case 0x1017: i = 4; *callbacks = NULL; break; + case 0x1018: i = 5; *callbacks = NULL; break; + case 0x1200: i = 6; *callbacks = NULL; break; + case 0x1800: i = 7; *callbacks = NULL; break; + case 0x1801: i = 8; *callbacks = NULL; break; + case 0x1A00: i = 9; *callbacks = NULL; break; + case 0x1A01: i = 10; *callbacks = NULL; break; + case 0x2000: i = 11; *callbacks = NULL; break; + case 0x2001: i = 12; *callbacks = NULL; break; + case 0x2002: i = 13; *callbacks = NULL; break; + case 0x2003: i = 14; *callbacks = NULL; break; + default: + *errorCode = OD_NO_SUCH_OBJECT; + return NULL; + } + *errorCode = OD_SUCCESSFUL; + return &TestSlave_objdict[i]; +} + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 TestSlave_count_sync[2] = {0,}; + +quick_index TestSlave_firstIndex = { + SDO_SVR : 6, + SDO_CLT : 0, + PDO_RCV : 0, + PDO_RCV_MAP : 0, + PDO_TRS : 7, + PDO_TRS_MAP : 9 +}; + +quick_index TestSlave_lastIndex = { + SDO_SVR : 6, + SDO_CLT : 0, + PDO_RCV : 0, + PDO_RCV_MAP : 0, + PDO_TRS : 8, + PDO_TRS_MAP : 10 +}; + +UNS16 TestSlave_ObjdictSize = sizeof(TestSlave_objdict)/sizeof(TestSlave_objdict[0]); + +CO_Data TestSlave_Data = CANOPEN_NODE_DATA_INITIALIZER(TestSlave); + diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestSlave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestSlave.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,47 @@ +/* +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 generated by gen_cfile.py. Should not be modified. */ + +#include "data.h" + +// prototypes of function to be filled by app +void TestSlave_SDOtimeoutError(UNS8 line); +void TestSlave_heartbeatError(UNS8); + +UNS8 TestSlave_canSend(Message *); + +void TestSlave_initialisation(); +void TestSlave_preOperational(); +void TestSlave_operational(); +void TestSlave_stopped(); + +void TestSlave_post_sync(); +void TestSlave_post_TPDO(); + +// Master node data struct +extern CO_Data TestSlave_Data; + +extern UNS8 SlaveMap1; // Mapped at index 0x2000, subindex 0x00 +extern UNS8 SlaveMap2; // Mapped at index 0x2001, subindex 0x00 +extern UNS8 SlaveMap3; // Mapped at index 0x2002, subindex 0x00 +extern UNS8 SlaveMap4; // Mapped at index 0x2003, subindex 0x00 diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/TestSlave.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/TestSlave.od Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e examples/TestMasterSlave/strace.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/TestMasterSlave/strace.txt Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,239 @@ +execve("./TestMasterSlave", ["./TestMasterSlave"], [/* 60 vars */]) = 0 +uname({sys="Linux", node="recto", ...}) = 0 +brk(0) = 0x509000 +mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaaaac0000 +access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) +open("/etc/ld.so.cache", O_RDONLY) = 3 +fstat(3, {st_mode=S_IFREG|0644, st_size=192295, ...}) = 0 +mmap(NULL, 192295, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2aaaaaac1000 +close(3) = 0 +open("/lib/libpthread.so.0", O_RDONLY) = 3 +read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240V\0\0"..., 640) = 640 +lseek(3, 624, SEEK_SET) = 624 +read(3, "\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\6\0\0\0"..., 32) = 32 +fstat(3, {st_mode=S_IFREG|0755, st_size=118250, ...}) = 0 +mmap(NULL, 1131368, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aaaaabc1000 +mprotect(0x2aaaaabd1000, 1065832, PROT_NONE) = 0 +mmap(0x2aaaaacd0000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf000) = 0x2aaaaacd0000 +mmap(0x2aaaaacd2000, 13160, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2aaaaacd2000 +close(3) = 0 +open("/lib/libc.so.6", O_RDONLY) = 3 +read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\307\1"..., 640) = 640 +lseek(3, 64, SEEK_SET) = 64 +read(3, "\6\0\0\0\5\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0"..., 616) = 616 +lseek(3, 680, SEEK_SET) = 680 +read(3, "\4\0\0\0\20\0\0\0\1\0\0\0GNU\0\0\0\0\0\2\0\0\0\6\0\0\0"..., 32) = 32 +fstat(3, {st_mode=S_IFREG|0755, st_size=1273952, ...}) = 0 +lseek(3, 64, SEEK_SET) = 64 +read(3, "\6\0\0\0\5\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0"..., 616) = 616 +mmap(NULL, 2252808, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2aaaaacd6000 +mprotect(0x2aaaaadf3000, 1085448, PROT_NONE) = 0 +mmap(0x2aaaaaef2000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x11c000) = 0x2aaaaaef2000 +mmap(0x2aaaaaef8000, 16392, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2aaaaaef8000 +close(3) = 0 +mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaaaefd000 +mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaaaefe000 +mprotect(0x2aaaaaef2000, 12288, PROT_READ) = 0 +mprotect(0x2aaaaacd0000, 4096, PROT_READ) = 0 +mprotect(0x2aaaaabbf000, 4096, PROT_READ) = 0 +arch_prctl(ARCH_SET_FS, 0x2aaaaaefde80) = 0 +munmap(0x2aaaaaac1000, 192295) = 0 +set_tid_address(0x2aaaaaefdf10) = 25127 +rt_sigaction(SIGRTMIN, {0x2aaaaabc6240, [], SA_RESTORER|SA_SIGINFO, 0x2aaaaabcd370}, NULL, 8) = 0 +rt_sigaction(SIGRT_1, {0x2aaaaabc62c0, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x2aaaaabcd370}, NULL, 8) = 0 +rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0 +getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0 +_sysctl({{CTL_KERN, KERN_VERSION}, 2, 0x7fffff967810, 31, (nil), 0}) = 0 +open("/dev/urandom", O_RDONLY) = 3 +read(3, "\327\236\37f?\202\314\203", 8) = 8 +close(3) = 0 +rt_sigaction(SIGTERM, {0x401130, [TERM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {SIG_DFL}, 8) = 0 +rt_sigaction(SIGINT, {0x401130, [INT], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {SIG_DFL}, 8) = 0 +pipe([3, 4]) = 0 +mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40, -1, 0) = 0x40000000 +brk(0) = 0x509000 +brk(0x52a000) = 0x52a000 +mprotect(0x40000000, 4096, PROT_NONE) = 0 +clone(child_stack=0x40800280, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x408009f0, tls=0x40800960, child_tidptr=0x408009f0) = 25128 +pipe([5, 6]) = 0 +mmap(NULL, 8392704, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40, -1, 0) = 0x40801000 +mprotect(0x40801000, 4096, PROT_NONE) = 0 +clone(child_stack=0x41001280, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x410019f0, tls=0x41001960, child_tidptr=0x410019f0) = 25129 +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {SIG_DFL}, 8) = 0 +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 1}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 18446744073709551615}}, {it_interval={0, 0}, it_value={0, 8000}}) = 0 +fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 2), ...}) = 0 +mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2aaaaaac1000 +write(1, "TestMaster_initialisation\n", 26) = 26 +write(1, "M->S NODE_GUARD rtr:0 len:1 00\n", 31) = 31 +write(4, "\1\7\0\0\0\0\0\0\0\1\0\0\0\0\0\0\31\0\0\0\0\0\0\0", 24) = 24 +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 50000}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "TestMaster_preOperational\n", 26) = 26 +write(1, "TestSlave_initialisation\n", 25) = 25 +write(1, "S->M NODE_GUARD rtr:0 len:1 00\n", 31) = 31 +write(6, "\2\7\0\0\0\0\0\0\0\1\0\0\0\0\0\0\30\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestSlave_preOperational\n", 25) = 25 +write(1, "TestMaster_operational\n", 23) = 23 +write(1, "M->S NMT rtr:0 len:2 01 02\n", 27) = 27 +write(4, "\0\0\0\0\0\0\0\0\0\2\1\2\0\0\0\0\0O@\0\0\0\0\0", 24) = 24 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49983}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 0 0 0 0\n", 16) = 16 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +write(1, "M->S SDOrx rtr:0 len:8 40 02 20 "..., 47) = 47 +write(4, "\2\6\0\0\0\0\0\0\0\10@\2 \0\0\0\0\0\226\377\377\177\0\0"..., 24) = 24 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49982}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 1 2 3 4\n", 16) = 16 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +write(1, "Got SDO answer (0x2002, 0x00), 0"..., 35) = 35 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49982}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 2 4 6 8\n", 16) = 16 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49968}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 3 6 9 12\n", 17) = 17 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49975}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 4 8 12 16\n", 18) = 18 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49982}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 5 10 15 20\n", 19) = 19 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49983}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 6 12 18 24\n", 19) = 19 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49984}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 7 14 21 28\n", 19) = 19 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49983}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 8 16 24 32\n", 19) = 19 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49983}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 9 18 27 36\n", 19) = 19 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49984}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 10 20 30 40\n", 20) = 20 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +write(1, "M->S SDOrx rtr:0 len:8 40 02 20 "..., 47) = 47 +write(4, "\2\6\0\0\0\0\0\0\0\10@\2 \0\0\0\0\0\226\377\377\177\0\0"..., 24) = 24 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49970}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 11 22 33 44\n", 20) = 20 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +write(1, "Got SDO answer (0x2002, 0x00), 0"..., 35) = 35 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49983}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 12 24 36 48\n", 20) = 20 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49984}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 13 26 39 52\n", 20) = 20 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGALRM (Alarm clock) @ 0 (0) --- +rt_sigaction(SIGALRM, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x4017f0, [ALRM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigreturn(0x508af0) = -1 EINTR (Interrupted system call) +setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 49984}}, {it_interval={0, 0}, it_value={0, 0}}) = 0 +write(1, "M->S SYNC rtr:0 len:0\n", 22) = 22 +write(4, "\200\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 24) = 24 +write(1, "TestMaster_post_sync\n", 21) = 21 +write(1, "Master: 14 28 42 56\n", 20) = 20 +write(1, "TestMaster_post_TPDO\n", 21) = 21 +pause() = ? ERESTARTNOHAND (To be restarted) +--- SIGINT (Interrupt) @ 0 (0) --- +rt_sigaction(SIGTERM, {0x401130, [TERM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x401130, [TERM], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +rt_sigaction(SIGINT, {0x401130, [INT], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, {0x401130, [INT], SA_RESTORER|SA_RESTART, 0x2aaaaad04a20}, 8) = 0 +kill(0, SIGALRM \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,120 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC + +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +BINUTILS_PREFIX = SUB_BINUTILS_PREFIX +TARGET = SUB_TARGET + + +INCLUDES = -I../../include -I../../include/hcs12 +MEMORY_X = ../../include/hcs12/board/arch + +OBJCOPY = $(BINUTILS_PREFIX)objcopy +OBJCOPY_FLAGS = --only-section=.text --only-section=.rodata --only-section=.vectors --only-section=.data + +PROGDEFINES = -mnoshort -Wall -Wmissing-prototypes -fno-strict-aliasing + +PGR=geneSYNC + +SYNC_OBJS = objdict.o appli.o vectors.o + +OBJS = ../../src/$(TARGET)_pdo.o\ + ../../src/$(TARGET)_sdo.o\ + ../../src/$(TARGET)_states.o\ + ../../src/$(TARGET)_sync.o\ + ../../src/$(TARGET)_objacces.o\ + ../../src/$(TARGET)_lifegrd.o\ + ../../src/$(TARGET)_timer.o\ + ../../src/$(TARGET)_nmtSlave.o\ + ../../drivers/$(TARGET)/canOpenDriver.o\ + ../../drivers/$(TARGET)/ports.o\ + ../../drivers/$(TARGET)/interrupt.o\ + $(SYNC_OBJS) + +LDFLAGS= -Wl,-m,m68hc12elfb -L$(MEMORY_X) + +all: $(PGR).elf $(PGR).s19 $(PGR).b $(PGR).s MSG + +%o: %c + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -c -o $@ $< + +%o: %s + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) -c -x assembler-with-cpp $(PROG_CFLAGS) -o $@ $< + +$(PGR).elf: $(OBJS) + @echo " " + @echo "=============================================" + @echo "**Linking : $@" + @echo "=============================================" + $(CC) $(CFLAGS) $(LDFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ $(OBJS) + +$(PGR).s19: $(PGR).elf + @echo " " + @echo "=============================================" + @echo "**Create s19 file : $@" + @echo "=============================================" + $(OBJCOPY) --output-target=srec $(OBJCOPY_FLAGS) $< $@ + +$(PGR).b: $(PGR).elf + @echo " " + @echo "=============================================" + @echo "**Create binary file : $@" + @echo "=============================================" + $(OBJCOPY) --output-target=binary --gap-fill=255 --only-section=.data $(OBJCOPY_FLAGS) $< $@ + +$(PGR).s: $(PGR).elf + @echo " " + @echo "=============================================" + @echo "**Create unassembled file : $@" + @echo "=============================================" + $(BINUTILS_PREFIX)objdump -D $(PGR).elf > $(PGR).s + +MSG: + @echo " " + @echo "---------------------------------------------" + @echo "**Informations on elf file : $(PGR).elf " + @echo "---------------------------------------------" + $(BINUTILS_PREFIX)readelf -S $(PGR).elf + @echo + $(BINUTILS_PREFIX)size $(PGR).elf + +clean: + -\rm $(SYNC_OBJS) + +mrproper: clean + -\rm $(PGR).elf $(PGR).s19 $(PGR).b $(PGR).s + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/appli.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/appli.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,329 @@ +/* +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 +*/ + + +#define DEBUG_WAR_CONSOLE_ON +#define DEBUG_ERR_CONSOLE_ON + +#include /* for NULL */ + +#include +#include +#include +#include + +#include + + + +#include <../include/hcs12/candriver.h> + +#include "../include/def.h" +#include "../include/can.h" +#include "../include/objdictdef.h" +#include "../include/objacces.h" +#include "../include/sdo.h" +#include "../include/pdo.h" +#include "../include/timer.h" +#include "../include/lifegrd.h" +#include "../include/sync.h" + + +#include "../include/nmtSlave.h" +#include "objdict.h" + + +// HCS12 configuration +// ----------------------------------------------------- + +enum E_CanBaudrate +{ + CAN_BAUDRATE_250K, + CAN_BAUDRATE_500K, + CAN_BAUDRATE_1M, +}; + + +const canBusTime CAN_Baudrates[] = +{ + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 3, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 13 tq for the TIME 1 segment (tseg1 = 12) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 4 MHZ (brp = 3+1), and there are 16 tq in the bit time, + so the freq of the bit time is 250 kHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 13 tq for the TIME 1 segment (tseg1 = 12) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 8 MHZ (brp = 1+1), and there are 16 tq in the bit time, + so the freq of the bit time is 500 kHz. + */ + }, + + { + 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ + 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ + 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ + 0, /* samp : chose btw 0 and 3 (2 bits) (samp +MSG_WAR(0x3F33, "Je suis le noeud ", getNodeId()); 1 ) samples per bit */ + 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ + 4, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ + + /* + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 5 tq for the TIME 1 segment (tseg1 = 4) + - 2 tq for the TIME 2 segment (tseg2 = 1) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 8 MHZ (brp = 1+1), and there are 8 tq in the bit time, + so the freq of the bit time is 1 MHz. + */ + } +}; + + + + +/**************************prototypes*****************************************/ + +//fonction d'initialisation du bus can et la couche CANOPEN pour le capteur +void initCanopencapteur (void); +// les fonctions d'initialisation du capteur: timer, compteurs logiciel +void initSensor(void); +void initPortB(void); + +//------------------------------------------------------------------------------ +//Initialisation of the port B for the leds. +void initPortB(void) +{ + // Port B is output + IO_PORTS_8(DDRB)= 0XFF; + // RAZ + IO_PORTS_8(PORTB) = 0xFF; +} + + + +//------------------------------------------------------------------------------ +void initSensor(void) +{ + UNS8 baudrate = 0; + MSG_WAR(0x3F33, "I am the node : ", getNodeId(&gene_SYNC_Data)); + // Init led control + initPortB(); + IO_PORTS_8(PORTB) &= ~ 0x01; //One led ON + // Init port to choose se CAN baudrate by switch + IO_PORTS_8(ATD0DIEN) = 0x03; + + canBusInit bi0 = { + 0, /* no low power */ + 0, /* no time stamp */ + 1, /* enable MSCAN */ + 0, /* clock source : oscillator (In fact, it is not used) */ + 0, /* no loop back */ + 0, /* no listen only */ + 0, /* no low pass filter for wk up */ + CAN_Baudrates[CAN_BAUDRATE_250K], + { + 0x00, /* Filter on 16 bits. See Motorola Block Guide V02.14 fig 4-3 */ + 0x00, 0xFF, /* filter 0 hight accept all msg */ + 0x00, 0xFF, /* filter 0 low accept all msg */ + 0x00, 0xFF, /* filter 1 hight filter all of msg */ + 0x00, 0xFF, /* filter 1 low filter all of msg */ + 0x00, 0xFF, /* filter 2 hight filter most of msg */ + 0x00, 0xFF, /* filter 2 low filter most of msg */ + 0x00, 0xFF, /* filter 3 hight filter most of msg */ + 0x00, 0xFF, /* filter 3 low filter most of msg */ + } + }; + + //Init the HCS12 microcontroler for CanOpen + initHCS12(); + + // Chose the CAN rate + baudrate = IO_PORTS_8(PORTAD0) & 0x03; + switch (baudrate) { + case 1: + bi0.clk = CAN_Baudrates[CAN_BAUDRATE_250K]; + MSG_WAR(0x3F30, "CAN 250 kbps ", 0); + break; + case 2: + bi0.clk = CAN_Baudrates[CAN_BAUDRATE_500K]; + MSG_WAR(0x3F31, "CAN 500 kbps ", 0); + break; + case 3: + bi0.clk = CAN_Baudrates[CAN_BAUDRATE_1M]; + MSG_WAR(0x3F31, "CAN 1000 kbps ", 0); + break; + default: + MSG_WAR(0x2F32, "CAN BAUD RATE NOT DEFINED ", 0); + } + + MSG_WAR(0x3F33, "SYNC signal generator", 0); + + canInit(CANOPEN_LINE_NUMBER_USED, bi0); //initialize filters... + initTimer(); // Init hcs12 timer used by CanFestival. (see timerhw.c) + unlock(); // Allow interruptions +} + + + + + + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// FUNCTIONS WHICH ARE PART OF CANFESTIVAL and *must* be implemented here. + +//------------------------------------------------------------------------------ +void gene_SYNC_heartbeatError( UNS8 heartbeatID ) +{ + + MSG_ERR(0x1F00, "HeartBeat not received from node : ", heartbeatID); +} + +//------------------------------------------------------------------------------ +void gene_SYNC_SDOtimeoutError (UNS8 line) +{ + MSG_ERR(0x1F01, "SDO timeout for line : ", line); +} + +//------------------------------------------------------------------------------ +UNS8 gene_SYNC_canSend(Message *m) +{ + // HCS12 driver function to send the CAN msg + canMsgTransmit(CAN0, *m); + return 0; +} + +//------------------------------------------------------------------------------ +void gene_SYNC_initialisation() +{ + MSG_WAR (0x3F00, "Entering in INIT ", 0); + initSensor(); + IO_PORTS_8(PORTB) &= ~ 0x01; // led 0 : ON + IO_PORTS_8(PORTB) |= 0x0E; // leds 1, 2, 3 : OFF +} + + +//------------------------------------------------------------------------------ +void gene_SYNC_preOperational() +{ + MSG_WAR (0x3F01, "Entering in PRE-OPERATIONAL ", 0); + IO_PORTS_8(PORTB) &= ~ 0x03; // leds 0, 1 : ON + IO_PORTS_8(PORTB) |= 0x0C; // leds 2, 3 : OFF +} + + +//------------------------------------------------------------------------------ +void gene_SYNC_operational() +{ + MSG_WAR (0x3F02, "Entering in OPERATIONAL ", 0); + IO_PORTS_8(PORTB) &= ~ 0x07; // leds 0, 1, 2 : ON + IO_PORTS_8(PORTB) |= 0x08; // leds 3 : OFF +} + +//------------------------------------------------------------------------------ +void gene_SYNC_stopped() +{ + MSG_WAR (0x3F02, "Entering in STOPPED ", 0); +} + +//------------------------------------------------------------------------------ +void gene_SYNC_post_sync() +{ +} + +//------------------------------------------------------------------------------ +void gene_SYNC_post_TPDO() +{ +} + +// End functions which are part of Canfestival +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ + + +/******************************************************************************/ +/********************************* MAIN ***************************************/ +/******************************************************************************/ + + +UNS8 main (void) +{ + + MSG_WAR(0x3F34, "Entering in the main", 0); + //----------------------------- INITIALISATION -------------------------------- + /* Defining the node Id */ + setNodeId(&gene_SYNC_Data, 0x03); + + /* Put the node in Initialisation mode */ + MSG_WAR(0x3F35, "va passer en init", 0); + setState(&gene_SYNC_Data, Initialisation); + + //----------------------------- START ----------------------------------------- + /* Put the node in pre-operational mode */ + //MSG_WAR(0x3F36, "va passer en pre-op", 0); + //setState(&gene_SYNC_Data, Pre_operational); + + while (1) { + { + Message m; + if (f_can_receive(0, &m)) { + MSG_WAR(0x3F36, "Msg received", m.cob_id.w); + canDispatch(&gene_SYNC_Data, &m); + } + + + } + + } + + return (0); +} + + + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/objdict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/objdict.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,233 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "objdict.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + + + +UNS32 gene_SYNC_valueRangeTest (UNS8 typeValue, UNS32 unsValue, REAL32 realValue) +{ + switch (typeValue) { + } + return 0; +} + + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* node_id default value. + This default value is deprecated. + You should always overwrite this by using the function setNodeId(UNS8 nodeId) in your C code. +*/ +#define NODE_ID 0x03 +UNS8 gene_SYNC_bDeviceNodeId = NODE_ID; + + +//*****************************************************************************/ +/* Array of message processing information */ +/* Should not be modified */ + +const UNS8 gene_SYNC_iam_a_slave = 1; + + // Macros definition + +/* Beware : +index *must* be writen 4 numbers in hexa +sub_index *must* be writen 2 numbers in hexa +size_variable_in_UNS8 *must* be writen 2 numbers in hexa +*/ +#define PDO_MAP(index, sub_index, size_variable_in_bits)\ +0x ## index ## sub_index ## size_variable_in_bits + +/** This macro helps creating the object dictionary entries. + * by calling this macro + * it creates an entry in form of: 7 of entries, pointer to the entry. + */ +#define DeclareIndexTableEntry(entryname, index) { (subindex*)entryname,sizeof(entryname)/sizeof(entryname[0]), index} + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// Make your change, depending of your application + + +/* index 0x1000 : Device type. + You have to change the value below, so + it fits your canopen-slave-module */ + + /* Not used, so, should not be modified */ + + UNS32 gene_SYNC_obj1000 = 0; + subindex gene_SYNC_Index1000[] = + { + { RO, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1000 } + }; + +/* index 0x1001 : Error register. + Change the entries to fit your application + Not used, so, should not be modified */ + UNS8 gene_SYNC_obj1001 = 0x00000000; + subindex gene_SYNC_Index1001[] = + { + { RO, uint8, sizeof(UNS8), (void*)&gene_SYNC_obj1001 } + }; + +/* index 0x1005 : COB_ID SYNC */ + /* Should not be modified */ + UNS32 gene_SYNC_obj1005 = 0x40000080; // bit 30 = 1 : device can generate a SYNC message + // Beware, it is over written when the node + // enters in reset mode + // See initResetMode() in init.c + subindex gene_SYNC_Index1005[] = + { + { RW, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1005 } + }; + +/* index 0x1006 : SYNC period */ + // For producing the SYNC signal every n micro-seconds. + // Put 0 to not producing SYNC + UNS32 gene_SYNC_obj1006 = 0x000186A0; + // Default 0 to not produce SYNC // + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + subindex gene_SYNC_Index1006[] = + { + { RW, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1006 } + }; + + + TIMER_HANDLE gene_SYNC_heartBeatTimers[0]; + UNS32 gene_SYNC_obj1016[0]; + UNS8 gene_SYNC_obj1016_cnt = 0; + subindex gene_SYNC_Index1016[0]; + + UNS16 gene_SYNC_obj1017 = 0x0000; +/* index 0x1018 : Identity object */ + /** index 1018: identify object. Adjust the entries for your node/company + */ + /* Values can be modified */ + + s_identity gene_SYNC_obj1018 = + { + 4, // number of supported entries + 0, // Vendor-ID (given by the can-cia) + 0, // Product Code + 0, // Revision number + 0 // serial number + }; + + subindex gene_SYNC_Index1018[] = + { + { RO, uint8, sizeof(UNS8), (void*)&gene_SYNC_obj1018.count }, + { RO, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1018.vendor_id}, + { RO, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1018.product_code}, + { RO, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1018.revision_number}, + { RO, uint32, sizeof(UNS32), (void*)&gene_SYNC_obj1018.serial_number} + }; + +/* index 0x1200 : The SDO Server parameters */ + /* BEWARE You cannot define more than one SDO server */ + /* The values should not be modified here, + but can be changed at runtime */ + // Beware that the default values that you could put here + // will be over written at the initialisation of the node. + // See setNodeId() in init.c + s_sdo_parameter gene_SYNC_obj1200 = + { 3, // Number of entries. Always 3 for the SDO + 0x000, // The cob_id transmited in CAN msg to the server + 0x000, // The cob_id received in CAN msg from the server + 0x03 // The node id of the client. Should not be modified + }; + subindex gene_SYNC_Index1200[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&gene_SYNC_obj1200.count }, + { RO, uint32, sizeof( UNS32), (void*)&gene_SYNC_obj1200.cob_id_client }, + { RO, uint32, sizeof( UNS32), (void*)&gene_SYNC_obj1200.cob_id_server }, + { RW, uint8, sizeof( UNS8), (void*)&gene_SYNC_obj1200.node_id } + }; + +/* index 0x1280 : SDO client parameter */ + s_sdo_parameter gene_SYNC_obj1280 = + { 3, // Nb of entries + 0x000, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x000, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x00 // server NodeId + }; + subindex gene_SYNC_Index1280[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&gene_SYNC_obj1280.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&gene_SYNC_obj1280.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&gene_SYNC_obj1280.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&gene_SYNC_obj1280.node_id } + }; + + +const indextable gene_SYNC_objdict[] = +{ + DeclareIndexTableEntry(gene_SYNC_Index1000, 0x1000), + DeclareIndexTableEntry(gene_SYNC_Index1001, 0x1001), + DeclareIndexTableEntry(gene_SYNC_Index1005, 0x1005), + DeclareIndexTableEntry(gene_SYNC_Index1006, 0x1006), + DeclareIndexTableEntry(gene_SYNC_Index1018, 0x1018), + DeclareIndexTableEntry(gene_SYNC_Index1200, 0x1200), + DeclareIndexTableEntry(gene_SYNC_Index1280, 0x1280), +}; + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 gene_SYNC_count_sync[1] = {0, }; + +quick_index gene_SYNC_firstIndex = { + SDO_SVR : 5, + SDO_CLT : 6, + PDO_RCV : 0, + PDO_RCV_MAP : 0, + PDO_TRS : 0, + PDO_TRS_MAP : 0 +}; + +quick_index gene_SYNC_lastIndex = { + SDO_SVR : 5, + SDO_CLT : 6, + PDO_RCV : 0, + PDO_RCV_MAP : 0, + PDO_TRS : 0, + PDO_TRS_MAP : 0 +}; + +UNS16 gene_SYNC_ObjdictSize = sizeof(gene_SYNC_objdict)/sizeof(gene_SYNC_objdict[0]); + +CO_Data gene_SYNC_Data = CANOPEN_NODE_DATA_INITIALIZER(gene_SYNC); + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/objdict.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/objdict.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,41 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "data.h" + +// prototypes of function to be filled by app +void gene_SYNC_SDOtimeoutError(UNS8 line); +void gene_SYNC_heartbeatError(UNS8); + +UNS8 gene_SYNC_canSend(Message *); + +void gene_SYNC_initialisation(); +void gene_SYNC_preOperational(); +void gene_SYNC_operational(); +void gene_SYNC_stopped(); + +void gene_SYNC_post_sync(); +void gene_SYNC_post_TPDO(); + +// Master node data struct +extern CO_Data gene_SYNC_Data; + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/objdict.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/objdict.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,128 @@ + + + + +CANOpen object dictionary Configuration + + + +

Object dictionary for Node :

+

+0x03(default) + Gene_SYNCslave +

+

Overview

+

+ How to make the object dictionary of the node ? + First, use Jaxe (command run_objdict) to edit an xml description file +of the dictionary : objdict.xml. +Then, run the php program : makeobjetdict.php. You can launch php through a web browser +if you have installed a server, or, on Linux, you can launch php in command line : +php-cgi makeobjetdict.php. It compute the file objdict.c. Link it to + your project. +
Note : To define the node id, use in your code the function setNodeId(UNS8 nodeId) +

+

+ Then the node can be connected to the network. The master must configure it + by sending SDO. It will write values in its index, subindex. What to configure ? +

    +
  • Receiving heartbeats from which nodes ? Waiting time ?
  • +
  • Emitting heartbeats or not ? time btw 2 heartbeats ?
  • +
  • Defining a cobId for each PDO receive and transmit
  • +
  • How to transmit a PDO ? on synchro ? request ? event ?
  • +
  • What variables to put in each PDO receive and transmit ?
  • +
  • ...
  • +
+

+ To avoid configuring the node at the connection, you can put the values directly +in the dictionary objdict.c. But it is boring and unsafe because it is too easy to make +a mistake ! + + +

Number of heartbeat consumers : + 1 +

+

This means that the node can expect heartbeats sent by 1 nodes.

+

Number of SDO clients : + 1 +

+

Usualy, a slave node does not have the use of SDO clients, but + today, for the library, you must define one. The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Mapped variables and tables

+

3 tables are defined for the mapping, starting at index 0x2000, 0x6000 and 0x6200. + You must start the mapping at the beginning of one of a table, without holes in index +or subindex. For example, variables in 0x2000 and 0x2001 is ok, but variables in 0x2000 and 0x2002 is not allowed, because you are loosing room in memory. It is the same for the subindex. +

+

+ The access of the variable is by default "rw" (read-write) or "ro" (read-only). A read-only variable cannot be mapped in a PDO receive. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + +
Var NameBitsIndexSub-indexaccess
canopenErrNB320x60000x01
canopenErrVAL320x60000x02
Table NameBitsIndexSub-indexaccess
+ + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/objdict.od --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/objdict.od Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,58 @@ +(inode +Node +p1 +(dp2 +S'Profile' +p3 +(dp4 +sS'Name' +p5 +Vgene_SYNC +p6 +sS'Dictionary' +p7 +(dp8 +I4096 +I0 +sI4097 +I0 +sI4101 +I1073741952 +sI4102 +I100000 +sI4608 +(lp9 +I0 +aI0 +asI4120 +(lp10 +I0 +aI0 +aI0 +aI0 +asI4736 +(lp11 +I0 +aI0 +aI0 +assS'SpecificMenu' +p12 +(lp13 +sS'UserMapping' +p14 +(dp15 +sS'DS302' +p16 +(dp17 +sS'ProfileName' +p18 +S'None' +p19 +sS'Type' +p20 +Vslave +p21 +sS'ID' +p22 +I3 +sb. \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/objdict.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/objdict.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/readme.txt Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,68 @@ +Generator of Canopen SYNC message (cobid = 0x80) +--------------------------------------------- +francis.dupin@inrets.fr +27 Janv 2005 + +Node for Microcontroler MC9S12DP256 +on board T-board (http://www.elektronikladen.de + +============= +Node N° 0x03 +============= + +This node generate only the SYNC signal. +(cob-id : 0x80) + +To test this node +----------------- +Reset it : +It is sending : +cobid : 0x703 +data : 00 + + 1 - Wants to generate SYNC every 10 milliseconds + +1a - put the value (4 bytes) : 0x00002710 in its dictionary +index 0x1006, subindex 0x00 : + +CAN message (SDO) : +cobid : 0x603 +data : 23 06 10 00 10 27 00 00 +(put 23 to transmit a data of 4 bytes + 27 3 bytes + 2B 2 bytes + 2F 1 byte +) + +The node is responding : +cobid : 0x583 +data : 60 06 10 00 00 00 00 00 + +1b - put the value (4 bytes) : 0x40000080 at index 0x1005, subindex 0x00 +to start the SYNC : +cobid : 0x603 +data : 23 05 10 00 80 00 00 40 + +The node is responding : +cobid : 0x583 +data : 60 05 10 00 00 00 00 00 + + 2 - Put the node in operational mode +CAN message (NMT) : +cobid : 0x00 +data : 01 03 + +The node is sending the SYNC every 10 ms + + +Nota +----- +To stop the SYNC : 2 methods + +1 - put 0x00000000 at index 1006 subindex 0 +2 - put 0x00000080 at index 1005 subindex 0 + + + + + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/trace32_flash_debug.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/trace32_flash_debug.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,43 @@ +; Réinitialisation +SYS.d + +; Effacer l'écran +WinCLEAR + +;Raffraichissement de trace32 toutes les 1 secondes +setup.urate 1 + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Vitesse de commuication debugger / carte HCS12 + SYStem.BdmClock 8.0MHZ + +; initialiser le uc en mode debug +SYStem.UP + +; Reset des registres +r.reset + +; Charger le programme +DATA.LOAD.ELF geneSYNC.elf /gnu /nocode /GHILLS + +; Positionner le compteur de programme +r.set PC _start + +; Positionner le pointeur de pile +r.set SP _stack + +; Afficher le code source +data.list + +; Afficher les registres +r + +; Afficher le contenu de la mémoire +DATA.dump 140 + + +; Fin du programme de script +ENDDO + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/trace32_flash_debug_sans_init.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/trace32_flash_debug_sans_init.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,36 @@ +; Réinitialisation +SYS.d + +; Effacer l'écran +;WinCLEAR + +;Raffraichissement de trace32 toutes les 1 secondes +setup.urate 1 + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Vitesse de commuication debugger / carte HCS12 + SYStem.BdmClock 8.0MHZ + +; initialiser le uc en mode debug +SYStem.UP + +; Reset des registres +r.reset + +; Charger le programme +DATA.LOAD.ELF geneSYNC.elf /gnu /nocode /GHILLS + +; Positionner le compteur de programme +r.set PC _start + +; Positionner le pointeur de pile +r.set SP _stack + + + + +; Fin du programme de script +ENDDO + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/trace32_flash_programmer.cmm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/trace32_flash_programmer.cmm Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,94 @@ +; Programmation de la mémoire flash + + +; Réinitialisation +SYS.d + +; Effacer l'écran +WinCLEAR + +; Vitesse de transmission : +SYStem.BdmClock 8.0MHZ + +; Choix du microcontrôleur cible +SYStem.CPU MCS12DP256 + +; Flash page 0X3E accessible entre 0X4000 et 0X7FFF +; cf Motorola, registre MISC + +system.option ROMHM ON + + +; Enlever tous les points d'arrêt +b.res + +; Utiliser les points d'arrêts onchip +map.bonchip + +; Connexion à la carte CS12 +system.up + +flash.reset + + +; Effacement de la flash +PRINT "Effacement de la flash" +FLASH.Erase all + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 1 " +FLASH.Program 0x4000--0x7FFF + +;print "Chargement du programme en flash 1" +DATA.LOAD.ELF geneSYNC.elf 0x4000--0x7FFF + + +FLASH.Program off +print "Flash programmée 1" + + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 2" +FLASH.Program 0x308000--0x30BFFF + +;print "Chargement du programme en flash 2" +DATA.LOAD.ELF geneSYNC.elf 0x8000--0xBFFF + + +FLASH.Program off +print "Flash programmée 2" + +; Passage en mode programmation de la flash +print "Programmation de la flash non paginée (48KO) 3" +FLASH.Program 0xC000--0xFFFF + +;print "Chargement du programme en flash 3" +DATA.LOAD.ELF geneSYNC.elf 0xC000--0xFFFF + + +FLASH.Program off +print "Flash programmée 3" + + +;Reset du HCS12 +system.up + +;Reset de trace32 +SYS.d + + +ENDDO + + + + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e examples/gene_SYNC_HCS12/vectors.s --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/gene_SYNC_HCS12/vectors.s Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,214 @@ +;;/* M68HC11 Interrupt vectors table +;; Copyright (C) 1999 Free Software Foundation, Inc. +;; Written by Stephane Carrez (stcarrez@worldnet.fr) +;; +;;This file is free software; you can redistribute it and/or modify it +;;under the terms of the GNU General Public License as published by the +;;Free Software Foundation; either version 2, or (at your option) any +;;later version. +;; +;;In addition to the permissions in the GNU General Public License, the +;;Free Software Foundation gives you unlimited permission to link the +;;compiled version of this file with other programs, and to distribute +;;those programs without any restriction coming from the use of this +;;file. (The General Public License restrictions do apply in other +;;respects; for example, they cover modification of the file, and +;;distribution when not linked into another program.) +;; +;;This file 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 +;;General Public License for more details. +;; +;;You should have received a copy of the GNU General Public License +;;along with this program; see the file COPYING. If not, write to +;;the Free Software Foundation, 59 Temple Place - Suite 330, +;;Boston, MA 02111-1307, USA. +;; ---------------------------------------------- +;; Modified by Francis Dupin for MC9S12DP256. April 2003 +;; francis.dupin@inrets.fr +;;*/ + + .sect .text + .globl _start + .globl can4HdlTra + .globl can4HdlRcv + .globl can4HdlErr + .globl can4HdlWup + .globl can3HdlTra + .globl can3HdlRcv + .globl can3HdlErr + .globl can3HdlWup + .globl can2HdlTra + .globl can2HdlRcv + .globl can2HdlErr + .globl can2HdlWup + .globl can1HdlTra + .globl can1HdlRcv + .globl can1HdlErr + .globl can1HdlWup + .globl can0HdlTra + .globl can0HdlRcv + .globl can0HdlErr + .globl can0HdlWup + .globl timerOvflHdl + .globl timer3IC + .globl timer2IC + .globl timer1IC + .globl timer0IC + +;; Default interrupt handler. + .sect .text +def: + rti + +;; +;; Interrupt vectors are in a specific section that is +;; mapped at 0xff00. For the example program, the reset handler +;; points to the generic crt0 entry point. +;; + .sect .vectors + .globl vectors +vectors: + + .word def ; ff00 + .word def ; ff02 + .word def ; ff04 + .word def ; ff06 + .word def ; ff08 + .word def ; ff0a + .word def ; ff0c + .word def ; ff0e + .word def ; ff10 + .word def ; ff12 + .word def ; ff14 + .word def ; ff16 + .word def ; ff18 + .word def ; ff1a + .word def ; ff1c + .word def ; ff1e + .word def ; ff20 + .word def ; ff22 + .word def ; ff24 + .word def ; ff26 + .word def ; ff28 + .word def ; ff2a + .word def ; ff2c + .word def ; ff2e + .word def ; ff30 + .word def ; ff32 + .word def ; ff34 + .word def ; ff36 + .word def ; ff38 + .word def ; ff3a + .word def ; ff3c + .word def ; ff3e + .word def ; ff40 + .word def ; ff42 + .word def ; ff44 + .word def ; ff46 + .word def ; ff48 + .word def ; ff4a + .word def ; ff4c + .word def ; ff4e + .word def ; ff50 + .word def ; ff52 + .word def ; ff54 + .word def ; ff56 + .word def ; ff58 + .word def ; ff5a + .word def ; ff5c + .word def ; ff5e + .word def ; ff60 + .word def ; ff62 + .word def ; ff64 + .word def ; ff66 + .word def ; ff68 + .word def ; ff6a + .word def ; ff6c + .word def ; ff6e + .word def ; ff70 + .word def ; ff72 + .word def ; ff74 + .word def ; ff76 + .word def ; ff78 + .word def ; ff7a + .word def ; ff7c + .word def ; ff7e + .word def ; ff80 + .word def ; ff82 + .word def ; ff84 + .word def ; ff86 + .word def ; ff88 + .word def ; ff8a + .word def ; ff8c + .word def ; ff8e + + ;; MSCAN + .word can4HdlTra ; ff90 (MSCAN4 Transmit) + .word can4HdlRcv ; ff92 (MSCAN4 Receive) + .word can4HdlErr ; ff94 (MSCAN4 Errors) + .word can4HdlWup ; ff96 (MSCAN4 Wake up) + .word can3HdlTra ; ff98 (MSCAN3 Transmit) + .word can3HdlRcv ; ff9a (MSCAN3 Receive) + .word can3HdlErr ; ff9c (MSCAN3 Errors) + .word can3HdlWup ; ff9e (MSCAN3 Wake up) + .word can2HdlTra ; ffa0 (MSCAN2 Transmit) + .word can2HdlRcv ; ffa2 (MSCAN2 Receive) + .word can2HdlErr ; ffa4 (MSCAN2 Errors) + .word can2HdlWup ; ffa6 (MSCAN2 Wake up) + .word can1HdlTra ; ffa8 (MSCAN1 Transmit) + .word can1HdlRcv ; ffaa (MSCAN1 Receive) + .word can1HdlErr ; ffac (MSCAN1 Errors) + .word can1HdlWup ; ffae (MSCAN1 Wake up) + .word can0HdlTra ; ffb0 (MSCAN0 Transmit) + .word can0HdlRcv ; ffb2 (MSCAN0 Receive) + .word can0HdlErr ; ffb4 (MSCAN0 Errors) + .word can0HdlWup ; ffb6 (MSCAN0 Wake up) + + .word def ; ffb8 + .word def ; ffba + .word def ; ffbc + .word def ; ffbe + + .word def ; ffc0 + .word def ; ffc2 + .word def ; ffc4 + .word def ; ffc6 + .word def ; ffc8 + .word def ; ffca (Modulus Down Counter underflow) + .word def ; ffcc + .word def ; ffce + .word def ; ffd0 + .word def ; ffd2 + .word def ; ffd4 + + ;; SCI + .word def ; ffd6 + + ;; SPI + .word def ; ffd8 + .word def ; ffda (PAII) + .word def ; ffdc (PAOVI) + .word def ;ffde (TOI) + + ;; Timer Output Compare + .word def ; ffe0 Timer Chanel 7 + .word def ; ffe2 Timer Chanel 6 + .word def ; ffe4 Timer Chanel 5 + .word timer4Hdl ; ffe6 Timer Chanel 4 used by Canopen + .word def ; ffe8 Timer Chanel 3 + .word def ; ffea Timer Chanel 2 + .word def ; ffec Timer Chanel 1 + .word def ; ffee Timer Chanel 0 + + ;; Misc + .word def ; fff0 (RTII) + .word def ; fff2 (IRQ) + .word def ; fff4 (XIRQ) + .word def ; fff6 (SWI) + .word def ; fff8 (ILL) + .word def ; fffa (COP Failure) + .word def ; fffc (COP Clock monitor) + .word _start ; fffe (reset) + diff -r 000000000000 -r 4472ee7c6c3e include/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +config.h diff -r 000000000000 -r 4472ee7c6c3e include/can.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,50 @@ +/* +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 __can_h__ +#define __can_h__ +/** Used for the Can message structure */ +/* +union SHORT_CAN { + struct { UNS8 b0,b1; } b; + UNS32 w; +}; +*/ + +typedef struct { + UNS32 w; // 32 bits +} SHORT_CAN; + + +/** Can message structure */ +typedef struct { + SHORT_CAN cob_id; // l'ID du mesg + UNS8 rtr; // remote transmission request. 0 if not rtr, + // 1 for a rtr message + UNS8 len; // message length (0 to 8) + UNS8 data[8]; // data +} Message; + + +typedef UNS8 (*canSend_t)(Message *); + +#endif // __can_h__ diff -r 000000000000 -r 4472ee7c6c3e include/can_driver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can_driver.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,55 @@ +/* +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 __can_driver_h__ +#define __can_driver_h__ + +#include "timerscfg.h" + +struct struct_s_BOARD; + +typedef struct struct_s_BOARD s_BOARD; + +#include "can.h" + +UNS8 canReceive(CAN_HANDLE fd0, Message *m); +UNS8 canSend(CAN_HANDLE fd0, Message *m); +CAN_HANDLE canOpen(s_BOARD *board); +int canClose(CAN_HANDLE fd0); +void canReceiveLoop(CAN_HANDLE fd0); + +void led_set_redgreen(unsigned char bits); + +int nvram_open(void); +void nvram_close(void); +char nvram_write(int type, int access_attr, void *data); +char nvram_read(int type, int access_attr, void *data); + +#include "data.h" + +struct struct_s_BOARD { + char * busname; + int baudrate; + CO_Data * d; +}; + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/can_peak/cancfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can_peak/cancfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,29 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __CANCFG_H__ +#define __CANCFG_H__ + +#include "libpcan.h" // for Baudrates defines +#define CAN_HANDLE void* + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/can_virtual/cancfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can_virtual/cancfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,28 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __CANCFG_H__ +#define __CANCFG_H__ + +#define CAN_HANDLE void* + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/data.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/data.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,164 @@ +/* +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 __data_h__ +#define __data_h__ + +// declaration of CO_Data type let us include all necessary headers +// struct struct_CO_Data can then be defined later +typedef struct struct_CO_Data CO_Data; + +#include +#include "def.h" +#include "can.h" +#include "objdictdef.h" +#include "objacces.h" +#include "sdo.h" +#include "pdo.h" +#include "states.h" +#include "lifegrd.h" +#include "sync.h" +#include "nmtMaster.h" + +// This structurs contains all necessary information for a CanOpen node +struct struct_CO_Data { + // Object dictionary + UNS8 *bDeviceNodeId; + const indextable *objdict; + UNS8 *count_sync; + quick_index *firstIndex; + quick_index *lastIndex; + UNS16 *ObjdictSize; + const UNS8 *iam_a_slave; + valueRangeTest_t valueRangeTest; + + // SDO + s_transfer transfers[SDO_MAX_SIMULTANEOUS_TRANSFERTS]; + SDOtimeoutError_t SDOtimeoutError; + //s_sdo_parameter *sdo_parameters; + + // State machine + e_nodeState nodeState; + s_state_communication CurrentCommunicationState; + initialisation_t initialisation; + preOperational_t preOperational; + operational_t operational; + stopped_t stopped; + + // NMT-heartbeat + UNS8 *ConsumerHeartbeatCount; + UNS32 *ConsumerHeartbeatEntries; + TIMER_HANDLE *ConsumerHeartBeatTimers; + UNS16 *ProducerHeartBeatTime; + TIMER_HANDLE ProducerHeartBeatTimer; + heartbeatError_t heartbeatError; + e_nodeState NMTable[NMT_MAX_NODE_ID]; + + // SYNC + TIMER_HANDLE syncTimer; + UNS32 *COB_ID_Sync; + UNS32 *Sync_Cycle_Period; + /*UNS32 *Sync_window_length*/; + post_sync_t post_sync; + post_TPDO_t post_TPDO; + + // PDO + s_process_var process_var; + + // General + UNS8 toggle; + canSend_t canSend; + scanIndexOD_t scanIndexOD; +}; + +// A macro to initialize the data in client app. +#define CANOPEN_NODE_DATA_INITIALIZER(NODE_PREFIX) {\ + /* Object dictionary*/\ + bDeviceNodeId:& NODE_PREFIX ## _bDeviceNodeId,\ + objdict: NODE_PREFIX ## _objdict,\ + count_sync: NODE_PREFIX ## _count_sync,\ + firstIndex: & NODE_PREFIX ## _firstIndex,\ + lastIndex: & NODE_PREFIX ## _lastIndex,\ + ObjdictSize: & NODE_PREFIX ## _ObjdictSize,\ + iam_a_slave: & NODE_PREFIX ## _iam_a_slave,\ + valueRangeTest: NODE_PREFIX ## _valueRangeTest,\ + \ + /* SDO */\ + transfers:{{\ + nodeId: 0,\ + index: 0,\ + subIndex: 0,\ + state: SDO_RESET,\ + toggle: 0,\ + count: 0,\ + offset: 0,\ + data: {0,},\ + dataType: 0,\ + timer: -1},},\ + SDOtimeoutError: &NODE_PREFIX ## _SDOtimeoutError,\ + \ + /* State machine */\ + nodeState:Unknown_state,\ + CurrentCommunicationState:{\ + csBoot_Up: 0,\ + csSDO: 0,\ + csEmergency: 0,\ + csSYNC: 0,\ + csHeartbeat: 0,\ + csPDO: 0},\ + initialisation: &NODE_PREFIX ## _initialisation,\ + preOperational: &NODE_PREFIX ## _preOperational,\ + operational: &NODE_PREFIX ## _operational,\ + stopped: &NODE_PREFIX ## _stopped,\ + \ + /* NMT-heartbeat */\ + ConsumerHeartbeatCount: & NODE_PREFIX ## _highestSubIndex_obj1016,\ + ConsumerHeartbeatEntries: NODE_PREFIX ## _obj1016,\ + ConsumerHeartBeatTimers: NODE_PREFIX ## _heartBeatTimers,\ + ProducerHeartBeatTime: & NODE_PREFIX ## _obj1017,\ + ProducerHeartBeatTimer: TIMER_NONE,\ + heartbeatError: NODE_PREFIX ## _heartbeatError,\ + NMTable:{Unknown_state,},\ + \ + /* SYNC */\ + syncTimer: TIMER_NONE,\ + COB_ID_Sync: & NODE_PREFIX ## _obj1005,\ + Sync_Cycle_Period: & NODE_PREFIX ## _obj1006,\ + /*Sync_window_length: & NODE_PREFIX ## _obj1007,*/\ + post_sync: NODE_PREFIX ## _post_sync,\ + post_TPDO: NODE_PREFIX ## _post_TPDO,\ + \ + /* PDO */\ + process_var: {\ + count: 0,\ + data: {0,}},\ + \ + /* General */\ + toggle: 0,\ + canSend: NODE_PREFIX ## _canSend,\ + scanIndexOD: NODE_PREFIX ## _scanIndexOD\ +} + +#endif // __data_h__ + + diff -r 000000000000 -r 4472ee7c6c3e include/def.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/def.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,126 @@ +/* +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 __def_h__ +#define __def_h__ + +#include "config.h" + +/** definitions used for object dictionary access. ie SDO Abort codes . (See DS 301 v.4.02 p.48) + */ +#define OD_SUCCESSFUL 0x00000000 +#define OD_READ_NOT_ALLOWED 0x06010001 +#define OD_WRITE_NOT_ALLOWED 0x06010002 +#define OD_NO_SUCH_OBJECT 0x06020000 +#define OD_NOT_MAPPABLE 0x06040041 +#define OD_LENGTH_DATA_INVALID 0x06070010 +#define OD_NO_SUCH_SUBINDEX 0x06090011 +#define OD_VALUE_TOO_LOW 0x06090031 /* Value range test result */ +#define OD_VALUE_TOO_HIGH 0x06090032 /* Value range test result */ +/* Others SDO abort codes + */ +#define SDOABT_TOGGLE_NOT_ALTERNED 0x05030000 +#define SDOABT_TIMED_OUT 0x05040000 +#define SDOABT_OUT_OF_MEMORY 0x05040005 /* Size data exceed SDO_MAX_LENGTH_TRANSFERT */ +#define SDOABT_GENERAL_ERROR 0x08000000 /* Error size of SDO message */ +#define SDOABT_LOCAL_CTRL_ERROR 0x08000021 + +/******************** CONSTANTS ****************/ + +/** Constantes which permit to define if a PDO frame + is a request one or a data one +*/ +/* Should not be modified */ +#define REQUEST 1 +#define NOT_A_REQUEST 0 + +/// Misc constants +// -------------- +/* Should not be modified */ +#define Rx 0 +#define Tx 1 +#define TRUE 1 +#define FALSE 0 + +//TODO: remove this limitation. do bit granularity mapping +#define PDO_MAX_LEN 8 + +/** Status of the SDO transmission + */ +#define SDO_RESET 0x0 // Transmission not started. Init state. +#define SDO_FINISHED 0x1 // data are available +#define SDO_ABORTED_RCV 0x80 // Received an abort message. Data not available +#define SDO_ABORTED_INTERNAL 0x85 // Aborted but not because of an abort message. +#define SDO_DOWNLOAD_IN_PROGRESS 0x2 +#define SDO_UPLOAD_IN_PROGRESS 0x3 + +// Status of the node during the SDO transfert : +#define SDO_SERVER 0x1 +#define SDO_CLIENT 0x2 +#define SDO_UNKNOWN 0x3 + +/* Function Codes + --------------- + defined in the canopen DS301 +*/ +#define NMT 0x0 +#define SYNC 0x1 +#define TIME_STAMP 0x2 +#define PDO1tx 0x3 +#define PDO1rx 0x4 +#define PDO2tx 0x5 +#define PDO2rx 0x6 +#define PDO3tx 0x7 +#define PDO3rx 0x8 +#define PDO4tx 0x9 +#define PDO4rx 0xA +#define SDOtx 0xB +#define SDOrx 0xC +#define NODE_GUARD 0xE + +/// NMT Command Specifier, sent by master to change a slave state +// ------------------------------------------------------------- +/* Should not be modified */ +#define NMT_Start_Node 0x01 +#define NMT_Stop_Node 0x02 +#define NMT_Enter_PreOperational 0x80 +#define NMT_Reset_Node 0x81 +#define NMT_Reset_Comunication 0x82 + +/// constantes used in the different state machines +// ----------------------------------------------- +/* Must not be modified */ +#define state1 0x01 +#define state2 0x02 +#define state3 0x03 +#define state4 0x04 +#define state5 0x05 +#define state6 0x06 +#define state7 0x07 +#define state8 0x08 +#define state9 0x09 +#define state10 0x0A +#define state11 0x0B + +#endif // __def_h__ + diff -r 000000000000 -r 4472ee7c6c3e include/generic/applicfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/generic/applicfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,98 @@ +/* +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 __APPLICFG_LINUX__ +#define __APPLICFG_LINUX__ + +#include +#include + +#include "cancfg.h" +#include "timerscfg.h" + +// Define the architecture : little_endian or big_endian +// ----------------------------------------------------- +// Test : +// UNS32 v = 0x1234ABCD; +// char *data = &v; +// +// Result for a little_endian architecture : +// data[0] = 0xCD; +// data[1] = 0xAB; +// data[2] = 0x34; +// data[3] = 0x12; +// +// Result for a big_endian architecture : +// data[0] = 0x12; +// data[1] = 0x34; +// data[2] = 0xAB; +// data[3] = 0xCD; + +// Integers +#define INTEGER8 char +#define INTEGER16 short +#define INTEGER24 +#define INTEGER32 long +#define INTEGER40 +#define INTEGER48 +#define INTEGER56 +#define INTEGER64 + +// Unsigned integers +#define UNS8 unsigned char +#define UNS16 unsigned short +#define UNS32 unsigned long +#define UNS24 +#define UNS40 +#define UNS48 +#define UNS56 +#define UNS64 + +// Reals +#define REAL32 float +#define REAL64 double + +/// Definition of error and warning macros +// -------------------------------------- +#if defined DEBUG_ERR_CONSOLE_ON || defined DEBUG_WAR_CONSOLE_ON +#include +#endif + +/// Definition of MSG_ERR +// --------------------- +#ifdef DEBUG_ERR_CONSOLE_ON +# define MSG_ERR(num, str, val)/* \ + printf("%s,%d : 0X%x %s 0X%x \n",__FILE__, __LINE__,num, str, val);*/ +#else +# define MSG_ERR(num, str, val) +#endif + +/// Definition of MSG_WAR +// --------------------- +#ifdef DEBUG_WAR_CONSOLE_ON +# define MSG_WAR(num, str, val)/* \ + printf("%s,%d : 0X%x %s 0X%x \n",__FILE__, __LINE__,num, str, val);*/ +#else +# define MSG_WAR(num, str, val) +#endif + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/applicfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/applicfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,193 @@ +/* +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 __APPLICFG_HC12__ +#define __APPLICFG_HC12__ + +#include +#include + +#include <../include/hcs12/asm-m68hc12/portsaccess.h> +#include <../include/hcs12/asm-m68hc12/ports_def.h> +#include <../include/hcs12/asm-m68hc12/ports.h> +#include <../include/hcs12/interrupt.h> + + +/// Define the architecture : little_endian or big_endian +// ----------------------------------------------------- +// Test : +// UNS32 v = 0x1234ABCD; +// char *data = &v; +// +// Result for a little_endian architecture : +// data[0] = 0xCD; +// data[1] = 0xAB; +// data[2] = 0x34; +// data[3] = 0x12; +// +// Result for a big_endian architecture : +// data[0] = 0x12; +// data[1] = 0x34; +// data[2] = 0xAB; +// data[3] = 0xCD; + + +#define CANOPEN_BIG_ENDIAN + +// Use or not the PLL +//#define USE_PLL + +#ifdef USE_PLL +# define BUS_CLOCK 24 // If the quartz on the board is 16 MHz. If different, change this value +#else +# define BUS_CLOCK 8 // If the quartz on the board is 16 MHz. If different, change this value +#endif + +/// Configuration of the serials port SCI0 and SCI1 +// Tested : +// SERIAL_SCI0_BAUD_RATE 9600 BUS_CLOCK 8 Send OK Receive not tested +// SERIAL_SCI0_BAUD_RATE 19200 BUS_CLOCK 8 Send OK Receive not tested +// SERIAL_SCI0_BAUD_RATE 38400 BUS_CLOCK 8 Send OK Receive not tested +// SERIAL_SCI0_BAUD_RATE 57600 BUS_CLOCK 8 Send Failed Receive not tested +// SERIAL_SCI0_BAUD_RATE 115200 BUS_CLOCK 8 Send Failed Receive not tested + +// SERIAL_SCI0_BAUD_RATE 9600 BUS_CLOCK 24 Send OK Receive not tested +// SERIAL_SCI0_BAUD_RATE 19200 BUS_CLOCK 24 Send OK Receive not tested +// SERIAL_SCI0_BAUD_RATE 38400 BUS_CLOCK 24 Send OK but init problems Receive not tested +// SERIAL_SCI0_BAUD_RATE 57600 BUS_CLOCK 24 Send Failed Receive not tested +// SERIAL_SCI0_BAUD_RATE 115200 BUS_CLOCK 24 Send Failed Receive not tested + +#define SERIAL_SCI0_BAUD_RATE 19200 +#define SERIAL_SCI1_BAUD_RATE 9600 + + + + + + +// Several hardware definitions functions +// -------------------------------------- + + +/// Initialisation of the serial port 0 +extern void initSCI_0 (void); + +/// Initialisation of the serial port 1 +extern void initSCI_1 (void); + +/// Convert an integer to a string in hexadecimal format +/// If you do not wants to use a lastCar, put lastCar = '\0' (end of string) +/// ex : value = 0XABCDEF and lastCar = '\n' +/// buf[0] = '0' +/// buf[1] = 'X' +/// buf[2] = 'A' +/// .... +/// buf[7] = 'F' +/// buf[8] = '\n' +/// buf[9] = '\0' +extern char * +hex_convert (char *buf, unsigned long value, char lastCar); + +/// Print the string to the serial port sci +/// (sci takes the values SCI0 or SCI1) +extern void printSCI_str (char sci, const char * str); + +/// Print the number in hexadecimal to the serial port sci +/// (sci takes the values SCI0 or SCI1) +extern void printSCI_nbr (char sci, unsigned long nbr, char lastCar); + +/// to start using the PLL. Bus clock becomes 24 MHz if the quartz +/// on the board is at 16 MHz +extern void initPLL (void); + +/// Put here all the code to init the HCS12 +extern void initHCS12 (void); + +// Integers +#define INTEGER8 signed char +#define INTEGER16 short +#define INTEGER24 +#define INTEGER32 long +#define INTEGER40 +#define INTEGER48 +#define INTEGER56 +#define INTEGER64 + +// Unsigned integers +#define UNS8 unsigned char +#define UNS16 unsigned short +#define UNS32 unsigned long +#define UNS24 +#define UNS40 +#define UNS48 +#define UNS56 +#define UNS64 + +// Whatever your microcontroller, the timer wont work if +// TIMEVAL is not at least on 32 bits +#define TIMEVAL UNS32 + +// The timer of the hcs12 counts from 0000 to 0xFFFF +#define TIMEVAL_MAX 0xFFFF + +// The timer is incrementing every 4 us. +#define MS_TO_TIMEVAL(ms) (ms * 250) +#define US_TO_TIMEVAL(us) (us>>2) + + +// Reals +#define REAL32 float +#define REAL64 double + +#include "can.h" + + +/// Definition of MSG_ERR +// --------------------- +#ifdef DEBUG_ERR_CONSOLE_ON +# define MSG_ERR(num, str, val) \ + initSCI_0(); \ + printSCI_nbr(SCI0, num, ' '); \ + /* large printing on console */ \ + printSCI_str(SCI0, str); \ + printSCI_nbr(SCI0, val, '\n'); +#else +# define MSG_ERR(num, str, val) +#endif + +/// Definition of MSG_WAR +// --------------------- +#ifdef DEBUG_WAR_CONSOLE_ON +# define MSG_WAR(num, str, val) \ + initSCI_0(); \ + printSCI_nbr(SCI0, num, ' '); \ + /* large printing on console */ \ + printSCI_str(SCI0, str); \ + printSCI_nbr(SCI0, val, '\n'); +#else +# define MSG_WAR(num, str, val) +#endif + + +#endif + + diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/asm-m68hc12/ports.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/asm-m68hc12/ports.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,245 @@ +/* +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 +*/ +/* m68hc11/ports.h -- Definition of 68HC11 ports + Copyright 1999, 2000 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@worldnet.fr) + +This file is part of GDB, GAS, and the GNU binutils. + +GDB, GAS, and the GNU binutils are free software; you can redistribute +them and/or modify them under the terms of the GNU General Public +License as published by the Free Software Foundation; either version +1, or (at your option) any later version. + +GDB, GAS, and the GNU binutils are distributed in the hope that they +will be useful, but WITHOUT ANY WARRANTY; without even the implied +warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this file; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + +// Revised francis.dupin@inrets.fr 2003-07 + +#ifndef _M68HC11_PORTS_H +#define _M68HC11_PORTS_H + + + +#include + +/* Prototypes */ + unsigned short get_timer_counter (void); +void set_timer_counter (unsigned short value); +void cop_reset (void); + + +/* Must me adapted to hc12 +void timer_acknowledge (void); +void timer_initialize_rate (unsigned char divisor); +void set_bus_expanded (void); +void set_bus_single_chip (void); +unsigned short * get_input_capture_1 (void); +void set_input_capture_1 (unsigned short value); +unsigned short * get_input_capture_2 (void); +void set_input_capture_2 (unsigned short value); +unsigned short * get_input_capture_3 (void); +void set_input_capture_3 (unsigned short value); +unsigned short * get_output_compare_1 (void); +void set_output_compare_1 (unsigned short value); +unsigned short * get_output_compare_2 (void); +void set_output_compare_2 (unsigned short value); +unsigned short * get_output_compare_3 (void); +void set_output_compare_3 (unsigned short value); +unsigned short * get_output_compare_4 (void); +void set_output_compare_4 (unsigned short value); +unsigned short * get_output_compare_5 (void); +void set_output_compare_5 (unsigned short value); +*/ + + +extern inline unsigned short +get_timer_counter (void) +{ + return ((unsigned volatile short*) &_io_ports[TCNTH])[0]; +} + +extern inline void +set_timer_counter (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[TCNTH])[0] = value; +} + + +/* Reset the COP. */ +extern inline void +cop_reset (void) +{ + _io_ports[ARMCOP] = 0x55; + _io_ports[ARMCOP] = 0xAA; +} + + +#if 0 +/* Acknowledge the timer interrupt. */ +extern inline void +timer_acknowledge (void) +{ + _io_ports[TFLG2] = 0x80; +} + +/* Initialize the timer. */ +extern inline void +timer_initialize_rate (unsigned char divisor) +{ + _io_ports[M6811_TMSK2] = M6811_RTII | divisor; +} + +extern inline void +cop_optional_reset (void) +{ +#if defined(M6811_USE_COP) && M6811_USE_COP == 1 + cop_reset (); +#endif +} + +/* Set the board in the expanded mode to get access to external bus. */ +extern inline void +set_bus_expanded (void) +{ + _io_ports[M6811_HPRIO] |= M6811_MDA; +} + + +/* Set the board in single chip mode. */ +extern inline void +set_bus_single_chip (void) +{ + _io_ports[M6811_HPRIO] &= ~M6811_MDA; +} + +extern inline unsigned short +get_input_capture_1 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TIC1_H])[0]; +} + +extern inline void +set_input_capture_1 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TIC1_H])[0] = value; +} + +extern inline unsigned short +get_input_capture_2 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TIC2_H])[0]; +} + +extern inline void +set_input_capture_2 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TIC2_H])[0] = value; +} + +extern inline unsigned short +get_input_capture_3 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TIC3_H])[0]; +} + +extern inline void +set_input_capture_3 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TIC3_H])[0] = value; +} + +/* Get output compare 16-bit register. */ +extern inline unsigned short +get_output_compare_1 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TOC1_H])[0]; +} + +extern inline void +set_output_compare_1 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TOC1_H])[0] = value; +} + +extern inline unsigned short +get_output_compare_2 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TOC2_H])[0]; +} + +extern inline void +set_output_compare_2 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TOC2_H])[0] = value; +} + +extern inline unsigned short +get_output_compare_3 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TOC3_H])[0]; +} + +extern inline void +set_output_compare_3 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TOC3_H])[0] = value; +} + +extern inline unsigned short +get_output_compare_4 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TOC4_H])[0]; +} + +extern inline void +set_output_compare_4 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TOC4_H])[0] = value; +} + +extern inline unsigned short +get_output_compare_5 (void) +{ + return ((unsigned volatile short*) &_io_ports[M6811_TOC5_H])[0]; +} + +extern inline void +set_output_compare_5 (unsigned short value) +{ + ((unsigned volatile short*) &_io_ports[M6811_TOC5_H])[0] = value; +} + +#endif + + + + +#endif /* _M68HC11_PORTS_H */ + diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/asm-m68hc12/ports_def.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/asm-m68hc12/ports_def.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,768 @@ +/* +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 +*/ +/* +Definition of the i/o ports of the Motorola HCS12 +*/ + +/* +On HCS12, ports are maped by default at 0X0000. (see ports.s) +It can also be done at link stage with an option in +command line : for example to map at 0X8000 +--defsym _io_ports8=0X8000 --defsym _io_ports16=0X8000 +Or in the file memory.x : +PROVIDE (_io_ports8 = 0X8000); +PROVIDE (_io_ports16 = 0X8000); +(see portsaccess.h) +I wonder if the value in INITRG must not be changed too +at run time. +*/ + +#ifndef __HCS12_PORTS__ +#define __HCS12_PORTS__ + +#define PORTA 0x0000 +#define PORTB 0x0001 +#define DDRA 0x0002 +#define DDRB 0x0003 + +#define PORTE 0x0008 +#define DDRE 0x0009 +#define PEAR 0x000A +#define MODE 0x000B +#define PUCR 0x000C +#define RDRIV 0x000D +#define EBICTL 0x000E + +#define INITRM 0x0010 +#define INITRG 0x0011 +#define INITEE 0x0012 +#define MISC 0x0013 +#define MTST0 0x0014 +#define ITCR 0x0015 +#define ITEST 0x0016 +#define MTST1 0x0017 + +#define PARTIDH 0x001A +#define PARTIDL 0x001B +#define MEMSIZ0 0x001C +#define MEMSIZ1 0x001D +#define INTCR 0x001E +#define HPRIO 0x001F + +#define BKPCT0 0x0028 +#define BKPCT1 0x0029 +#define BKP0X 0x002A +#define BKP0H 0x002B +#define BKP0L 0x002C +#define BKP1X 0x002D +#define BKP1H 0x002E +#define BKP1L 0x002F +#define PPAGE 0x0030 + +#define PORTK 0x0032 +#define DDRK 0x0033 +#define SYNR 0x0034 +#define REFDV 0x0035 +#define CTFLG 0x0036 +#define CRGFLG 0x0037 +#define CRGINT 0x0038 +#define CLKSEL 0x0039 +#define PLLCTL 0x003A +#define RTICTL 0x003B +#define COPCTL 0x003C +#define FORBYP 0x003D +#define CTCTL 0x003E +#define ARMCOP 0x003F +#define TIOS 0x0040 +#define TCFORC 0x0041 +#define TOC7M 0x0042 +#define TOC7D 0x0043 +#define TCNTH 0x0044 +#define TCNTL 0x0045 +#define TSCR1 0x0046 +#define TTOV 0x0047 +#define TCTL1 0x0048 +#define TCTL2 0x0049 +#define TCTL3 0x004A +#define TCTL4 0x004B +#define TIE 0x004C +#define TSCR2 0x004D +#define TFLG1 0x004E +#define TFLG2 0x004F +#define TC0H 0x0050 +#define TC0L 0x0051 +#define TC1H 0x0052 +#define TC1L 0x0053 +#define TC2H 0x0054 +#define TC2L 0x0055 +#define TC3H 0x0056 +#define TC3L 0x0057 +#define TC4H 0x0058 +#define TC4L 0x0059 +#define TC5H 0x005A +#define TC5L 0x005B +#define TC6H 0x005C +#define TC6L 0x005D +#define TC7H 0x005E +#define TC7L 0x005F +#define PACTL 0x0060 +#define PAFLG 0x0061 +#define PACN3H 0x0062 +#define PACN2L 0x0063 +#define PACN1H 0x0064 +#define PACN0L 0x0065 +#define MCCTL 0x0066 +#define MCFLG 0x0067 +#define ICPAR 0x0068 +#define DLYCT 0x0069 +#define ICOVW 0x006A +#define ICSYS 0x006B + +#define TIMTST 0x006D + +#define PBCTL 0x0070 +#define PBFLG 0x0071 +#define PA3H 0x0072 +#define PA2H 0x0073 +#define PA1H 0x0074 +#define PA0H 0x0075 +#define MCCNTH 0x0076 +#define MCCNTL 0x0077 +#define TC0HH 0x0078 +#define TC0HL 0x0079 +#define TC1HH 0x007A +#define TC1HL 0x007B +#define TC2HH 0x007C +#define TC2HL 0x007D +#define TC3HH 0x007E + +#define ATD0CTL0 0x0080 +#define ATD00CTL1 0x0081 +#define ATD0CTL2 0x0082 +#define ATD0CTL3 0x0083 +#define ATD0CTL4 0x0084 +#define ATD0CTL5 0x0085 +#define ATD0STAT0 0x0086 +#define ATD0STAT1 0x0087 +#define ATD0TEST0 0x0088 +#define ATD0TEST1 0x0089 + +#define ATD0DIEN 0x008D + +#define PORTAD0 0x008F +#define ATD0DR0H 0x0090 +#define ATD0DR0L 0x0091 +#define ATD0DR1H 0x0092 +#define ATD0DR1L 0x0093 +#define ATD0DR2H 0x0094 +#define ATD0DR2L 0x0095 +#define ATD0DR3H 0x0096 +#define ATD0DR3L 0x0097 +#define ATD0DR4H 0x0098 +#define ATD0DR4L 0x0099 +#define ATD0DR5H 0x009A +#define ATD0DR5L 0x009B +#define ATD0DR6H 0x009C +#define ATD0DR6L 0x009D +#define ATD0DR7H 0x009E +#define ATD0DR7L 0x009F +#define PWME 0x00A0 +#define PWMPOL 0x00A1 +#define PWMCLK 0x00A2 +#define PWMPRCLK 0x00A3 +#define PWMCAE 0x00A4 +#define PWMCTL 0x00A5 +#define PWMTST 0x00A6 +#define PWMPRSC 0x00A7 +#define PWMSCLA 0x00A8 +#define PWMSCLB 0x00A9 +#define PWMSCNTA 0x00AA +#define PWMSCNTB 0x00AB +#define PWMCNT0 0x00AC +#define PWMCNT1 0x00AD +#define PWMCNT2 0x00AE +#define PWMCNT3 0x00AF +#define PWMCNT4 0x00B0 +#define PWMCNT5 0x00B1 +#define PWMCNT6 0x00B2 +#define PWMCNT7 0x00B3 +#define PWMPER0 0x00B4 +#define PWMPER1 0x00B5 +#define PWMPER2 0x00B6 +#define PWMPER3 0x00B7 +#define PWMPER4 0x00B8 +#define PWMPER5 0x00B9 +#define PWMPER6 0x00BA +#define PWMPER7 0x00BB +#define PWMDTY0 0x00BC +#define PWMDTY1 0x00BD +#define PWMDTY2 0x00BE +#define PWMDTY3 0x00BF +#define PWMDTY4 0x00C0 +#define PWMDTY5 0x00C1 +#define PWMDTY6 0x00C2 +#define PWMDTY7 0x00C3 +#define PWMSDN 0x00C4 + +#define SCI0BDH 0x00C8 +#define SCI0BDL 0x00C9 +#define SC0CR1 0x00CA +#define SCI0CR2 0x00CB +#define SCI0SR1 0x00CC +#define SC0SR2 0x00CD +#define SCI0DRH 0x00CE +#define SCI0DRL 0x00CF +#define SCI1BDH 0x00D0 +#define SCI1BDL 0x00D1 +#define SC1CR1 0x00D2 +#define SCI1CR2 0x00D3 +#define SCI1SR1 0x00D4 +#define SC1SR2 0x00D5 +#define SCI1DRH 0x00D6 +#define SCI1DRL 0x00D7 +#define SPI0CR1 0x00D8 +#define SPI0CR2 0x00D9 +#define SPI0BR 0x00DA +#define SPI0SR 0x00DB + +#define SPI0DR 0x00DD + +#define IBAD 0x00E0 +#define IBFD 0x00E1 +#define IBCR 0x00E2 +#define IBSR 0x00E3 +#define IICDR 0x00E4 + +#define DLCBCR1 0x00E8 +#define DLCBSVR 0x00E9 +#define DLCBCR2 0x00EA +#define DLCBDR 0x00EB +#define DLCBARD 0x00EC +#define DLCBRSR 0x00ED +#define DLCSCR 0x00EE +#define DLCBSTAT 0x00EF +#define SPI1CR1 0x00F0 +#define SPI1CR2 0x00F1 +#define SPI1BR 0x00F2 +#define SPI1SR 0x00F3 + +#define SPI1DR 0x00F5 + +#define SPI2CR1 0x00F8 +#define SPI2CR2 0x00F9 +#define SPI2BR 0x00FA +#define SPI2SR 0x00FB + +#define SPI2DR 0x00FD + +#define FCLKDIV 0x0100 +#define FSEC 0x0101 + +#define FCNFG 0x0103 +#define FPROT 0x0104 +#define FSTAT 0x0105 +#define FCMD 0x0106 + +#define ECLKDIV 0x0110 + +#define ECNFG 0x0113 +#define EPROT 0x0114 +#define ESTAT 0x0115 +#define ECMD 0x0116 + +#define ATD1CTL0 0x0120 +#define ATD1CTL1 0x0121 +#define ATD1CTL2 0x0122 +#define ATD1CTL3 0x0123 +#define ATD1CTL4 0x0124 +#define ATD1CTL5 0x0125 +#define ATD1STAT0 0x0126 +#define ATD1STAT1 0x0127 +#define ATD1TEST0 0x0128 +#define ATD1TEST1 0x0129 + +#define ATDDIEN 0x012D + +#define PORTAD1 0x012F +#define ATD1DR0H 0x0130 +#define ATD1DR0L 0x0131 +#define ATD1DR1H 0x0132 +#define ATD1DR1L 0x0133 +#define ATD1DR2H 0x0134 +#define ATD1DR2L 0x0135 +#define ATD1DR3H 0x0136 +#define ATD1DR3L 0x0137 +#define ATD1DR4H 0x0138 +#define ATD1DR4L 0x0139 +#define ATD1DR5H 0x013A +#define ATD1DR5L 0x013B +#define ATD1DR6H 0x013C +#define ATD1DR6L 0x013D +#define ATD1DR7H 0x013E +#define ATD1DR7L 0x013F +#define CAN0CTL0 0x0140 +#define CAN0CTL1 0x0141 +#define CAN0BTR0 0x0142 +#define CAN0BTR1 0x0143 +#define CAN0RFLG 0x0144 +#define CAN0RIER 0x0145 +#define CAN0TFLG 0x0146 +#define CAN0TIER 0x0147 +#define CAN0TARQ 0x0148 +#define CAN0TAAK 0x0149 +#define CAN0TBSEL 0x014A +#define CAN0IDAC 0x014B + +#define CAN0RXERR 0x014E +#define CAN0TXERR 0x014F +#define CAN0IDAR0 0x0150 +#define CAN0IDAR1 0x0151 +#define CAN0IDAR2 0x0152 +#define CAN0IDAR3 0x0153 +#define CAN0IDMR0 0x0154 +#define CAN0IDMR1 0x0155 +#define CAN0IDMR2 0x0156 +#define CAN0IDMR3 0x0157 +#define CAN0IDAR4 0x0158 +#define CAN0IDAR5 0x0159 +#define CAN0IDAR6 0x015A +#define CAN0IDAR7 0x015B +#define CAN0IDMR4 0x015C +#define CAN0IDMR5 0x015D +#define CAN0IDMR6 0x015E +#define CAN0IDMR7 0x015F +#define CAN0RXFG0 0x0160 +#define CAN0RXFG1 0x0161 +#define CAN0RXFG2 0x0162 +#define CAN0RXFG3 0x0163 +#define CAN0RXFG4 0x0164 +#define CAN0RXFG5 0x0165 +#define CAN0RXFG6 0x0166 +#define CAN0RXFG7 0x0167 +#define CAN0RXFG8 0x0168 +#define CAN0RXFG9 0x0169 +#define CAN0RXFGA 0x016A +#define CAN0RXFGB 0x016B +#define CAN0RXFGC 0x016C +#define CAN0RXFGD 0x016D +#define CAN0RXFGE 0x016E +#define CAN0RXFGF 0x016F +#define CAN0TXFG0 0x0170 +#define CAN0TXFG1 0x0171 +#define CAN0TXFG2 0x0172 +#define CAN0TXFG3 0x0173 +#define CAN0TXFG4 0x0174 +#define CAN0TXFG5 0x0175 +#define CAN0TXFG6 0x0176 +#define CAN0TXFG7 0x0177 +#define CAN0TXFG8 0x0178 +#define CAN0TXFG9 0x0179 +#define CAN0TXFGA 0x017A +#define CAN0TXFGB 0x017B +#define CAN0TXFGC 0x017C +#define CAN0TXFGD 0x017D +#define CAN0TXFGE 0x017E +#define CAN0TXFGF 0x017F + +#define CAN1CTL0 0x0180 +#define CAN1CTL1 0x0181 +#define CAN1BTR0 0x0182 +#define CAN1BTR1 0x0183 +#define CAN1RFLG 0x0184 +#define CAN1RIER 0x0185 +#define CAN1TFLG 0x0186 +#define CAN1TIER 0x0187 +#define CAN1TARQ 0x0188 +#define CAN1TAAK 0x0189 +#define CAN1TBSEL 0x018A +#define CAN1IDAC 0x018B +#define CAN1RXERR 0x018E +#define CAN1TXERR 0x018F +#define CAN1IDAR0 0x0190 +#define CAN1IDAR1 0x0191 +#define CAN1IDAR2 0x0192 +#define CAN1IDAR3 0x0193 +#define CAN1IDMR0 0x0194 +#define CAN1IDMR1 0x0195 +#define CAN1IDMR2 0x0196 +#define CAN1IDMR3 0x0197 +#define CAN1IDAR4 0x0198 +#define CAN1IDAR5 0x0199 +#define CAN1IDAR6 0x019A +#define CAN1IDAR7 0x019B +#define CAN1IDMR4 0x019C +#define CAN1IDMR5 0x019D +#define CAN1IDMR6 0x019E +#define CAN1IDMR7 0x019F + +#define CAN1RXFG0 0x01A0 +#define CAN1RXFG1 0x01A1 +#define CAN1RXFG2 0x01A2 +#define CAN1RXFG3 0x01A3 +#define CAN1RXFG4 0x01A4 +#define CAN1RXFG5 0x01A5 +#define CAN1RXFG6 0x01A6 +#define CAN1RXFG7 0x01A7 +#define CAN1RXFG8 0x01A8 +#define CAN1RXFG9 0x01A9 +#define CAN1RXFGA 0x01AA +#define CAN1RXFGB 0x01AB +#define CAN1RXFGC 0x01AC +#define CAN1RXFGD 0x01AD +#define CAN1RXFGE 0x01AE +#define CAN1RXFGF 0x01AF +#define CAN1TXFG0 0x01B0 +#define CAN1TXFG1 0x01B1 +#define CAN1TXFG2 0x01B2 +#define CAN1TXFG3 0x01B3 +#define CAN1TXFG4 0x01B4 +#define CAN1TXFG5 0x01B5 +#define CAN1TXFG6 0x01B6 +#define CAN1TXFG7 0x01B7 +#define CAN1TXFG8 0x01B8 +#define CAN1TXFG9 0x01B9 +#define CAN1TXFGA 0x01BA +#define CAN1TXFGB 0x01BB +#define CAN1TXFGC 0x01BC +#define CAN1TXFGD 0x01BD +#define CAN1TXFGE 0x01BE +#define CAN1TXFGF 0x01BF +#define CAN2CTL0 0x01C0 +#define CAN2CTL1 0x01C1 +#define CAN2BTR0 0x01C2 +#define CAN2BTR1 0x01C3 +#define CAN2RFLG 0x01C4 +#define CAN2RIER 0x01C5 +#define CAN2TFLG 0x01C6 +#define CAN2TIER 0x01C7 +#define CAN2TARQ 0x01C8 +#define CAN2TAAK 0x01C9 +#define CAN2TBSEL 0x01CA +#define CAN2IDAC 0x01CB + +#define CAN2RXERR 0x01CE +#define CAN2TXERR 0x01CF +#define CAN2IDAR0 0x01D0 +#define CAN2IDAR1 0x01D1 +#define CAN2IDAR2 0x01D2 +#define CAN2IDAR3 0x01D3 +#define CAN2IDMR0 0x01D4 +#define CAN2IDMR1 0x01D5 +#define CAN2IDMR2 0x01D6 +#define CAN2IDMR3 0x01D7 +#define CAN2IDAR4 0x01D8 +#define CAN2IDAR5 0x01D9 +#define CAN2IDAR6 0x01DA +#define CAN2IDAR7 0x01DB +#define CAN2IDMR4 0x01DC +#define CAN2IDMR5 0x01DD +#define CAN2IDMR6 0x01DE +#define CAN2IDMR7 0x01DF +#define CAN2RXFG0 0x01E0 +#define CAN2RXFG1 0x01E1 +#define CAN2RXFG2 0x01E2 +#define CAN2RXFG3 0x01E3 +#define CAN2RXFG4 0x01E4 +#define CAN2RXFG5 0x01E5 +#define CAN2RXFG6 0x01E6 +#define CAN2RXFG7 0x01E7 +#define CAN2RXFG8 0x01E8 +#define CAN2RXFG9 0x01E9 +#define CAN2RXFGA 0x01EA +#define CAN2RXFGB 0x01EB +#define CAN2RXFGC 0x01EC +#define CAN2RXFGD 0x01ED +#define CAN2RXFGE 0x01EE +#define CAN2RXFGF 0x01EF +#define CAN2TXFG0 0x01F0 +#define CAN2TXFG1 0x01F1 +#define CAN2TXFG2 0x01F2 +#define CAN2TXFG3 0x01F3 +#define CAN2TXFG4 0x01F4 +#define CAN2TXFG5 0x01F5 +#define CAN2TXFG6 0x01F6 +#define CAN2TXFG7 0x01F7 +#define CAN2TXFG8 0x01F8 +#define CAN2TXFG9 0x01F9 +#define CAN2TXFGA 0x01FA +#define CAN2TXFGB 0x01FB +#define CAN2TXFGC 0x01FC +#define CAN2TXFGD 0x01FD +#define CAN2TXFGE 0x01FE +#define CAN2TXFGF 0x01FF + +#define CAN3CTL0 0x0200 +#define CAN3CTL1 0x0201 +#define CAN3BTR0 0x0202 +#define CAN3BTR1 0x0203 +#define CAN3RFLG 0x0204 +#define CAN3RIER 0x0205 +#define CAN3TFLG 0x0206 +#define CAN3TIER 0x0207 +#define CAN3TARQ 0x0208 +#define CAN3TAAK 0x0209 +#define CAN3TBSEL 0x020A +#define CAN3IDAC 0x020B + +#define CAN3RXERR 0x020E +#define CAN3TXERR 0x020F +#define CAN3IDAR0 0x0210 +#define CAN3IDAR1 0x0211 +#define CAN3IDAR2 0x0212 +#define CAN3IDAR3 0x0213 +#define CAN3IDMR0 0x0214 +#define CAN3IDMR1 0x0215 +#define CAN3IDMR2 0x0216 +#define CAN3IDMR3 0x0217 +#define CAN3IDAR4 0x0218 +#define CAN3IDAR5 0x0219 +#define CAN3IDAR6 0x021A +#define CAN3IDAR7 0x021B +#define CAN3IDMR4 0x021C +#define CAN3IDMR5 0x021D +#define CAN3IDMR6 0x021E +#define CAN3IDMR7 0x021F + +#define CAN3RXFG0 0x0220 +#define CAN3RXFG1 0x0221 +#define CAN3RXFG2 0x0222 +#define CAN3RXFG3 0x0223 +#define CAN3RXFG4 0x0224 +#define CAN3RXFG5 0x0225 +#define CAN3RXFG6 0x0226 +#define CAN3RXFG7 0x0227 +#define CAN3RXFG8 0x0228 +#define CAN3RXFG9 0x0229 +#define CAN3RXFGA 0x022A +#define CAN3RXFGB 0x022B +#define CAN3RXFGC 0x022C +#define CAN3RXFGD 0x022D +#define CAN3RXFGE 0x022E +#define CAN3RXFGF 0x022F +#define CAN3TXFG0 0x0230 +#define CAN3TXFG1 0x0231 +#define CAN3TXFG2 0x0232 +#define CAN3TXFG3 0x0233 +#define CAN3TXFG4 0x0234 +#define CAN3TXFG5 0x0235 +#define CAN3TXFG6 0x0236 +#define CAN3TXFG7 0x0237 +#define CAN3TXFG8 0x0238 +#define CAN3TXFG9 0x0239 +#define CAN3TXFGA 0x023A +#define CAN3TXFGB 0x023B +#define CAN3TXFGC 0x023C +#define CAN3TXFGD 0x023D +#define CAN3TXFGE 0x023E +#define CAN3TXFGF 0x023F + +#define PTT 0x0240 +#define PTIT 0x0241 +#define DDRT 0x0242 +#define RDRT 0x0243 +#define PERT 0x0244 +#define PPST 0x0245 + +#define PTS 0x0248 +#define PTIS 0x0249 +#define DDRS 0x024A +#define RDRS 0x024B +#define PERS 0x024C +#define PPSS 0x024D +#define WOMS 0x024E + +#define PTM 0x0250 +#define PTIM 0x0251 +#define DDRM 0x0252 +#define RDRM 0x0253 +#define PERM 0x0254 +#define PPSM 0x0255 +#define WOMM 0x0256 + +#define PTP 0x0258 +#define PTIP 0x0259 +#define DDRP 0x025A +#define RDRP 0x025B +#define PERP 0x025C +#define PPSP 0x025D +#define PIEP 0x025E +#define PIFP 0x025F +#define PTH 0x0260 +#define PTIH 0x0261 +#define DDRH 0x0262 +#define RDRH 0x0263 +#define PERH 0x0264 +#define PPSH 0x0265 +#define PIEH 0x0266 +#define PIFH 0x0267 +#define PTJ 0x0268 +#define PTIJ 0x0269 +#define DDRJ 0x026A +#define RDRJ 0x026B +#define PERJ 0x026C +#define PPSJ 0x026D +#define PIEJ 0x026E +#define PIFJ 0x026F + +#define CAN4CTL0 0x0280 +#define CAN4CTL1 0x0281 +#define CAN4BTR0 0x0282 +#define CAN4BTR1 0x0283 +#define CAN4RFLG 0x0284 +#define CAN4RIER 0x0285 +#define CAN4TFLG 0x0286 +#define CAN4TIER 0x0287 +#define CAN4TARQ 0x0288 +#define CAN4TAAK 0x0289 +#define CAN4TBSEL 0x028A +#define CAN4IDAC 0x028B + +#define CAN4RXERR 0x028E +#define CAN4TXERR 0x028F +#define CAN4IDAR0 0x0290 +#define CAN4IDAR1 0x0291 +#define CAN4IDAR2 0x0292 +#define CAN4IDAR3 0x0293 +#define CAN4IDMR0 0x0294 +#define CAN4IDMR1 0x0295 +#define CAN4IDMR2 0x0296 +#define CAN4IDMR3 0x0297 +#define CAN4IDAR4 0x0298 +#define CAN4IDAR5 0x0299 +#define CAN4IDAR6 0x029A +#define CAN4IDAR7 0x029B +#define CAN4IDMR4 0x029C +#define CAN4IDMR5 0x029D +#define CAN4IDMR6 0x029E +#define CAN4IDMR7 0x029F + +#define CAN4RXFG0 0x02A0 +#define CAN4RXFG1 0x02A1 +#define CAN4RXFG2 0x02A2 +#define CAN4RXFG3 0x02A3 +#define CAN4RXFG4 0x02A4 +#define CAN4RXFG5 0x02A5 +#define CAN4RXFG6 0x02A6 +#define CAN4RXFG7 0x02A7 +#define CAN4RXFG8 0x02A8 +#define CAN4RXFG9 0x02A9 +#define CAN4RXFGA 0x02AA +#define CAN4RXFGB 0x02AB +#define CAN4RXFGC 0x02AC +#define CAN4RXFGD 0x02AD +#define CAN4RXFGE 0x02AE +#define CAN4RXFGF 0x02AF +#define CAN4TXFG0 0x02B0 +#define CAN4TXFG1 0x02B1 +#define CAN4TXFG2 0x02B2 +#define CAN4TXFG3 0x02B3 +#define CAN4TXFG4 0x02B4 +#define CAN4TXFG5 0x02B5 +#define CAN4TXFG6 0x02B6 +#define CAN4TXFG7 0x02B7 +#define CAN4TXFG8 0x02B8 +#define CAN4TXFG9 0x02B9 +#define CAN4TXFGA 0x02BA +#define CAN4TXFGB 0x02BB +#define CAN4TXFGC 0x02BC +#define CAN4TXFGD 0x02BD +#define CAN4TXFGE 0x02BE +#define CAN4TXFGF 0x02BF + + + +/*********************************************** +Constants for MSCAN +************************************************ +*/ + +#define CAN0 0x0140 /* First address for MSCAN0 */ +#define CAN1 0x0180 /* First address for MSCAN1 */ +#define CAN2 0x01C0 /* First address for MSCAN2 */ +#define CAN3 0x0200 /* First address for MSCAN3 */ +#define CAN4 0x0280 /* First address for MSCAN4 */ + +#define CANCTL0 0X00 /* Control register 0 */ +#define CANCTL1 0X01 /* Control register 1 */ +#define CANBTR0 0X02 /* Bus timing register 0 */ +#define CANBTR1 0X03 /* Bus timing register 1 */ +#define CANRFLG 0X04 /* Receiver flag register */ +#define CANRIER 0X05 /* Enable interruptions when reception */ +#define CANTFLG 0X06 /* Transmit flag register */ +#define CANTIER 0X07 /* Enable interruptions when transmission */ +#define CANTBSEL 0X0A /* Select foreground buffer for transmit */ +#define CANIDAC 0x0B /* Identifier acceptance control register */ +#define CANIDAR0 0x10 +#define CANIDAR1 0x11 +#define CANIDAR2 0x12 +#define CANIDAR3 0x13 +#define CANIDMR0 0x14 +#define CANIDMR1 0x15 +#define CANIDMR2 0x16 +#define CANIDMR3 0x17 +#define CANIDAR4 0x18 +#define CANIDAR5 0x19 +#define CANIDAR6 0x1A +#define CANIDAR7 0x1B +#define CANIDMR4 0x1C +#define CANIDMR5 0x1D +#define CANIDMR6 0x1E +#define CANIDMR7 0x1F + +/* Received foreground buffer */ +#define CANRCVID 0x20 /* Base of identifier registers */ +#define CANRCVDTA 0x24 /* Base of data registers */ +#define CANRCVLEN 0x2C /* Data length register */ + +/* Transmit foreground buffer */ +#define CANTRSID 0x30 /* Base of identifier registers */ +#define CANTRSDTA 0x34 /* Base of data registers */ +#define CANTRSLEN 0x3C /* Data length register */ +#define CANTRSPRI 0x3D /* Priority register */ + + +/* Constants for serials port */ +#define SCI0 0x00C8 +#define SCI1 0x00D0 + +#define SCIBDH 0x00 +#define SCIBDL 0x01 +#define SCICR1 0x02 +#define SCICR2 0x03 +#define SCISR1 0x04 +#define SCISR2 0x05 +#define SCIDRH 0x06 +#define SCIDRL 0x07 + + +#endif /* __HCS12_PORTS__ */ + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/asm-m68hc12/portsaccess.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/asm-m68hc12/portsaccess.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,49 @@ +/* +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 +*/ +/* +Variables to access to the io_ports +*/ + + +#ifndef __PORTS_ACCESS__ +#define __PORTS_ACCESS__ + +/* +By default the address is 0X0000 on HCS12. +But the ports can be remaped. See the file ports.h +*/ + + +extern volatile unsigned char _io_ports[]; + +/* To use for a 8 bits access */ +#define IO_PORTS_8(adr) \ +_io_ports[adr] + +/* To use for a 16 bits access */ +/* Example : IO_PORTS_16(CAN0IDAR1)= 0xABCD; +will put AB at @CAN0IDAR1 and CD at @CAN0IDAR1 + 1 +*/ +#define IO_PORTS_16(adr) \ +*((unsigned volatile short*) (_io_ports + (adr))) + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/asm-m68hc12/regs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/asm-m68hc12/regs.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,96 @@ +/* +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 +*/ + +/* Regs - Software registers used by GCC + Copyright (C) 2000 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@worldnet.fr) + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file with other programs, and to distribute +those programs without any restriction coming from the use of this +file. (The General Public License restrictions do apply in other +respects; for example, they cover modification of the file, and +distribution when not linked into another program.) + +This file 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _M68HC11_REGS_H +#define _M68HC11_REGS_H + +/* Include this file if you want to have access to the soft registers + used by GCC. The soft registers are memory location. They have + special names that cannot conflict with C or C++ variables. + The extern definition below map those special names to + some usable names in C and C++. */ + +extern unsigned short __tmp __asm__("_.tmp"); +extern unsigned short __z __asm__("_.z"); +extern unsigned short __xy __asm__("_.xy"); +extern unsigned short __frame __asm__("_.frame"); +extern unsigned short __d1 __asm__("_.d1"); +extern unsigned short __d2 __asm__("_.d2"); +extern unsigned short __d3 __asm__("_.d3"); +extern unsigned short __d4 __asm__("_.d4"); +extern unsigned short __d5 __asm__("_.d5"); +extern unsigned short __d6 __asm__("_.d6"); +extern unsigned short __d7 __asm__("_.d7"); +extern unsigned short __d8 __asm__("_.d8"); +extern unsigned short __d9 __asm__("_.d9"); +extern unsigned short __d10 __asm__("_.d10"); +extern unsigned short __d11 __asm__("_.d11"); +extern unsigned short __d12 __asm__("_.d12"); +extern unsigned short __d13 __asm__("_.d13"); +extern unsigned short __d14 __asm__("_.d14"); +extern unsigned short __d15 __asm__("_.d15"); +extern unsigned short __d16 __asm__("_.d16"); +extern unsigned short __d17 __asm__("_.d17"); +extern unsigned short __d18 __asm__("_.d18"); +extern unsigned short __d19 __asm__("_.d19"); +extern unsigned short __d20 __asm__("_.d20"); +extern unsigned short __d21 __asm__("_.d21"); +extern unsigned short __d22 __asm__("_.d22"); +extern unsigned short __d23 __asm__("_.d23"); +extern unsigned short __d24 __asm__("_.d24"); +extern unsigned short __d25 __asm__("_.d25"); +extern unsigned short __d26 __asm__("_.d26"); +extern unsigned short __d27 __asm__("_.d27"); +extern unsigned short __d28 __asm__("_.d28"); +extern unsigned short __d29 __asm__("_.d29"); +extern unsigned short __d30 __asm__("_.d30"); +extern unsigned short __d31 __asm__("_.d31"); +extern unsigned short __d32 __asm__("_.d32"); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/board/alire.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/board/alire.txt Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,2 @@ +Ici, on met ce qui est spécifique à la carte et au type de processeur : +l'organisation de la mémoire \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/board/arch/exit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/board/arch/exit.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,71 @@ +/* +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 +*/ + +/* exit.h - 32K Board specific parameters + Copyright (C) 2002 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@nerim.fr) + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file with other programs, and to distribute +those programs without any restriction coming from the use of this +file. (The General Public License restrictions do apply in other +respects; for example, they cover modification of the file, and +distribution when not linked into another program.) + +This file 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _M68HC11_ARCH_32K_EXIT_H +#define _M68HC11_ARCH_32K_EXIT_H + +extern void _exit (short status) __attribute__((noreturn)); + +/* For the simulator, the wai stops everything and exits with the + error code stored in register d. + + For a real 68HC11, enable interrupts and wait forever. */ +extern inline void +_exit (short status) +{ + /* Use 'd' constraint to force the status to be in the D + register before execution of the asm. */ + while (1) + { + __asm__ __volatile__ ("cli\n" + "wai" : : "d"(status)); + } +} + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/board/arch/interrupts.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/board/arch/interrupts.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,60 @@ +/* +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 +*/ +/* Interrupt Vectors -- ROM mode + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@worldnet.fr) + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file with other programs, and to distribute +those programs without any restriction coming from the use of this +file. (The General Public License restrictions do apply in other +respects; for example, they cover modification of the file, and +distribution when not linked into another program.) + +This file 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _M68HC11_ARCH_32K_INTERRUPTS_H +#define _M68HC11_ARCH_32K_INTERRUPTS_H + +/* For ROM-boards, interrupts are in ROM and are not installed + at run time. Implementation is empty. */ +extern inline void +set_interrupt_handler (interrupt_vector_id id ATTRIBUTE_UNUSED, + interrupt_t handler ATTRIBUTE_UNUSED) +{ +} + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/board/arch/memory.x --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/board/arch/memory.x Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,39 @@ + +/* L'espace mémoire du MCS12DP256 en "Normal single ship */ +/* ----------------------------------------------------- */ +/* 0X0000 - 0X0399 : Registres + 0X0400 - 0X0FFF : 4KO EEPROM + 0X1000 - 0X3FFF : 12KO RAM + 0X4000 - 0XFFFF : 48KO FLASH (accès par pages jusau'à 256 KO + entre 0X8000 et 0XBFFF) + + francis.dupin@inrets.fr +*/ + +/* +---------------------------------------------------------------- +Programme dans la flash, données dans la RAM interne +---------------------------------------------------------------- +*/ + +/* Fixed definition of the available memory banks. + See generic emulation script for a user defined configuration. */ +MEMORY +{ + /* Registres softs utilisés par gcc. Ne jamais modifier */ + page0 (rwx) : ORIGIN = 0x0, LENGTH = 256 + + /* Programme placé en flash, de 4000 à FF00-1 */ + /* (Les vecteurs d'interruption sont en flash entre 0XFF00 et 0XFFFF */ + text (rx) : ORIGIN = 0x4000, LENGTH = 0xFF00 - 0x4000 + + /* Données en RAM (12k), de 0X1000 à 0X3FFF*/ + data : ORIGIN = 0x1000, LENGTH = 0x4000 - 0x1000 +} +/* Setup the stack on the top of the data memory bank. */ +PROVIDE (_stack = 0x3FFF); + + +vectors_addr = 0xff00; + + diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/board/arch/param.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/board/arch/param.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,70 @@ +/* +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 +*/ +/* param.h - 32K Board specific parameters + Copyright (C) 2002 Free Software Foundation, Inc. + Written by Stephane Carrez (stcarrez@worldnet.fr) + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +In addition to the permissions in the GNU General Public License, the +Free Software Foundation gives you unlimited permission to link the +compiled version of this file with other programs, and to distribute +those programs without any restriction coming from the use of this +file. (The General Public License restrictions do apply in other +respects; for example, they cover modification of the file, and +distribution when not linked into another program.) + +This file 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 +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef _M68HC11_ARCH_32K_PARAM_H +#define _M68HC11_ARCH_32K_PARAM_H + +/* Generic 32K board. */ +#define M6811_ARCH_32K + +#undef M6811_DEF_BAUD +#define M6811_DEF_BAUD 0x30 /* 9600 baud. */ + +#undef RAM_SIZE +#define RAM_SIZE 32768 /* 32Kb of memory. */ + +#undef ROM_SIZE +#define ROM_SIZE 32768 /* 32Kb of rom. */ + +#undef DATA_SIZE +#define DATA_SIZE (0x8000-0x1040) /* Data section size. */ + +#undef TEXT_SIZE +#define TEXT_SIZE ROM_SIZE /* Text section size. */ + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/canOpenDriver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/canOpenDriver.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,43 @@ +/* +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 __CANOPENDRIVER__ +#define __CANOPENDRIVER__ + + + +// --------- to be called by user app --------- + +void initTimer(void); +void resetTimer(void); +void TimerLoop(void); + +/** +Returns 0 if no message received, 0xFF if the receiving stack is not empty. +May be call in polling. +You can also call canDispatch(...) in void __attribute__((interrupt)) can0HdlRcv (void) +(see include/hcs12/canOpenDriver.c) + */ +UNS8 f_can_receive(UNS8 notused, Message *m); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/candriver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/candriver.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,350 @@ +/* +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 __CANDRIVER__ +#define __CANDRIVER__ + +//#include DEBUG_CAN + +#include +#include + + +/* +The CAN message received are stored in a fifo stack +We consider one stack for all the 5 can devices. It is a choice ! +*/ + +/* Be free to change this value */ +#define MAX_STACK_MSG_RCV 5 + +/* Number of incomings and outcomings CAN Line. The layer CanOpen must be +used only for ONE line CAN. But you may used one or more CAN drivers, without +a CanOpen layer. +Only 2 lines are implemented. If more lines are needed, copy void __attribute__((interrupt)) can0HdlRcv (void) to void __attribute__((interrupt)) canXHdlRcv (void) and make +changes : [0] to [x], CAN0 to CANX, etc +*/ +#define NB_LINE_CAN 1 + +/* Whose hardware HCS12 CAN block is used for CanOpen ? Chose between CAN0, ..., CAN4 +If you use CANOPEN_LINE_NUMBER_USED = CANI, the value of NB_LINE_CAN must be +more or equal to I + 1 +Value other than CAN0 not tested, but should work fine. + */ +#define CANOPEN_LINE_NUMBER_USED CAN0 + +/* Stack of received messages +MSG received on CAN0 module is stored in stackMsgRcv[0], etc +*/ +extern volatile Message stackMsgRcv[NB_LINE_CAN][MAX_STACK_MSG_RCV]; + + +/* Copy from the stack of the message to treat */ +extern Message msgRcv; + + +/* To move on the stack of messages + */ +typedef struct { + UNS8 w ; /* received */ + UNS8 r ; /* To transmit */ +} t_pointerStack; + + +/* Pointer for write or read a message in/from the reception stack */ +extern volatile t_pointerStack ptrMsgRcv[NB_LINE_CAN]; + +/* +Parameters to define the clock system for the CAN bus +example : +CAN_BUS_TIME clk = { + 1, // clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board + 0, // brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) + 1, // sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum + 1, // samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit + 4, // tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq + 9, // tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq + + + With these values, + - The width of the bit time is 16 time quantum : + - 1 tq for the SYNC segment (could not be modified) + - 10 tq for the TIME 1 segment (tseg1 = 9) + - 5 tq for the TIME 2 segment (tseg2 = 4) + - Because the bus clock of the MSCAN is 16 MHZ, and the + freq of the time quantum is 16 MHZ (brp = 0), and there are 16 tq in the bit time, + so the freq of the bit time is 1 MHz. + + }; +*/ +typedef struct { + UNS8 clksrc; /* use of internal clock or clock bus */ + UNS8 brp; /* define the bus speed */ + UNS8 sjw; /* Number of time quantum for synchro - 1 */ + UNS8 samp; /* Number of sample per bit (1 or 3) */ + UNS8 tseg2; /* Width of the time segment 2 (in tq) - 1 */ + UNS8 tseg1; /* Width of the time segment 1 (in tq) - 1 */ +} canBusTime; + +/* +Parameters to init the filters for received messages +*/ +typedef struct { + UNS8 idam; /* Put 0x01 for 16 bits acceptance filter */ + UNS8 canidar0; + UNS8 canidmr0; + UNS8 canidar1; + UNS8 canidmr1; + UNS8 canidar2; + UNS8 canidmr2; + UNS8 canidar3; + UNS8 canidmr3; + UNS8 canidar4; + UNS8 canidmr4; + UNS8 canidar5; + UNS8 canidmr5; + UNS8 canidar6; + UNS8 canidmr6; + UNS8 canidar7; + UNS8 canidmr7; +} canBusFilterInit; + +/* +Parameters to init MSCAN +Example +CAN_BUS_INIT bi = { + 0, no low power + 0, no time stamp + 1, enable MSCAN + 0, clock source : oscillator + 0, no loop back + 0, no listen only + 0, no low pass filter for wk up + { + 1, Use the oscillator clock + 0, Quartz oscillator : freq time quantum = freq oscillator clock / (0 + 1) + 1, Sync on (1 + 1) time quantum + 1, 1 sample per bit + 4, time segment 2 width : (4 + 1) tq + 9, time segment 1 width : (9 + 1) tq + } + }; +*/ + +typedef struct { + UNS8 cswai; /* Low power/normal in wait mode (1/0) */ + UNS8 time; /* Timer for time-stamp enable/disable (1/0) */ + UNS8 cane; /* Enable MSCAN (yes=1) Do it ! */ + UNS8 clksrc; /* clock source bus/oscillator (1/0) */ + UNS8 loopb; /* loop back mode for test (yes=1/no=0) */ + UNS8 listen; /* MSCAN is listen only (yes=1/no=0 ie normal)*/ + UNS8 wupm; /* low pas filter for wake up (yes=1/no=0) */ + canBusTime + clk; /* Values for clock system init */ + canBusFilterInit + fi; /* Values for filter acceptance msg init */ + +} canBusInit; + +extern canBusInit bi; + + +/* +For the received messsage, add a Identificator to +the list of ID to accept. +You can use several times this function to accept several messages. +It configures registers on 16 bits. +Automatically, it configure the filter to +- not accepting the msg on 29 bits (ide=1 refused) +- not filtering on rtr state (rtr = 1 and rtr = 0 are accepted) +Algo : +if CANIDARx = 0 then CANIDARx = id . else do nothing +CANIDMRx = CANIDMRx OR (CANIDARx XOR id ) +nFilter : 0 to 3 +Must be in init mode before. +*/ +char canAddIdToFilter ( + UNS16 adrCAN, + UNS8 nFilter, + UNS16 id /* 11 bits, the 5 msb not used */ + ); + +/* +Enable one of the 5 MSCAN. +Must be done only one time after a reset of the CPU. +To do before any CAN initialisation +*/ +char canEnable ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + + +/* +Initialize one of the 5 mscan +can be done multiple times in your code +Return 0 : OK +When it return from the function, +mscan is on sleep mode with wake up disabled. + is not on init mode +*/ +char canInit ( + UNS16 adrCAN, /* First address of MSCANx registers */ + canBusInit + bi /* All the parameters to init the bus */ + ); +/* +Initialize the parameters of the system clock for the MSCAN +You must put the MSCAN in sleep mode before with canSleepMode() +Return 0 : OK + 1 : Not in sleep mode. Unable to init MSCAN +*/ +char canInitClock ( + UNS16 adrCAN, /* First address of MSCANx registers */ + canBusTime clk); + +/* +Initialize one filter for acceptance of received msg. +Filters MUST be configured on 16 bits +(See doc Motorola mscan bloc guide fig 4.3) +Must be in init mode before. +adrCAN : adress of the first register of the mscan module +nFilter : the filter : 0 to 3. +ar : Value to write in acceptance register + Beware ! hight byte and low byte inverted. + for example if nFilter = 0, hight byte of ar -> CANIDAR0 + low byte of ar -> CANIDAR1 +mr : Value to write in mask register + Beware ! hight byte and low byte inverted. + for example if nFilter = 2, hight byte of ar -> CANIDMR4 + low byte of ar -> CANIDMR5 +*/ +char canInit1Filter ( + UNS16 adrCAN, + UNS8 nFilter, + UNS16 ar, + UNS16 mr + ); + +/* +Initialise the parameters for filtering the messages received. +You must put the MSCAN in init mode before with canInitMode() +Return 0 : OK + 1 : Not in init mode. Unable to init MSCAN +*/ + +char canInitFilter ( + UNS16 adrCAN, /* First address of MSCANx registers */ + canBusFilterInit fi); +/* +Put one of the 5 mscan in Init mode +Loop until init mode is reached. +*/ + +char canInitMode ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + +/* +Leave the Init mode +loop until init mode leaved. +*/ + +char canInitModeQ ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + + + +/* +Transmit a msg on CAN "adrCan" +Return : 0 No error + other error : no buffer available to make the transmission +*/ + +char canMsgTransmit ( + UNS16 adrCAN, /* First address of MSCANx registers */ + Message msg /* Message to transmit */ + ); + +/* +Put one of the 5 mscan in sleep mode +Beware! If some messages are to be sent, +or if it is receiving, going into sleep mode +may take time. +Wake up is disabled : stay in sleep mode even if +bus traffic detected. +return 0 if 0K, other if error : mscan is on init mode. +Stay in this function until the sleep mode +is reached. +*/ +char canSleepMode ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + +/* +Leave the sleep mode +loop until sleep mode leaved. +return 0 : OK +return 1 : error : in init mode +*/ +char canSleepModeQ ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + +/* +Put one of the 5 mscan in sleep mode +MSCAN must not be in init mode. +wake up is enabled : wake up if traffic on CAN is detected +Beware! If some messages are to be sent, +or if it is receiving, going into sleep mode +may take time. +Loop until sleep mode reached. +return 0 if 0K, other if error +*/ +char canSleepWupMode ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + +/* +Test if one of the 5 mscan is in init mode. +Return + 0 -> Not in init mode + other -> In init mode +*/ +char canTestInitMode ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + +/* +Test if one of the 5 mscan is in sleep mode. +Return + 0 -> Not in sleep mode + other -> In sleep mode +*/ +char canTestSleepMode ( + UNS16 adrCAN /* First address of MSCANx registers */ + ); + + + +#endif /*__CANDRIVER__*/ + diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/error.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/error.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,37 @@ +/* +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 __ERROR__ +#define __ERROR__ + + +#define ERR_CAN_ADD_ID_TO_FILTER "1 Not in init mode" +#define ERR_CAN_INIT_CLOCK "4 Not in init mode" +#define ERR_CAN_INIT_1_FILTER "5 Not in init mode" +#define ERR_CAN_INIT_FILTER "6 Not in init mode" +#define ERR_CAN_MSG_TRANSMIT "7 No buffer free " +#define ERR_CAN_SLEEP_MODE "8 Is in init mode" +#define ERR_CAN_SLEEP_MODE_Q "9 Is in init mode" +#define ERR_CAN_SLEEP_WUP_MODE "10 Is in init mode" +#define ERR_CAN0HDLRCV_STACK_FULL "11 Stack R full" + +#endif /* __ERROR__ */ diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/interrupt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/interrupt.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,144 @@ +/* +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 __INTERRUPT__ +#define __INTERRUPT__ + + +/** +Disable interrupts +*/ +void lock (void); + +/** +Enable interrupts +*/ +void unlock (void); + +/** +Timer overflow +*/ +void __attribute__((interrupt)) timerOvflHdl (void); + +/** +Message transmitted on MSCAN 0 +*/ +void __attribute__((interrupt)) can0HdlTra (void); + +/** +Message received on MSCAN 0 +*/ +void __attribute__((interrupt)) can0HdlRcv (void); + +/** +Message error on MSCAN 0 + +*/ +void __attribute__((interrupt)) can0HdlWup (void); + +/** +Message error on MSCAN 0 +*/ +void __attribute__((interrupt)) can0HdlErr (void); + +/** +Message transmited on MSCAN 1 +*/ +void __attribute__((interrupt)) can1HdlTra (void); + +/** +Message received on MSCAN 1 +*/ +void __attribute__((interrupt)) can1HdlRcv (void); + +/** +Message error on MSCAN 1 +*/ +void __attribute__((interrupt)) can1HdlWup (void); + +/** +Message error on MSCAN 1 +*/ +void __attribute__((interrupt)) can1HdlErr (void); + +/** +Message transmited on MSCAN 2 +*/ +void __attribute__((interrupt)) can2HdlTra (void); + +/** +Message received on MSCAN 2 +*/ +void __attribute__((interrupt)) can2HdlRcv (void); + +/* +Message error on MSCAN 2 +*/ +void __attribute__((interrupt)) can2HdlWup (void); + +/** +Message error on MSCAN 2 +*/ +void __attribute__((interrupt)) can2HdlErr (void); + +/** +Message transmited on MSCAN 3 +*/ +void __attribute__((interrupt)) can3HdlTra (void); + +/** +Message received on MSCAN 3 +*/ +void __attribute__((interrupt)) can3HdlRcv (void); + +/** +Message error on MSCAN 3 +*/ +void __attribute__((interrupt)) can3HdlWup (void); + +/** +Message error on MSCAN 3 +*/ +void __attribute__((interrupt)) can3HdlErr (void); + +/** +Message error on MSCAN 4 +*/ +void __attribute__((interrupt)) can4HdlTra (void); + +/** +Message received on MSCAN 4 +*/ +void __attribute__((interrupt)) can4HdlRcv (void); + +/* +Message error on MSCAN 4 +*/ +void __attribute__((interrupt)) can4HdlWup (void); + +/** +Message error on MSCAN 4 +*/ +void __attribute__((interrupt)) can4HdlErr (void); + + +#endif /* __INTERRUPT__ */ diff -r 000000000000 -r 4472ee7c6c3e include/hcs12/regbase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/hcs12/regbase.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,38 @@ +/* +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 +*/ + +/* +Définition du maping, +qui dépend du contenu du registre INITRG +*/ + + +#ifndef __REGBASE__ +#define __REGBASE__ + + + + + + + +#endif __REGBASE__ diff -r 000000000000 -r 4472ee7c6c3e include/led.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/led.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,43 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +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 +*/ + + +#if !defined(_LED_INDICATORS_H_) +#define _LED_INDICATORS_H_ + + +enum +{ + LED_NO_ERROR = 6, /* reference to States values */ + LED_AUTOBITRATE, + LED_INVALID_CONFIG, + LED_WARNING_LIMIT_REACH, + LED_ERROR_CTRL_EVENT, + LED_SYNC_ERROR, + LED_EVENT_TIMER_ERROR, + LED_BUS_OFF, + LED_PRG_DOWNLOAD +}; + + +void led_set_state(CO_Data *d, int state); + + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/lifegrd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/lifegrd.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,62 @@ +/* +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 __lifegrd_h__ +#define __lifegrd_h__ + + +#include + +typedef void (*heartbeatError_t)(UNS8); + +#include "data.h" + +//*************************************************************************/ +//Functions +//*************************************************************************/ + + +/** To read the state of a node + * This can be used by the master after having sent a life guard request, + * of by any node if it is waiting for heartbeat. + */ +e_nodeState getNodeState (CO_Data* d, UNS8 nodeId); + +/** Start heartbeat consumer and producer + * with respect to 0x1016 and 0x1017 + * object dictionary entries + */ +void heartbeatInit(CO_Data* d); + +/** Stop heartbeat consumer and producer + */ +void heartbeatStop(CO_Data* d); + +/** This function is responsible to process a canopen-message which seams to be an NMT Error Control + * Messages. At them moment we assume that every NMT error control message + * is a heartbeat message. + * \param Message The CAN-message which has to be analysed. + * If a BootUp message is detected, it will return the nodeId of the Slave who booted up + */ +void proceedNODE_GUARD (CO_Data* d, Message* m); + +#endif //__lifegrd_h__ diff -r 000000000000 -r 4472ee7c6c3e include/lss.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/lss.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,33 @@ +#if !defined(_LSS_H_) +#define _LSS_H_ + + +void lss_SwitchModeGlobal(CO_Data *d, UNS32 mode); +void lss_SwitchModeSelective(CO_Data *d, UNS32 *LSSaddr); +void lss_ConfigureNode_ID(CO_Data *d, UNS32 node_id); + +void lss_ConfigureBitTimingParameters(CO_Data *d, + UNS32 table_selector, + UNS32 table_index); + +void lss_ActivateBitTimingParameters_master(CO_Data *d, UNS16 switch_delay); +void lss_ActivateBitTimingParameters_slave(UNS8 data1, UNS8 data2); + +void lss_StoreConfiguredParameters(CO_Data *d); +UNS32 lss_InquireLSSAddress(CO_Data *d, UNS32 *LSSaddr); + +void lss_IdentifyRemoteSlaves(CO_Data *d, + UNS32 vendor_id, + UNS32 product_code, + UNS32 rev_low, + UNS32 rev_high, + UNS32 serial_low, + UNS32 serial_high); + +UNS32 lss_validate_address(CO_Data *d); + +void lss_IdentifySlave(CO_Data *d); + + +#endif + diff -r 000000000000 -r 4472ee7c6c3e include/nmtMaster.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/nmtMaster.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,64 @@ +/* +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 __nmtMaster_h__ +#define __nmtMaster_h__ + +#include "data.h" + +/** Transmit a NMT message on the bus number bus_id + * to the slave whose node_id is ID + * bus_id is hardware dependant + * cs represents the order of state changement: + * cs = NMT_Start_Node // Put the node in operational mode + * cs = NMT_Stop_Node // Put the node in stopped mode + * cs = NMT_Enter_PreOperational // Put the node in pre_operational mode + * cs = NMT_Reset_Node // Put the node in initialization mode + * cs = NMT_Reset_Comunication // Put the node in initialization mode + * The mode is changed according to the slave state machine mode : + * initialisation ---> pre-operational (Automatic transition) + * pre-operational <--> operational + * pre-operational <--> stopped + * pre-operational, operational, stopped -> initialisation + * + * return canSend(bus_id,&m) + */ +UNS8 masterSendNMTstateChange (CO_Data* d, UNS8 Node_ID, UNS8 cs); + +/** Transmit a Node_Guard message on the bus number bus_id + * to the slave whose node_id is nodeId + * bus_id is hardware dependant + * return canSend(bus_id,&m) + */ +UNS8 masterSendNMTnodeguard (CO_Data* d, UNS8 nodeId); + + +/** Prepare a Node_Guard message transmission on the bus number bus_id + * to the slave whose node_id is nodeId + * Put nodeId = 0 to send an NMT broadcast. + * This message will ask for the slave, whose node_id is nodeId, its state + * bus_id is hardware dependant + */ +void masterRequestNodeState (CO_Data* d, UNS8 nodeId); + + +#endif // __nmtMaster_h__ diff -r 000000000000 -r 4472ee7c6c3e include/nmtSlave.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/nmtSlave.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,45 @@ +/* +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 __nmtSlave_h__ +#define __nmtSlave_h__ + +#include +#include "data.h" + +/** Threat the reception of a NMT message from the master + * *m is a pointer to the message received + * bus_id is hardware dependant + * return 0 if OK, -1 if the slave is not allowed, by its state, + * to receive the message + */ +void proceedNMTstateChange (CO_Data* d, Message * m); + +/** Transmit the boot-Up frame when the slave is moving from initialization + * state to pre_operational state. + * bus_id is hardware dependant + * return canSend(bus_id,&m) + */ +UNS8 slaveSendBootUp (CO_Data* d); + + +#endif // __nmtSlave_h__ diff -r 000000000000 -r 4472ee7c6c3e include/nvram.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/nvram.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,7 @@ +#if !defined(_NVRAM_H_) +#define _NVRAM_H_ + +int canSaveData(indextable *dict, int max_index); +int canReadData(indextable *dict, int max_index); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/objacces.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/objacces.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,140 @@ +/* +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. + */ + +#ifndef __objacces_h__ +#define __objacces_h__ + +#include + +typedef UNS32 (*valueRangeTest_t)(UNS8 typeValue, void *Value); + +#include "data.h" + + + +/** +Print MSG_WAR (s) if error to the access to the object dictionary occurs. +You must uncomment the lines +//#define DEBUG_CAN +//#define DEBUG_WAR_CONSOLE_ON +//#define DEBUG_ERR_CONSOLE_ON +in the file objaccess.c +sizeDataDict : Size of the data defined in the dictionary +sizeDataGiven : Size data given by the user. +code : error code to print. (SDO abort code. See file def.h) +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. +*/ +#ifdef DEBUG_WAR_CONSOLE_ON +UNS8 accessDictionaryError(UNS16 index, UNS8 subIndex, + UNS8 sizeDataDict, UNS8 sizeDataGiven, UNS32 code); +#else +#define accessDictionaryError(...) +#endif + +/** Reads an entry from the object dictionary.\n + * \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 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 ppbData Pointer to the pointer which points to the variable where + * the value of this object dictionary entry should be copied + * \param pdwSize This function writes the size of the copied value (in Byte) + * into this variable. + * \param pDataType : 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]. + * \return OD_SUCCESSFUL or SDO abort code. (See file def.h) + */ +UNS32 getODentry( CO_Data* d, + UNS16 wIndex, + UNS8 bSubindex, + void * pDestData, + UNS8 * pExpectedSize, + UNS8 * pDataType, + UNS8 checkAccess); + + +/** By this function you can write an entry into the object dictionary\n + * \code + * // Example usage: + * UNS8 B; + * B = 0xFF; // set transmission type + * + * retcode = setODentry( (UNS16)0x1800, (UNS8)2, &B, sizeof(UNS8), 1 ); + * \endocde + * \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 pbData Pointer to the variable that holds the value that should + * be copied into the object dictionary + * \param dwSize The size of the value (in Byte). + * \param CheckAccess if other than 0, do not read if the data is Read Only or Constant + * \return OD_SUCCESSFUL or SDO abort code. (See file def.h) + */ +UNS32 setODentry( CO_Data* d, + UNS16 wIndex, + UNS8 bSubindex, + void * pSourceData, + UNS8 * pExpectedSize, + UNS8 checkAccess); + + +/** Scan the index of object dictionary. Used only by setODentry and getODentry. + * *errorCode : OD_SUCCESSFUL if index foundor SDO abort code. (See file def.h) + * 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 // __objacces_h__ diff -r 000000000000 -r 4472ee7c6c3e include/objdictdef.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/objdictdef.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,133 @@ +/* +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 __objdictdef_h__ +#define __objdictdef_h__ + +/************************* CONSTANTES **********************************/ +/** this are static defined datatypes taken fCODE the canopen standard. They + * are located at index 0x0001 to 0x001B. As described in the standard, they + * are in the object dictionary for definition purpose only. a device does not + * to support all of this datatypes. + */ +#define boolean 0x01 +#define int8 0x02 +#define int16 0x03 +#define int32 0x04 +#define uint8 0x05 +#define uint16 0x06 +#define uint32 0x07 +#define real32 0x08 +#define visible_string 0x09 +#define octet_string 0x0A +#define unicode_string 0x0B +#define time_of_day 0x0C +#define time_difference 0x0D + +#define domain 0x0F +#define int24 0x10 +#define real64 0x11 +#define int40 0x12 +#define int48 0x13 +#define int56 0x14 +#define int64 0x15 +#define uint24 0x16 + +#define uint40 0x18 +#define uint48 0x19 +#define uint56 0x1A +#define uint64 0x1B + +#define pdo_communication_parameter 0x20 +#define pdo_mapping 0x21 +#define sdo_parameter 0x22 +#define identity 0x23 + +// CanFestival is using 0x24 to 0xFF to define some types containing a +// value range (See how it works in objdict.c) + + + +/** definitions of the different types of PDOs' transmission + * + * SYNCHRO(n) means that the PDO will be transmited every n SYNC signal. + */ +#define TRANS_EVERY_N_SYNC(n) (n) /*n = 1 to 240 */ +#define TRANS_SYNC_MIN 1 /* Trans after reception of n SYNC. n = 1 to 240 */ +#define TRANS_SYNC_MAX 240 /* Trans after reception of n SYNC. n = 1 to 240 */ +#define TRANS_RTR_SYNC 252 /* Transmission on request */ +#define TRANS_RTR 253 /* Transmission on request */ +#define TRANS_EVENT 255 /* Transmission on event */ + +/** Each entry of the object dictionary can be READONLY (RO), READ/WRITE (RW), + * WRITE-ONLY (WO) + */ +#define RW 0x00 +#define WO 0x01 +#define RO 0x02 + +#define TO_BE_SAVED 0x04 + +/************************ STRUCTURES ****************************/ +/** This are some structs which are neccessary for creating the entries + * of the object dictionary. + */ +typedef struct td_subindex +{ + UNS8 bAccessType; + UNS8 bDataType; // Defines of what datatype the entry is + UNS8 size; // The size (in Byte) of the variable + void* pObject; // This is the pointer of the Variable +} subindex; + +/** Struct for creating entries in the communictaion profile + */ +typedef struct td_indextable +{ + subindex* pSubindex; // Pointer to the subindex + UNS8 bSubCount; // the count of valid entries for this subindex + // This count here defines how many memory has been + // allocated. this memory does not have to be used. + UNS16 index; +} indextable; + +typedef struct s_quick_index{ + UNS16 SDO_SVR; + UNS16 SDO_CLT; + UNS16 PDO_RCV; + UNS16 PDO_RCV_MAP; + UNS16 PDO_TRS; + UNS16 PDO_TRS_MAP; +}quick_index; + + +//typedef struct struct_CO_Data CO_Data; +typedef UNS32 (*ODCallback_t)(CO_Data* d, const indextable *, UNS8 bSubindex); +typedef const indextable * (*scanIndexOD_t)(UNS16 wIndex, UNS32 * errorCode, ODCallback_t **Callback); + +/************************** MACROS *********************************/ + +///CANopen usefull helpers +#define GET_NODE_ID(m) (m.cob_id.w & 0x7f) +#define GET_FUNCTION_CODE(m) (m.cob_id.w >> 7) + +#endif // __objdictdef_h__ diff -r 000000000000 -r 4472ee7c6c3e include/pdo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/pdo.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,96 @@ +/* +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 __pdo_h__ +#define __pdo_h__ + +#include +#include + +/* The process_var structure + Used to store the PDO before the transmission or the reception. +*/ +typedef struct struct_s_process_var { + UNS8 count; // Size of data. Ex : for a PDO of 6 bytes of data, count = 6 + // WARNING s_process_var.data is subject to ENDIANISATION + // (with respect to CANOPEN_BIG_ENDIAN) + UNS8 data[PDO_MAX_LEN]; +}s_process_var; + +#include "data.h" + +/** The PDO structure */ +typedef struct struct_s_PDO { + UNS32 cobId; // COB-ID + UNS8 len; // Number of data transmitted (in data[]) + UNS8 data[8]; // Contain the data +}s_PDO; + +/** Transmit a PDO data frame on the bus bus_id + * pdo is a structure which contains the pdo to transmit + * bus_id is hardware dependant + * return canSend(bus_id,&m) or 0xFF if error + * request can take the value REQUEST or NOT_A_REQUEST + */ +UNS8 sendPDO (CO_Data* d, s_PDO pdo, UNS8 request); + +/** Prepare a PDO frame transmission, + * whose different parameters are stored in process_var table, + * to the slave. + * bus_id is hardware dependant + * call the function sendPDO + * return the result of the function sendPDO or 0xFF if error + */ +UNS8 PDOmGR (CO_Data* d, UNS32 cobId); + +/** Prepare the PDO defined at index to be sent by PDOmGR + * Copy all the data to transmit in process_var + * *pwCobId : returns the value of the cobid. (subindex 1) + * Return 0 or 0xFF if error. + */ +UNS8 buildPDO (CO_Data* d, UNS16 index); + +/** Transmit a PDO request frame on the bus bus_id + * to the slave. + * bus_id is hardware dependant + * Returns 0xFF if error, other in success. + */ +UNS8 sendPDOrequest (CO_Data* d, UNS32 cobId); + +/** Compute a PDO frame reception + * bus_id is hardware dependant + * return 0xFF if error, else return 0 + */ +UNS8 proceedPDO (CO_Data* d, Message *m); + +/* used by the application to send a variable by PDO. + * Check in which PDO the variable is mapped, and send the PDO. + * of course, the others variables mapped in the PDO are also sent ! + * ( ie when a specific event occured) + * bus_id is hardware dependant + * variable is a pointer to the variable which has to be sent. Must be + * defined in the object dictionary + * return 0xFF if error, else return 0 + */ +UNS8 sendPDOevent (CO_Data* d, void * variable); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/sdo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/sdo.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,249 @@ +/* +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 __sdo_h__ +#define __sdo_h__ + +typedef void (*SDOtimeoutError_t)(UNS8 line); +struct struct_s_transfer; + +#include "timer.h" + +/* The Transfer structure +Used to store the different segments of + - a SDO received before writing in the dictionary + - the reading of the dictionary to put on a SDO to transmit +*/ + +struct struct_s_transfer { + UNS8 nodeId; //own ID if server, or node ID of the server if client + + UNS8 whoami; // Takes the values SDO_CLIENT or SDO_SERVER + UNS8 state; // state of the transmission : Takes the values SDO_... + UNS8 toggle; + UNS32 abortCode; // Sent or received + // index and subindex of the dictionary where to store + // (for a received SDO) or to read (for a transmit SDO) + UNS16 index; + UNS8 subIndex; + UNS32 count; // Number of data received or to be sent. + UNS32 offset; // stack pointer of data[] + // Used only to tranfer part of a line to or from a SDO. + // offset is always pointing on the next free cell of data[]. + // WARNING s_transfer.data is subject to ENDIANISATION + // (with respect to CANOPEN_BIG_ENDIAN) + UNS8 data [SDO_MAX_LENGTH_TRANSFERT]; + UNS8 dataType; // Defined in objdictdef.h Value is visible_string + // if it is a string, any other value if it is not a string, + // like 0. In fact, it is used only if client. + TIMER_HANDLE timer; // Time counter to implement a timeout in milliseconds. + // It is automatically incremented whenever + // the line state is in SDO_DOWNLOAD_IN_PROGRESS or + // SDO_UPLOAD_IN_PROGRESS, and reseted to 0 + // when the response SDO have been received. +}; +typedef struct struct_s_transfer s_transfer; + + +#include "data.h" + +/// The 8 bytes data of the SDO +struct BODY{ + UNS8 data[8]; +}; + +/// The SDO structure ... +struct struct_s_SDO { + UNS8 nodeId; //in any case, Node ID of the server (case sender or receiver). + struct BODY body; +}; + + +typedef struct struct_s_SDO s_SDO; + +/** Reset all sdo buffers + */ +void resetSDO (CO_Data* d); + + +/** Copy the data received from the SDO line transfert to the object dictionary + * Returns SDO error code if error. Else, returns 0; + */ +UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line); + +/** Copy the data from the object dictionary to the SDO line for a network transfert. + * Returns SDO error code if error. Else, returns 0; + */ +UNS32 objdictToSDOline (CO_Data* d, UNS8 line); + +/** copy data from an existant line in the argument "* data" + * Returns 0xFF if error. Else, returns 0; + */ +UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8 * data); + +/** Add data to an existant line + * Returns 0xFF if error. Else, returns 0; + */ +UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8 * data); + +/** Called when an internal SDO abort occurs. + * Release the line * Only if server * + * If client, the line must be released manually in the core application. + * The reason of that is to permit the program to read the transfers[][] structure before its reset, + * because many informations are stored on it : index, subindex, data received or trasmited, ... + * In all cases, sends a SDO abort. + * Returns 0 + */ +UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index, + UNS8 subIndex, UNS32 abortCode); + +/** Reset an unused line. + * + */ +void resetSDOline (CO_Data* d, UNS8 line); + +/** Initialize some fields of the structure. + * Returns 0 + */ +UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state); + +/** Search for an unused line in the transfers array + * to store a new SDO. + * ie a line which value of the field "state" is "SDO_RESET" + * An unused line have the field "state" at the value SDO_RESET + * bus_id is hardware dependant + * whoami : create the line for a SDO_SERVER or SDO_CLIENT. + * return 0xFF if all the lines are on use. Else, return 0 + */ +UNS8 getSDOfreeLine (CO_Data* d, UNS8 whoami, UNS8 *line); + +/** Search for the line, in the transfers array, which contains the + * beginning of the reception of a fragmented SDO + * whoami takes 2 values : look for a line opened as SDO_CLIENT or SDO_SERVER + * bus_id is hardware dependant + * nodeId correspond to the message node-id + * return 0xFF if error. Else, return 0 + */ +UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line); + +/** Close a transmission. + * nodeId : Node id of the server if both server or client + * whoami : Line opened as SDO_CLIENT or SDO_SERVER + */ +UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami); + +/** Bytes in the line structure which must be transmited (or received) + * bus_id is hardware dependant. + * return 0. + */ +UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes); + +/** Store in the line structure the nb of bytes which must be transmited (or received) + * bus_id is hardware dependant. + * return 0 if success, 0xFF if error. + */ +UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes); + +/** Transmit a SDO frame on the bus bus_id + * sdo is a structure which contains the sdo to transmit + * bus_id is hardware dependant + * whoami takes 2 values : SDO_CLIENT or SDO_SERVER + * return canSend(bus_id,&m) or 0xFF if error + */ +UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo); + +/** Transmit a SDO error to the client. The reasons may be : + * Read/Write to a undefined object + * Read/Write to a undefined subindex + * Read/write a not valid length object + * Write a read only object + * whoami takes 2 values : SDO_CLIENT or SDO_SERVER + */ +UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode); + +/** Treat a SDO frame reception + * bus_id is hardware dependant + * call the function sendSDO + * return 0xFF if error + * 0x80 if transfert aborted by the server + * 0x0 ok + */ +UNS8 proceedSDO (CO_Data* d, Message *m); + +/** Used by the application to send a SDO request frame to write the data *data + * at the index and subIndex indicated + * in the dictionary of the slave whose node_id is nodeId + * Count : nb of bytes to write in the dictionnary. + * datatype (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value. + * bus_id is hardware dependant + * return 0xFF if error, else return 0 + */ +UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, + UNS8 subIndex, UNS8 count, UNS8 dataType, void *data); + +/** Used by the application to send a SDO request frame to read + * in the dictionary of a server node whose node_id is ID + * at the index and subIndex indicated + * bus_id is hardware dependant + * datatype (defined in objdictdef.h) : put "visible_string" for strings, 0 for integers or reals or other value. + * return 0xFF if error, else return 0 + */ +UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, + UNS8 subIndex, UNS8 dataType); + +/** Use this function after a readNetworkDict to get the result. + Returns : SDO_FINISHED // data is available + SDO_ABORTED_RCV // Transfert failed. (abort SDO received) + SDO_ABORTED_INTERNAL // Transfert failed. Internal abort. + SDO_UPLOAD_IN_PROGRESS // Data not yet available + SDO_DOWNLOAD_IN_PROGRESS // Should not arrive ! + + dataType (defined in objdictdef.h) : type expected. put "visible_string" for strings, 0 for integers or reals. + abortCode : 0 = not available. Else : SDO abort code. (received if return SDO_ABORTED_RCV) + example : + UNS32 data; + UNS8 size; + readNetworkDict(0, 0x05, 0x1016, 1, 0) // get the data index 1016 subindex 1 of node 5 + while (getReadResultNetworkDict (0, 0x05, &data, &size) != SDO_UPLOAD_IN_PROGRESS); +*/ +UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, + UNS8 *size, UNS32 * abortCode); + +/** + Use this function after a writeNetworkDict to get the result of the write + It is mandatory to call this function because it is releasing the line used for the transfer. + Returns : SDO_FINISHED // data is available + SDO_ABORTED_RCV // Transfert failed. (abort SDO received) + SDO_ABORTED_INTERNAL // Transfert failed. Internal abort. + SDO_DOWNLOAD_IN_PROGRESS // Data not yet available + SDO_UPLOAD_IN_PROGRESS // Should not arrive ! + abortCode : 0 = not available. Else : SDO abort code. (received if return SDO_ABORTED_RCV) + example : + UNS32 data = 0x50; + UNS8 size; + UNS32 abortCode; + writeNetworkDict(0, 0x05, 0x1016, 1, size, &data) // write the data index 1016 subindex 1 of node 5 + while ( getWriteResultNetworkDict (0, 0x05, &abortCode) != SDO_DOWNLOAD_IN_PROGRESS); +*/ +UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/states.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/states.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,100 @@ +/* +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 __states_h__ +#define __states_h__ + +#include + +///The nodes states +//----------------- +/// values are choosen so, that they can be sent directly +/// for heartbeat messages... +/// Must be coded on 7 bits only +/* Should not be modified */ +enum enum_nodeState { + Initialisation = 0x00, + Disconnected = 0x01, + Connecting = 0x02, + Preparing = 0x02, + Stopped = 0x04, + Operational = 0x05, + Pre_operational = 0x7F, + Unknown_state = 0x0F +}; + +typedef enum enum_nodeState e_nodeState; + +typedef struct +{ + UNS8 csBoot_Up; + UNS8 csSDO; + UNS8 csEmergency; + UNS8 csSYNC; + UNS8 csHeartbeat; + UNS8 csPDO; +} s_state_communication; + +/** Function that user app must provide + * + */ +typedef void (*initialisation_t)(void); +typedef void (*preOperational_t)(void); +typedef void (*operational_t)(void); +typedef void (*stopped_t)(void); + +#include "data.h" + +/************************* prototypes ******************************/ + +/** Called by driver/app when receiving messages +*/ +void canDispatch(CO_Data* d, Message *m); + +/** Returns the state of the node +*/ +e_nodeState getState (CO_Data* d); + +/** Change the state of the node +*/ +UNS8 setState (CO_Data* d, e_nodeState newState); + +/** Returns the nodId +*/ +UNS8 getNodeId (CO_Data* d); + +/** Define the node ID. Initialize the object dictionary +*/ +void setNodeId (CO_Data* d, UNS8 nodeId); + +/** Some stuff to do when the node enter in reset mode + * + */ +//void initResetMode (CO_Data* d); + + +/** Some stuff to do when the node enter in pre-operational mode + * + */ +void initPreOperationalMode (CO_Data* d); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/sync.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/sync.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,57 @@ +/* +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 __SYNC_h__ +#define __SYNC_h__ + +void startSYNC(CO_Data* d); + +void stopSYNC(CO_Data* d); + +typedef void (*post_sync_t)(void); + +typedef void (*post_TPDO_t)(void); + +/** transmit a SYNC message on the bus number bus_id + * bus_id is hardware dependant + * return canSend(bus_id,&m) + */ +UNS8 sendSYNC (CO_Data* d, UNS32 cob_id); + +/** This function is called when the node is receiving a SYNC + * message (cob-id = 0x80). + * What does the function : + * check if the node is in OERATIONAL mode. (other mode : return 0 but does nothing). + * Get the SYNC cobId by reading the dictionary index 1005. (Return -1 if it does not correspond + * to the cobId received). + * Scan the dictionary from index 0x1800 to the last PDO defined (dict_cstes.max_count_of_PDO_transmit) + * for each PDO whose transmission type is on synchro (transmission type < 241) and if the msg must + * be send at this SYNC. read the COBID. Verify that the nodeId inside the + * nodeId correspond to bDeviceNodeId. (Assume that the cobId of a PDO Transmit is made + * with the node id of the node who transmit), get the mapping, launch PDOmGR to send the PDO + * *m is a pointer to the message received + * bus_id is hardware dependant + * return 0 if OK, 0xFF if error + */ +UNS8 proceedSYNC (CO_Data* d, Message * m); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/timer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/timer.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,63 @@ +/* +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 __timer_h__ +#define __timer_h__ + +#include + +#define TIMER_HANDLE INTEGER16 + +#include "data.h" + +// --------- types et constants definitions --------- +#define TIMER_FREE 0 +#define TIMER_ARMED 1 +#define TIMER_TRIG 2 +#define TIMER_TRIG_PERIOD 3 + +#define TIMER_NONE -1 + +typedef void (*TimerCallback_t)(CO_Data* d, UNS32 id); + +struct struct_s_timer_entry { + UNS8 state; + CO_Data* d; + TimerCallback_t callback; // The callback func. + UNS32 id; // The callback func. + TIMEVAL val; + TIMEVAL interval; // Periodicity +}; + +typedef struct struct_s_timer_entry s_timer_entry; + +// --------- prototypes --------- +//#define SetAlarm(d, id, callback, value, period) printf("%s, %d, SetAlarm(%s, %s, %s, %s, %s)\n",__FILE__, __LINE__, #d, #id, #callback, #value, #period); _SetAlarm(d, id, callback, value, period) +TIMER_HANDLE SetAlarm(CO_Data* d, UNS32 id, TimerCallback_t callback, TIMEVAL value, TIMEVAL period); +TIMER_HANDLE DelAlarm(TIMER_HANDLE handle); +void TimeDispatch(void); + +// --------- to be defined in user app --------- +void setTimer(TIMEVAL value); +TIMEVAL getElapsedTime(void); + +#endif // #define __timer_h__ diff -r 000000000000 -r 4472ee7c6c3e include/timers_driver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/timers_driver.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,39 @@ +/* +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 __timer_driver_h__ +#define __timer_driver_h__ + +#include "timer.h" +/*void initTimer();*/ + +// For use from CAN driver +void EnterMutex(void); +void LeaveMutex(void); +void WaitReceiveTaskEnd(TASK_HANDLE*); +void stopTimer(void); + +// For use from application +void TimerLoop(TimerCallback_t init_callback); +void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE *ReceiveLoop_task); + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/timers_unix/timerscfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/timers_unix/timerscfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,37 @@ +/* +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 + +// Time unit : us +// Time resolution : 64bit (~584942 years) +#define TIMEVAL unsigned long long +#define TIMEVAL_MAX 0xffffffffffffffff +#define MS_TO_TIMEVAL(ms) ms*1000 +#define US_TO_TIMEVAL(us) us + +#define TASK_HANDLE pthread_t + +#endif diff -r 000000000000 -r 4472ee7c6c3e include/timers_xeno/timerscfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/timers_xeno/timerscfg.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,40 @@ +/* +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 +#include +#include +#include + +// Time unit : ns +// Time resolution : 64bit (~584 years) +#define TIMEVAL RTIME +#define TIMEVAL_MAX ~(RTIME)0 +#define MS_TO_TIMEVAL(ms) (RTIME)ms*1000000 +#define US_TO_TIMEVAL(us) (RTIME)us*1000 + +#define TASK_HANDLE RT_TASK + +#endif diff -r 000000000000 -r 4472ee7c6c3e objdictgen/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,8 @@ +Makefile +objdict.xml +gnosis +Gnosis_Utils-1.2.1.tar.gz +*.od +*.pyc +*.c +*.h \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e objdictgen/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,73 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +PREFIX = SUB_PREFIX +INSTALL_JAXE = SUB_OPT_JAXE + +all: jaxe gnosis + +jaxe: jaxe-unix-2.2.tar.gz + +gnosis: Gnosis_Utils-1.2.1.tar.gz + +Gnosis_Utils-1.2.1.tar.gz: + wget http://gnosis.cx/download/Gnosis_Utils-1.2.1.tar.gz + tar xfz Gnosis_Utils-1.2.1.tar.gz + mv Gnosis_Utils-1.2.1/gnosis . + rm -rf Gnosis_Utils-1.2.1 + +jaxe-unix-2.2.tar.gz: +ifeq ($(INSTALL_JAXE),jaxe) + wget http://dl.sourceforge.net/sourceforge/jaxe/jaxe-unix-2.2.tar.gz + tar xfz jaxe-unix-2.2.tar.gz +endif + +install: jaxe + cp -r ../objdictgen $(PREFIX)/ +ifeq ($(INSTALL_JAXE),jaxe) + rm -f $(PREFIX)/objdictgen/jaxe-unix-2.2.tar.gz +endif + rm -f $(PREFIX)/objdictgen/Gnosis_Utils-current.tar.gz + chmod -R a+r $(PREFIX)/objdictgen + chmod 755 $(PREFIX)/objdictgen/objdictedit.sh + echo -e "#!/bin/sh\n pushd $(PREFIX)/objdictgen/\n ./objdictedit.sh\n popd\n" > $(PREFIX)/bin/objdictedit + chmod 755 $(PREFIX)/bin/objdictedit + ln -s $(PREFIX)/objdictgen/objdictgen.py $(PREFIX)/bin/objdictgen + chmod 755 $(PREFIX)/objdictgen/objdictgen.py + +uninstall: + -rm -rf $(PREFIX)/objdictgen + -rm -f $(PREFIX)/bin/objdictgen + -rm -f $(PREFIX)/bin/objdictgen.py + +clean: + +mrproper: clean +ifeq ($(INSTALL_JAXE),jaxe) + -rm -f jaxe-unix-2.2.tar.gz + -rm -rf jaxe +endif + -rm -f Gnosis_Utils-1.2.1.tar.gz + -rm -rf gnosis + + diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-401.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-401.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,276 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-401 +""" + +Mapping = { + 0x6000 : {"name" : "Read Inputs 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 8 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Read Inputs 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6002 : {"name" : "Polarity Input 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 8 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Polarity Input 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6003 : {"name" : "Filter Constant Input 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 8 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Constant Input 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + 0x6005 : {"name" : "Global Interrupt Enable Digital", "struct" : var, "need" : False, "values" : + [{"name" : "Global Interrupt Enable Digital", "type" : 0x01, "access" : 'rw', "pdo" : False}]}, + + 0x6006 : {"name" : "Interrupt Mask Any Change 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 8 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Any Change 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6007 : {"name" : "Interrupt Mask Low to High 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 8 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Low to High 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6008 : {"name" : "Interrupt Mask High to Low 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 8 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt High to Low 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6020 : {"name" : "Read Input Bit 0x%X to 0x%X[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x8, "values" : + [{"name" : "Number of Input 1 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Read Single Input 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6030 : {"name" : "Polarity Input Bit 0x%X to 0x%X[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x8, "values" : + [{"name" : "Number of Input 1 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Polarity Input bit 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6038 : {"name" : "Filter Constant Input Bit 0x%X to 0x%X[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x8, "values" : + [{"name" : "Number of Input 1 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Constant Input bit 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6050 : {"name" : "Interrupt Mask Input Any Change Bit 0x%X to 0x%X[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x8, "values" : + [{"name" : "Number of Input 1 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Mask Any Change Input bit 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6060 : {"name" : "Interrupt Mask Input Low to High Bit 0x%X to 0x%X[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x8, "values" : + [{"name" : "Number of Input 1 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Mask Any Change Input bit 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6070 : {"name" : "Interrupt Mask Input High to Low Bit 0x%X to 0x%X[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x8, "values" : + [{"name" : "Number of Input 1 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Mask Any Change Input bit 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + + + 0x6100 : {"name" : "Read Inputs 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 16 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Read Inputs 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6102 : {"name" : "Polarity Input 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 16 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Polarity Input 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6103 : {"name" : "Filter Constant Input 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 16 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Constant Input 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6106 : {"name" : "Interrupt Mask Any Change 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 16 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Any Change 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6107 : {"name" : "Interrupt Mask Low to High 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 16 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Low to High 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6106 : {"name" : "Interrupt Mask High to Low 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 16 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt High to Low 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6120 : {"name" : "Read Input 4 Byte", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 32 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Read Input 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6122 : {"name" : "Polarity Input 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 32 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Polarity Input 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x6123 : {"name" : "Filter Constant Input 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 32 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Polarity Input 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x6126 : {"name" : "Interrupt Mask Input Any Change 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 32 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Any Change Input 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6127 : {"name" : "Interrupt Mask Input Low to High 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 32 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Low to High Input 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6128 : {"name" : "Interrupt Mask Input High to Low 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Input 32 bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt High to Low Input 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6200 : {"name" : "Write Outputs 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Write Outputs 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6202 : {"name" : "Change Polarity Outputs 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Change Polarity Outputs 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6206 : {"name" : "Error Mode Outputs 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Mode Outputs 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6207 : {"name" : "Error Value Outputs 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Value Outputs 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6208 : {"name" : "Filter Mask Outputs 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Mask Outputs 0x%X to 0x%X[(sub*8-7,sub*8)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6220 : {"name" : "Write Outputs Bit %d to %d[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Output 1 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Write Outputs 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6240 : {"name" : "Change Polarity Outputs Bit %d to %d[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Output 1 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Write Outputs 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6250 : {"name" : "Error Mode Outputs Lines %d to %d[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Output 1 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Mode Outputs 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6260 : {"name" : "Error Value Outputs Lines %d to %d[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Output 1 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Value Outputs 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + 0x6270 : {"name" : "Filter Constant Outputs Lines %d to %d[(idx*128-127,idx*128)]", "struct" : plurirec, "incr" : 0x01, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Output 1 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Constant Outputs 0x%X[((idx-1)*128+sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0x80}]}, + + + 0x6300 : {"name" : "Write Outputs 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Write Outputs 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6302 : {"name" : "Change Polarity Outputs 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Change Polarity Outputs 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6306 : {"name" : "Error Mode Outputs 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Mode Outputs 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6307 : {"name" : "Error Value Outputs 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Value Outputs 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6308 : {"name" : "Filter Mask Outputs 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Mask Outputs 0x%X to 0x%X[(sub*16-15,sub*16)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + 0x6320 : {"name" : "Write Output 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Write Outputs 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6322 : {"name" : "Change Polarity Outputs 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Polarity Outputs 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6326 : {"name" : "Error Mode Outputs 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Mode Outputs 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6327 : {"name" : "Error Value Outputs 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Value Outputs 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6328 : {"name" : "Filter Mask Outputs 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Output 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Filter Mask Outputs 0x%X to 0x%X[(sub*32-31,sub*32)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6400 : {"name" : "Read Analogue Input 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6401 : {"name" : "Read Analogue Input 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6402 : {"name" : "Read Analogue Input 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6403 : {"name" : "Read Analogue Input Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input Float", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6404 : {"name" : "Read Manufacturer specific Analogue Input", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x11, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6410 : {"name" : "Write Analogue Output 8 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input 8 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6411 : {"name" : "Write Analogue Output 16 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Input 16 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6412 : {"name" : "Write Analogue Output 32 Bit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs 32 Bit", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6413 : {"name" : "Write Analogue Output Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs Float", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6414 : {"name" : "Write Manufacturer specific Analogue Output", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x11, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6421 : {"name" : "Interrupt Trigger Selection", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analog Inputs 0x%X[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6422 : {"name" : "Analogue Input Interrupt Source", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Interrupt Source Bank", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Interrupt Source Bank 0x%X[(sub)]", "type" : 0x07, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + + 0x6423 : {"name" : "Analogue Input Global Interrupt Enable", "struct" : var, "need" : False, "values" : + [{"name" : "Analogue Input Global Interrupt Enable", "type" : 0x01, "access" : 'rw', "pdo" : True}]}, + + 0x6424 : {"name" : "Analogue Input Interrupt Upper Limit Interger", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6425 : {"name" : "Analogue Input Interrupt Lower Limit Interger", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6426 : {"name" : "Analogue Input Interrupt Delta Unsigned", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6427 : {"name" : "Analogue Input Interrupt Negative Delta Unsigned", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6428 : {"name" : "Analogue Input Interrupt Positive Delta Unsigned", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6429 : {"name" : "Analogue Input Interrupt Upper Limit Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x642A : {"name" : "Analogue Input Interrupt Lower Limit Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x642B : {"name" : "Analogue Input Interrupt Delta Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x642C : {"name" : "Analogue Input Interrupt Negative Delta Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x642D : {"name" : "Analogue Input Interrupt Positive Delta Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x642E : {"name" : "Analogue Input Offset Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x642F : {"name" : "Analogue Input Scaling Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6430 : {"name" : "Analogue Input SI unit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6431 : {"name" : "Analogue Input Offset Integer", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6432 : {"name" : "Analogue Input Scaling Integer", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Inputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Input %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6441 : {"name" : "Analogue Output Offset Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6442 : {"name" : "Analogue Output Scaling Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6443 : {"name" : "Analogue Output Error Mode", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Error Mode Analogue Output %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6444 : {"name" : "Analogue Output Error Value Integer", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6445 : {"name" : "Analogue Output Error Value Float", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6446 : {"name" : "Analogue Output Offset Integer", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6447 : {"name" : "Analogue Output Scaling Integer", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6450 : {"name" : "Analogue Output SI Unit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Analogue Outputs", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Analogue Output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]} +} + +AddMenuEntries = [("Read Input Bit",[0x6020, 0x6030, 0x6038, 0x6050, 0x6060, 0x6070]), ("Write Output Bit",[0x6220, 0x6240, 0x6250, 0x6260, 0x6270])] \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-404.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-404.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1042 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-404 +""" + +Mapping = { + 0x6000 : {"name" : "DI Read state 8 Input Lines", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DI Read state 8 Inputs Lines %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6002 : {"name" : "DI Polarity 8 Input Lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'rw', "pdo" : False}, + {"name" : "DI Polarity 8 Input Lines %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x6020 : {"name" : "DI Read state 1 Input Lines", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DI Read state 1 Inputs Lines %d[(sub)]", "type" : 0x01, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x6030 : {"name" : "DI Polarity 1 Input Lines", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DI Polarity 1 Inputs Lines %d[(sub)]", "type" : 0x01, "access" : 'ro', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6100 : {"name" : "AI Input FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input FV %d[(sub)]", "type" : 0x08, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7100 : {"name" : "AI Input FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input FV %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8100 : {"name" : "AI Input FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input FV %d[(sub)]", "type" : 0x10, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9100 : {"name" : "AI Input FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input FV %d[(sub)]", "type" : 0x04, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6103 : {"name" : "AI Interrupt delta input FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input FV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7103 : {"name" : "AI Interrupt delta input FV","struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input FV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8103 : {"name" : "AI Interrupt delta input FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input FV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9103 : {"name" : "AI Interrupt delta input FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input FV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6110 : {"name" : "AI Sensor Type", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Sensor Type %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x6111 : {"name" : "AI Autocalibration", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Autocalibration %d[(sub)]", "type" : 0x07, "access" : 'wo', "pdo" : False, "nbmax" : 0xC7}]}, + 0x6112 : {"name" : "AI Operating Mode", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Operating Mode %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x6114 : {"name" : "AI ADC Sample Rate", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Sample Rate %d[(sub)]", "type" : 0x07, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6120 : {"name" : "AI Input Scaling 1 FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 FV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7120 : {"name" : "AI Input Scaling 1 FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 FV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8120 : {"name" : "AI Input Scaling 1 FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 FV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9120 : {"name" : "AI Input Scaling 1 FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 FV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6121 : {"name" : "AI Input Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7121 : {"name" : "AI Input Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8121 : {"name" : "AI Input Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9121 : {"name" : "AI Input Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 1 PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6122 : {"name" : "AI Input Scaling 2 FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 FV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7122 : {"name" : "AI Input Scaling 2 FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 FV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8122 : {"name" : "AI Input Scaling 2 FV", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 FV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9122 : {"name" : "AI Input Scaling 2 FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 FV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6123 : {"name" : "AI Input Scaling 2 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7123 : {"name" : "AI Input Scaling 2 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8123 : {"name" : "AI Input Scaling 2 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9123 : {"name" : "AI Input Scaling 2 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Scaling 2 PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6124 : {"name" : "AI Input Offset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Offset %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7124 : {"name" : "AI Input Offset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Offset %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8124 : {"name" : "AI Input Offset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Offset %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9124 : {"name" : "AI Input Offset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input Offset %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6125 : {"name" : "AI Autozero", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Autozero %d[(sub)]", "type" : 0x07, "access" : 'wo', "pdo" : False, "nbmax" : 0xC7}]}, + 0x6126 : {"name" : "AI Scaling Factor", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Scaling Factor %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x6127 : {"name" : "AI Scaling Offset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Scaling Offset %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6130 : {"name" : "AI Input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input PV %d[(sub)]", "type" : 0x08, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7130 : {"name" : "AI Input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input PV %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8130 : {"name" : "AI Input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input PV %d[(sub)]", "type" : 0x10, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9130 : {"name" : "AI Input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Input PV %d[(sub)]", "type" : 0x04, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6131 : {"name" : "AI Physical Unit PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Physical Unit PV %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x6132 : {"name" : "AI Decimal digits PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Decimal digits PV %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6133 : {"name" : "AI Interrupt delta input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7133 : {"name" : "AI Interrupt delta input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8133 : {"name" : "AI Interrupt delta input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9133 : {"name" : "AI Interrupt delta input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta input PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6134 : {"name" : "AI Interrupt lower input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower input PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7134 : {"name" : "AI Interrupt lower input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower input PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8134 : {"name" : "AI Interrupt lower input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower input PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9134 : {"name" : "AI Interrupt lower input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower input PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6135 : {"name" : "AI Interrupt upper input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper input PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7135 : {"name" : "AI Interrupt upper input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper input PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8135 : {"name" : "AI Interrupt upper input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper input PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9135 : {"name" : "AI Interrupt upper input PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper input PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6138 : {"name" : "AI Tare zero", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Tare zero %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7138 : {"name" : "AI Tare zero", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Tare zero %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8138 : {"name" : "AI Tare zero", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Tare zero %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9138 : {"name" : "AI Tare zero", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Tare zero %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6139 : {"name" : "AI Autotare", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Autotare %d[(sub)]", "type" : 0x07, "access" : 'wo', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6140 : {"name" : "AI Net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Net PV %d[(sub)]", "type" : 0x08, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7140 : {"name" : "AI Net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Net PV %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8140 : {"name" : "AI Net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Net PV %d[(sub)]", "type" : 0x10, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9140 : {"name" : "AI Net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Net PV %d[(sub)]", "type" : 0x04, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6143 : {"name" : "AI Interrupt delta net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta net PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7143 : {"name" : "AI Interrupt delta net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta net PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8143 : {"name" : "AI Interrupt delta net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta net PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9143 : {"name" : "AI Interrupt delta net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt delta net PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6144 : {"name" : "AI Interrupt lower limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower limit net PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7144 : {"name" : "AI Interrupt lower limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower limit net PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8144 : {"name" : "AI Interrupt lower limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower limit net PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9144 : {"name" : "AI Interrupt lower limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt lower limit net PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6145 : {"name" : "AI Interrupt upper limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper limit net PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7145 : {"name" : "AI Interrupt upper limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper limit net PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8145 : {"name" : "AI Interrupt upper limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper limit net PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9145 : {"name" : "AI Interrupt upper limit net PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Interrupt upper limit net PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6148 : {"name" : "AI Span start", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span start %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7148 : {"name" : "AI Span start", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span start %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8148 : {"name" : "AI Span start", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span start %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9148 : {"name" : "AI Span start", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span start %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6149 : {"name" : "AI Span end", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span end %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7149 : {"name" : "AI Span end", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span end %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8149 : {"name" : "AI Span end", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span end %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9149 : {"name" : "AI Span end", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Span end %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6150 : {"name" : "AI Status", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Status %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6160 : {"name" : "AI Control Byte", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Control Byte %d[(sub)]", "type" : 0x05, "access" : 'wo', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6161 : {"name" : "AI Control Byte Enable", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Control Byte Enable %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x61A0 : {"name" : "AI Filter Type", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Filter Type %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x61A1 : {"name" : "AI Filter Constant", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AI Filter Constant %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6200 : {"name" : "DO Write state 8 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Write state 8 output lines %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6202 : {"name" : "DO Polarity 8 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Polarity 8 output lines %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6206 : {"name" : "DO Fault mode 8 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Fault mode 8 output lines %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6207 : {"name" : "DO Fault state 8 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Fault state 8 output lines %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6210 : {"name" : "DO Link object 8 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Link Object 8 output lines %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6220 : {"name" : "DO Write state 1 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Write state 1 output lines %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6240 : {"name" : "DO Polarity 1 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Polarity 1 output lines %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6250 : {"name" : "DO Fault mode 1 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Failt mode 1 output lines %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6260 : {"name" : "DO Fault state 1 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Fault state 1 output lines %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6280 : {"name" : "DO Link object 1 output lines", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "DO Link object 1 output lines %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6300 : {"name" : "AO Output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7300 : {"name" : "AO Output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8300 : {"name" : "AO Output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9300 : {"name" : "AO Output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + + + 0x6301 : {"name" : "AO Physical Unit PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Physical Unit PV %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6302 : {"name" : "AO Decimal digits PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Decimal digits PV %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6303 : {"name" : "AO Link output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Link output PV %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6310 : {"name" : "AO Output type", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output type %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6320 : {"name" : "AO Output Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7320 : {"name" : "AO Output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8320 : {"name" : "AO Output Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9320 : {"name" : "AO Output Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6323 : {"name" : "AO Output Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7323 : {"name" : "AO Output PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8323 : {"name" : "AO Output Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9323 : {"name" : "AO Output Scaling 1 PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Output Scaling 1 PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + + 0x6331 : {"name" : "AO Physical Unit FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Physical Unit FV %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6332 : {"name" : "AO Decimal digits FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Decimal digits FV %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6340 : {"name" : "AO Fault mode", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Fault mode %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6341 : {"name" : "AO Fault FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Fault FV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7341 : {"name" : "AO Fault FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Fault FV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8341 : {"name" : "AO Fault FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Fault FV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9341 : {"name" : "AO Fault FV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AO Fault FV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6400 : {"name" : "CO Effective Current Value Xeff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Current Value Xeff %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7400 : {"name" : "CO Effective Current Value Xeff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Current Value Xeff %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8400 : {"name" : "CO Effective Current Value Xeff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Current Value Xeff %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9400 : {"name" : "CO Effective Current Value Xeff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Current Value Xeff %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + + + 0x6401 : {"name" : "CO Effective Set Point Weff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Set Point Weff %d[(sub)]", "type" : 0x08, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7401 : {"name" : "CO Effective Set Point Weff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Set Point Weff %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8401 : {"name" : "CO Effective Set Point Weff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Set Point Weff %d[(sub)]", "type" : 0x10, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9401 : {"name" : "CO Effective Set Point Weff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective Set Point Weff %d[(sub)]", "type" : 0x04, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + + + + 0x6402 : {"name" : "CO Set Point W", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Set Point W %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7402 : {"name" : "CO Set Point W", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Set Point W %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8402 : {"name" : "CO Set Point W", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Set Point W %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9402 : {"name" : "CO Set Point W", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Set Point W %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + + + 0x6403 : {"name" : "CO 2nd Set Point W2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7403 : {"name" : "CO 2nd Set Point W2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8403 : {"name" : "CO 2nd Set Point W2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9403 : {"name" : "CO 2nd Set Point W2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + + + 0x6404 : {"name" : "CO Lower Set Point Limit W0", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Lower Set Point Limit W0 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7404 : {"name" : "CO Lower Set Point Limit W0", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Lower Set Point Limit W0 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8404 : {"name" : "CO Lower Set Point Limit W0", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Lower Set Point Limit W0 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9404 : {"name" : "CO Lower Set Point Limit W0", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Lower Set Point Limit W0 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6405 : {"name" : "CO upper Set Point Limit W100", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7405 : {"name" : "CO 2nd Set Point W2", "struct" : rec , "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8405 : {"name" : "CO 2nd Set Point W2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9405 : {"name" : "CO 2nd Set Point W2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO 2nd Set Point W2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + + 0x6406 : {"name" : "CO Physical unit current value - set point", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Physical unit current value - set point %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6407 : {"name" : "CO Decimal digits current value - set point", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Decimal digits current value - set point %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6410 : {"name" : "CO Effective controller output Y", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Effective controller output Y %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6411 : {"name" : "CO Differential controller output Ydiff", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Differential controller output Ydiff %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6412 : {"name" : "CO Manual controller output", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Manual controller output %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6413 : {"name" : "CO Lower controler output limit Ymin", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Lower controler output limit Ymin %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6414 : {"name" : "CO Upper controler output limit Ymax", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Upper controler output limit Ymax %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6415 : {"name" : "CO Physical unit controller output", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Physical unit controller output %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6420 : {"name" : "CO Set point switch W-W2", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Set point switch W-W2 %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6421 : {"name" : "CO Automatic - manual mode A-M", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Automatic - manual mode %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6422 : {"name" : "CO Controller on - off", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Controller on - off %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6423 : {"name" : "CO Controller mode", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Controller mode %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6424 : {"name" : "CO Self optimization on - off", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Self optimization on - off %d[(sub)]", "type" : 0x01, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6425 : {"name" : "CO control byte", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO control byte %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6426 : {"name" : "CO control byte enable", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO control byte enable %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6427 : {"name" : "CO status word", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO status word %d[(sub)]", "type" : 0x06, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6430 : {"name" : "CO Minimum Pulse Time Tmin1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7430 : {"name" : "CO Minimum Pulse Time Tmin1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8430 : {"name" : "CO Minimum Pulse Time Tmin1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9430 : {"name" : "CO Minimum Pulse Time Tmin1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6431 : {"name" : "CO Minimum Pulse Time Tmin2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7431 : {"name" : "CO Minimum Pulse Time Tmin2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8431 : {"name" : "CO Minimum Pulse Time Tmin2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9431 : {"name" : "CO Minimum Pulse Time Tmin2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Minimum Pulse Time Tmin2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6432 : {"name" : "CO Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7432 : {"name" : "CO Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8432 : {"name" : "Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9432 : {"name" : "CO Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6433 : {"name" : "CO Min. Pulse Length Tpuls", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7433 : {"name" : "CO Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8433 : {"name" : "Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9433 : {"name" : "CO Motor Response Time Tm", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Motor Response Time Tm %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6434 : {"name" : "CO Physical unit pulse timing", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Physical unit pulse timing %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6435 : {"name" : "CO Decimal digits pulse timing", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Decimal digits pulse timing %d[(sub)]", "type" : 0x06, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6440 : {"name" : "Neutral zone 3point Xsh1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7440 : {"name" : "Neutral zone 3point Xsh1","struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8440 : {"name" : "Neutral zone 3point Xsh1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9440 : {"name" : "Neutral zone 3point Xsh1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6441 : {"name" : "Neutral zone 3point Xsh2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7441 : {"name" : "Neutral zone 3point Xsh1","struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8441 : {"name" : "Neutral zone 3point Xsh1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9441 : {"name" : "Neutral zone 3point Xsh1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Neutral zone 3point Xsh2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6442 : {"name" : "CO Neutral zone 3point stepping Xsh", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Neutral zone 3point stepping Xsh %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7442 : {"name" : "CO Neutral zone 3point stepping Xsh", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Neutral zone 3point stepping Xsh %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8442 : {"name" : "CO Neutral zone 3point stepping Xsh", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Neutral zone 3point stepping Xsh %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9442 : {"name" : "CO Neutral zone 3point stepping Xsh", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Neutral zone 3point stepping Xsh %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6443 : {"name" : "CO Switching difference of signaller Xsd1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of signaller Xsd1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7443 : {"name" : "CO Switching difference of signaller Xsd1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of signaller Xsd1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8443 : {"name" : "CO Switching difference of signaller Xsd1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of signaller Xsd1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9443 : {"name" : "CO Switching difference of signaller Xsd1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of signaller Xsd1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6444 : {"name" : "CO Switching difference of additional Contact Xsd2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of additional Contact Xsd2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7444 : {"name" : "CO Switching difference of additional Contact Xsd2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of additional Contact Xsd2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8444 : {"name" : "CO Switching difference of additional Contact Xsd2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of additional Contact Xsd2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9444 : {"name" : "CO Switching difference of additional Contact Xsd2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Switching difference of additional Contact Xsd2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6445 : {"name" : "CO Trigger point separation of additional contact LW", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Trigger point separation of additional contact LW %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7445 : {"name" : "CO Trigger point separation of additional contact LW", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Trigger point separation of additional contact LW %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8445 : {"name" : "CO Trigger point separation of additional contact LW", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Trigger point separation of additional contact LW %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9445 : {"name" : "CO Trigger point separation of additional contact LW", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Trigger point separation of additional contact LW %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6450 : {"name" : "CO Proportional Band Xp1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7450 : {"name" : "CO Proportional Band Xp1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8450 : {"name" : "CO Proportional Band Xp1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9450 : {"name" : "CO Proportional Band Xp1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6451 : {"name" : "CO Proportional Band Xp2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7451 : {"name" : "CO Proportional Band Xp2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8451 : {"name" : "CO Proportional Band Xp2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9451 : {"name" : "CO Proportional Band Xp2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Proportional Band Xp2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x6452 : {"name" : "CO Integral Action Time Tn1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7452 : {"name" : "CO Integral Action Time Tn1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8452 : {"name" : "CO Integral Action Time Tn1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9452 : {"name" : "CO Integral Action Time Tn1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6453 : {"name" : "CO Integral Action Time Tn2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7453 : {"name" : "CO Integral Action Time Tn2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8453 : {"name" : "CO Integral Action Time Tn2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9453 : {"name" : "CO Integral Action Time Tn2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Integral Action Time Tn2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6454 : {"name" : "CO Derivate Action Time Tv1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7454 : {"name" : "CO Integral Action Time Tv2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8454 : {"name" : "CO Derivate Action Time Tv1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9454 : {"name" : "CO Derivate Action Time Tv1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6455 : {"name" : "CO Derivate Action Time Tv2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7455 : {"name" : "CO Integral Action Time Tv2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8455 : {"name" : "CO Derivate Action Time Tv2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9455 : {"name" : "CO Derivate Action Time Tv2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Derivate Action Time Tv2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6456 : {"name" : "CO Cycle Time T1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T1 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7456 : {"name" : "CO Cycle Time T1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T1 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8456 : {"name" : "CO Cycle Time T1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T1 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9456 : {"name" : "CO Cycle Time T1", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T1 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6456 : {"name" : "CO Cycle Time T2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T2 %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7456 : {"name" : "CO Cycle Time T2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T2 %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8456 : {"name" : "CO Cycle Time T2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T2 %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9456 : {"name" : "CO Cycle Time T2", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Cycle Time T2 %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6458 : {"name" : "CO Physical unit PID timing", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Physical unit PID timing %d[(sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6459 : {"name" : "CO Decimal digits PID timing", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CO Decimal digits PID timing %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6500 : {"name" : "AL %d Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Input Value %d[(idx,sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7500 : {"name" : "AL %d Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Input Value %d[(idx,sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8500 : {"name" : "AL %d Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Input Value %d[(idx,sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9500 : {"name" : "AL %d Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Input Value %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6503 : {"name" : "AL %d Link Input[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Link Input %d[(idx,sub)]", "type" : 0x07, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6504 : {"name" : "AL %d Alternate Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Alternate Input Value %d[(idx,sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x7504 : {"name" : "AL %d Alternate Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Alternate Input Value %d[(idx,sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x8504 : {"name" : "AL %d Alternate Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Alternate Input Value %d[(idx,sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x9504 : {"name" : "AL %d Alternate Input Value[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Alternate Input Value %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6505 : {"name" : "AL %d Link alternate input[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Link alternate Input %d[(idx,sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6506 : {"name" : "AL %d Fault mode[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Fault mode %d[(idx,sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6507 : {"name" : "AL %d Fault state[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Fault state %d[(idx,sub)]", "type" : 0x01, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6508 : {"name" : "AL %d Type[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Type %d[(idx,sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6509 : {"name" : "AL %d Action[(idx)]", "struct" : pluriarray, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Action %d[(idx,sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x650A : {"name" : "AL %d Level[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Level %d[(idx,sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x750A : {"name" : "AL %d Level[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Level %d[(idx,sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x850A : {"name" : "AL %d Level[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Level %d[(idx,sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x950A : {"name" : "AL %d Level[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Level %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x650B : {"name" : "AL %d Hysteresis[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Hysteresis %d[(idx,sub)]", "type" : 0x08, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x750B : {"name" : "AL %d Hysteresis[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Hysteresis %d[(idx,sub)]", "type" : 0x03, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x850B : {"name" : "AL %d Hysteresis[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Hysteresis %d[(idx,sub)]", "type" : 0x10, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + 0x950B : {"name" : "AL %d Hysteresis[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Hysteresis %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + + 0x650C : {"name" : "AL %d Group[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Group %d[(idx,sub)]", "type" : 0x05, "access" : 'rw', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x650D : {"name" : "AL %d State[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d State %d[(idx,sub)]", "type" : 0x01, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x650E : {"name" : "AL %d Reset[(idx)]", "struct" : plurirec, "incr" : 0x10, "need" : False, "nbmax" : 16, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL %d Reset %d[(idx,sub)]", "type" : 0x01, "access" : 'wo', "pdo" : False, "nbmax" : 0xC7}]}, + + 0x6600 : {"name" : "AL 1..8 State", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL 1..8 State %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6601 : {"name" : "AL 9..16 State", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL 9..16 State %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6602 : {"name" : "AL General State", "struct" : var, "need" : False, "values" : + [{"name" : "AL General State", "type" : 0x01, "access" : 'ro', "pdo" : True}]}, + + 0x6603 : {"name" : "AL Group 1..8 State", "struct" : var, "need" : False, "values" : + [{"name" : "AL Group 1..8 State", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x6610 : {"name" : "AL General Reset", "struct" : var, "need" : False, "values" : + [{"name" : "AL General Reset", "type" : 0x01, "access" : 'wo', "pdo" : True}]}, + + 0x6611 : {"name" : "AL 1..8 Reset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL 1..8 Reset %d[(sub)]", "type" : 0x05, "access" : 'wo', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6612 : {"name" : "AL 9..16 Reset", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "AL 9..16 Reset %d[(sub)]", "type" : 0x05, "access" : 'wo', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6F20 : {"name" : "Life counter", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Life counter %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6F30 : {"name" : "Receive PDO check", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Receive PDO check %d[(sub)]", "type" : 0x05, "access" : 'wo', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6F31 : {"name" : "Transmit PDO check", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Transmit PDO check %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xC7}]}, + + + 0x6F50 : {"name" : "Receive PV", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Receive PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7F50 : {"name" : "Receive PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Receive PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8F50 : {"name" : "Receive PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Receive PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9F50 : {"name" : "Receive PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Receive PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6F51 : {"name" : "Alternate receive PV", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Alternate receive PV %d[(sub)]", "type" : 0x08, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x7F51 : {"name" : "Alternate receive PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Alternate receive PV %d[(sub)]", "type" : 0x03, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x8F51 : {"name" : "Alternate receive PV","struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Alternate receive PV %d[(sub)]", "type" : 0x10, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + 0x9F51 : {"name" : "Alternate receive PV", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Alternate receive PV %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6F52 : {"name" : "Received status", "struct" : rec, "need" : True, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Received status %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6F53 : {"name" : "Alternate received status", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Alternate received status %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xC7}]}, + + 0x6F60 : {"name" : "Transmission enable", "struct" : var, "need" : False, "values" : + [{"name" : "Transmission enable", "type" : 0x01, "access" : 'ro', "pdo" : False}]}, +} + +AddMenuEntries = [("Alarm function block",[0x6500, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507, 0x6508, 0x6509, 0x650A, 0x650B, 0x650C, 0x650D, 0x650E, 0x7500, 0x7504, 0x750A, 0x750B, 0x8500, 0x8504, 0x850A, 0x850B, 0x9500, 0x9504, 0x950A, 0x950B])] diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-406.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-406.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,119 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-406 +""" + +Mapping = { + 0x6000 : {"name" : "Operating Parameters", "struct" : var, "need" : True, "values" : + [{"name" : "Operating Parameters", "type" : 0x06, "access" : 'rw', "pdo" : False}]}, + 0x6001 : {"name" : "Measuring Units per Revolution", "struct" : var, "need" : False, "values" : + [{"name" : "Measuring Units per Revolution", "type" : 0x07, "access" : 'rw', "pdo" : False}]}, + 0x6002 : {"name" : "Total Measuring Range in Measuring Unit", "struct" : var, "need" : False, "values" : + [{"name" : "Total Measuring Range in Measuring Unit", "type" : 0x07, "access" : 'rw', "pdo" : False}]}, + 0x6003 : {"name" : "Preset Value", "struct" : var, "need" : False, "values" : + [{"name" : "Preset Value", "type" : 0x07, "access" : 'rw', "pdo" : False}]}, + 0x6004 : {"name" : "Position Value", "struct" : var, "need" : True, "values" : + [{"name" : "Position Value", "type" : 0x07, "access" : 'ro', "pdo" : True}]}, + 0x6005 : {"name" : "Linear Encoder Measuring Step Settings", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Objects", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Position Step Setting", "type" : 0x07, "access" : 'rw', "pdo" : False}, + {"name" : "Speed Step Setting", "type" : 0x07, "access" : 'rw', "pdo" : False}, + {"name" : "Acceleration Step Setting", "type" : 0x07, "access" : 'rw', "pdo" : False}, + {"name" : "Jerk Step Setting", "type" : 0x07, "access" : 'rw', "pdo" : False}]}, + 0x6008 : {"name" : "High Precision Position Value", "struct" : var, "need" : False, "values" : + [{"name" : "High Precision Position Value", "type" : 0x1B, "access" : 'ro', "pdo" : True}]}, + 0x6009 : {"name" : "High Precision Preset Value", "struct" : var, "need" : False, "values" : + [{"name" : "High Precision Preset Value", "type" : 0x1B, "access" : 'rw', "pdo" : False}]}, + + + 0x6010 : {"name" : "Preset Value for Multi-Sensor Device", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Preset Value Channel %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x6020 : {"name" : "Position Value for Multi-Sensor Device", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Position Value Channel %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6030 : {"name" : "Speed Value", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Speed Value Channel %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6040 : {"name" : "Acceleration Value", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Acceleration Value Channel %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6050 : {"name" : "Jerk Value", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Jerk Value Channel %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6200 : {"name" : "Cyclic Timer", "struct" : var, "need" : False, "values" : + [{"name" : "Cyclic Timer", "type" : 0x06, "access" : 'rw', "pdo" : False}]}, + + + 0x6300 : {"name" : "CAM State Register", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CAM State Channel %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6301 : {"name" : "CAM Enable", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CAM Enable Channel %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6302 : {"name" : "CAM Polarity", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CAM Polarity Channel %d[(sub)]", "type" : 0x05, "access" : 'rw', "pdo" : True, "nbmax" : 0xFE}]}, + + + 0x6310 : {"name" : "CAM%d Low Limit[(idx)]", "struct" : plurirec, "incr" : 1, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CAM%d Low Limit Channel %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x6320 : {"name" : "CAM%d High Limit[(idx)]", "struct" : plurirec, "incr" : 1, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CAM%d High Limit Channel %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x6330 : {"name" : "CAM%d Hysteresis[(idx)]", "struct" : plurirec, "incr" : 1, "need" : False, "nbmax" : 0x08, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "CAM%d Hysteresis Channel %d[(idx,sub)]", "type" : 0x06, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + + + 0x6400 : {"name" : "Area State Register", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Work Area State Channel %d[(sub)]", "type" : 0x05, "access" : 'ro', "pdo" : True, "nbmax" : 0xFE}]}, + 0x6401 : {"name" : " Work Area Low Limit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Work Area Low Limit Channel %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x6402 : {"name" : " Work Area High Limit", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Work Area High Limit Channel %d[(sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + + + 0x6500 : {"name" : "Operating Status", "struct" : var, "need" : True, "values" : + [{"name" : "Operating Status", "type" : 0x06, "access" : 'ro', "pdo" : False}]}, + 0x6501 : {"name" : "Single Turn Resolution", "struct" : var, "need" : True, "values" : + [{"name" : "Single Turn Resolution", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + 0x6502 : {"name" : "Number of Distinguishable Revolutions", "struct" : var, "need" : True, "values" : + [{"name" : "Number of Distinguishable Revolutions", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + 0x6503 : {"name" : "Alarms", "struct" : var, "need" : False, "values" : + [{"name" : "Alarms", "type" : 0x06, "access" : 'ro', "pdo" : True}]}, + 0x6504 : {"name" : "Supported Alarms", "struct" : var, "need" : False, "values" : + [{"name" : "Supported Alarms", "type" : 0x06, "access" : 'ro', "pdo" : False}]}, + 0x6505 : {"name" : "Warnings", "struct" : var, "need" : False, "values" : + [{"name" : "Warnings", "type" : 0x06, "access" : 'ro', "pdo" : True}]}, + 0x6506 : {"name" : "Supported Warnings", "struct" : var, "need" : False, "values" : + [{"name" : "Supported Warnings", "type" : 0x06, "access" : 'ro', "pdo" : False}]}, + 0x6507 : {"name" : "Profile and Software Version", "struct" : var, "need" : False, "values" : + [{"name" : "Profile and Software Version", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + 0x6508 : {"name" : "Operating Time", "struct" : var, "need" : False, "values" : + [{"name" : "Operating Time", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + 0x6509 : {"name" : "Offset Value", "struct" : var, "need" : False, "values" : + [{"name" : "Offset Value", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x650A : {"name" : "Module Identification", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Manufacturer Offset Value", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Manufacturer Min Position Value", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Manufacturer Max Position Value", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x650B : {"name" : "Serial Number", "struct" : var, "need" : False, "values" : + [{"name" : "Serial Number", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + 0x650C : {"name" : "Offset Values for Multi-Sensor Devices", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Available Channels", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Offset Value Channel %d[(sub)]", "type" : 0x04, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]}, + + 0x6510 : {"name" : "Number of High Precision Revolutions", "struct" : var, "need" : True, "values" : + [{"name" : "Number of High Precision Revolutions", "type" : 0x18, "access" : 'ro', "pdo" : False}]} +} + +AddMenuEntries = [("CAM",[0x6310, 0x6320, 0x6330])] diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-408.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-408.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1738 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-408 +""" + +Mapping = { + 0x0080 : {"name" : "Value parameter record Unsigned8", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0081 : {"name" : "Value parameter record Unsigned16", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0082 : {"name" : "Value parameter record Unsigned32", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0083 : {"name" : "Value parameter record integer8", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0084 : {"name" : "Value parameter record integer16", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0085 : {"name" : "Value parameter record integer32", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0086 : {"name" : "Value parameter record Float32", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x08, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + 0x0087 : {"name" : "Value parameter record Float64", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x11, "access" : 'ro', "pdo" : False}, + {"name" : "SI unit", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Prefix", "type" : 0x02, "access" : 'ro', "pdo" : False}]}, + + + + + + 0x6040 : {"name" : "Device control word", "struct" : var, "need" : True, "values" : + [{"name" : "Device control word", "type" : 0x06, "access" : 'rw', "pdo" : True}]}, + + 0x6041 : {"name" : "Device status word", "struct" : var, "need" : True, "values" : + [{"name" : "Device status word", "type" : 0x06, "access" : 'ro', "pdo" : True}]}, + + 0x6042 : {"name" : "Device mode", "struct" : var, "need" : True, "values" : + [{"name" : "Device mode", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6043 : {"name" : "Device control mode", "struct" : var, "need" : False, "values" : + [{"name" : "Device control mode", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x604E : {"name" : "Device error code", "struct" : var, "need" : False, "values" : + [{"name" : "Device error code", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x604F : {"name" : "Device local", "struct" : var, "need" : False, "values" : + [{"name" : "Device local", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6050 : {"name" : "Device version", "struct" : var, "need" : False, "values" : + [{"name" : "Device version", "type" : 0x09, "access" : 'ro', "pdo" : False}]}, + + 0x6051 : {"name" : "Device code number", "struct" : var, "need" : False, "values" : + [{"name" : "Device code number", "type" : 0x06, "access" : 'rw', "pdo" : True}]}, + + 0x6052 : {"name" : "Device serial number", "struct" : var, "need" : False, "values" : + [{"name" : "Device version", "type" : 0x09, "access" : 'ro', "pdo" : True}]}, + + 0x6053 : {"name" : "Device description", "struct" : var, "need" : False, "values" : + [{"name" : "Device description", "type" : 0x09, "access" : 'rw', "pdo" : False}]}, + + 0x6054 : {"name" : "Device model description", "struct" : var, "need" : False, "values" : + [{"name" : "Device model description", "type" : 0x09, "access" : 'ro', "pdo" : False}]}, + + 0x6055 : {"name" : "Device model URL", "struct" : var, "need" : False, "values" : + [{"name" : "Device model URL", "type" : 0x09, "access" : 'ro', "pdo" : False}]}, + + 0x6056 : {"name" : "Device parameter set code", "struct" : var, "need" : False, "values" : + [{"name" : "Device parameter set code", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6057 : {"name" : "Device vendor name", "struct" : var, "need" : False, "values" : + [{"name" : "Device vendor name", "type" : 0x09, "access" : 'ro', "pdo" : False}]}, + + 0x605F : {"name" : "Device capability", "struct" : var, "need" : True, "values" : + [{"name" : "Device capability", "type" : 0x07, "access" : 'ro', "pdo" : True}]}, + + 0x6100 : {"name" : "viv actual value conditioning max interface number", "struct" : var, "need" : False, "values" : + [{"name" : "viv actual value conditioning", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x6101 : {"name" : "viv actual value conditioning interface number", "struct" : var, "need" : False, "values" : + [{"name" : "viv actual value conditioning", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6102 : {"name" : "viv actual value conditioning type", "struct" : var, "need" : False, "values" : + [{"name" : "viv actual value conditioning type", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6103 : {"name" : "viv actual value conditioning sign", "struct" : var, "need" : False, "values" : + [{"name" : "viv actual value conditioning sign", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6104 : {"name" : "viv actual value conditioning actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6110 : {"name" : "viv actual value conditioning actual valuei 1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6111 : {"name" : "viv actual value conditioning actual valuei 2", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6112 : {"name" : "viv actual value conditioning actual valuei 3", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6113 : {"name" : "viv actual value conditioning actual valuei 4", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6114 : {"name" : "viv actual value conditioning actual valuei 5", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6115 : {"name" : "viv actual value conditioning actual valuei 6", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6116 : {"name" : "viv actual value conditioning actual valuei 7", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6117 : {"name" : "viv actual value conditioning actual valuei 8", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6120 : {"name" : "viv actual value conditioning min pressure", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6121 : {"name" : "viv actual value conditioning max pressure", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6122 : {"name" : "viv actual value conditioning area", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6123 : {"name" : "viv actual value conditioning pressure offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6124 : {"name" : "viv actual value conditioning min tranducer signal", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6125 : {"name" : "viv actual value conditioning max tranducer signal", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6130 : {"name" : "viv actual value conditioning min referance", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6131 : {"name" : "viv actual value conditioning max referance", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6132 : {"name" : "viv actual value conditioning T1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6133 : {"name" : "viv actual value conditioning min interface", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6134 : {"name" : "viv actual value conditioning max interface", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6140 : {"name" : "viv actual value conditioning resolution", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6141 : {"name" : "viv actual value conditioning position offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6142 : {"name" : "viv actual value conditioning zero shift", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6143 : {"name" : "viv actual value conditioning bit size", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6144 : {"name" : "viv actual value conditioning C", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6145 : {"name" : "viv actual value conditioning start stop type", "struct" : var, "need" : False, "values" : + [{"name" : "viv actual value conditioning start stop type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6200 : {"name" : "drv actual value conditioning max interface", "struct" : var, "need" : False, "values" : + [{"name" : "drv actual value conditioning max interface", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x6201 : {"name" : "drv actual value conditioning interface number", "struct" : var, "need" : False, "values" : + [{"name" : "drv actual value conditioning interface number", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6202 : {"name" : "drv actual value conditioning type", "struct" : var, "need" : False, "values" : + [{"name" : "drv actual value conditioning type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6203 : {"name" : "drv actual value conditioning sign", "struct" : var, "need" : False, "values" : + [{"name" : "drv actual value conditioning sign", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6204 : {"name" : "drv actual value conditioning actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6210 : {"name" : "drv actual value conditioning actual value 1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6211 : {"name" : "drv actual value conditioning actual value 2", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6212 : {"name" : "drv actual value conditioning actual value 3", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6213 : {"name" : "drv actual value conditioning actual value 4", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6214 : {"name" : "drv actual value conditioning actual value 5", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6215 : {"name" : "drv actual value conditioning actual value 6", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6216 : {"name" : "drv actual value conditioning actual value 7", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6217 : {"name" : "drv actual value conditioning actual value 8", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6220 : {"name" : "drv actual value conditioning min pressure", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6221 : {"name" : "drv actual value conditioning max pressure", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6222 : {"name" : "drv actual value conditioning area", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6223 : {"name" : "drv actual value conditioning pressure offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6224 : {"name" : "drv actual value conditioning min transducer signal", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6225 : {"name" : "drv actual value conditioning max transducer signal", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6230 : {"name" : "drv actual value conditioning min referance", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6231 : {"name" : "drv actual value conditioning max referance", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6232 : {"name" : "drv actual value conditioning T1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6233 : {"name" : "drv actual value conditioning min interface", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6234 : {"name" : "drv actual value conditioning max interface", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6240 : {"name" : "drv actual value conditioning resolution", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6241 : {"name" : "drv actual value conditioning position offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6242 : {"name" : "drv actual value conditioning zero shift", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6243 : {"name" : "drv actual value conditioning bit size", "struct" : var, "need" : False, "values" : + [{"name" : "drv actual value conditioning bit size", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6244 : {"name" : "drv actual value conditioning C", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6245 : {"name" : "drv actual value conditioning start stop type", "struct" : var, "need" : False, "values" : + [{"name" : "drv actual value conditioning bit size", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6280 : {"name" : "drv controller output", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6281 : {"name" : "drv controller output interface min", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6282 : {"name" : "drv controller output interface max", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6290 : {"name" : "drv controler output filter type", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output filter type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6291 : {"name" : "drv controller output filter T1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6292 : {"name" : "drv controller output filter D", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6293 : {"name" : "drv controller output filter f0", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62A0 : {"name" : "drv controller output directional dependant gain type", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output directional dependant gain type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62A1 : {"name" : "drv controller output directional dependant gain factor", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output directional dependant gain factor", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62A2 : {"name" : "drv controller output characteristic compensation type", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output characteristic compensation type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62B0 : {"name" : "drv controller output dead band compensation type", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output dead band compensation type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62B1 : {"name" : "drv controller output dead band compensation A side", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62B2 : {"name" : "drv controller output dead band compensation B side", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62C0 : {"name" : "drv controller output zero correction offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62D0 : {"name" : "drv controller output dither type", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output dither type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62D1 : {"name" : "drv controller output dither amplitude", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62D2 : {"name" : "drv controller output dither frequency", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62E0 : {"name" : "drv controller output upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62E1 : {"name" : "drv controller output lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x62F0 : {"name" : "drv controller output inverting sign", "struct" : var, "need" : False, "values" : + [{"name" : "drv controler output inverting sign", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6300 : {"name" : "vpoc set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6301 : {"name" : "vpoc actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6302 : {"name" : "vpoc interface referance", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6310 : {"name" : "vpoc demand value generator demand value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6311 : {"name" : "vpoc demand value generator referance value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6314 : {"name" : "vpoc demand value generator hold set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6320 : {"name" : "vpoc demand value generator upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6321 : {"name" : "vpoc demand value generator lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6322 : {"name" : "vpoc demand value generator scaling factor", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc demand value generator scaling factor", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + + 0x6323 : {"name" : "vpoc demand value generator scaling offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6324 : {"name" : "vpoc demand value generator zero correction offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6330 : {"name" : "vpoc demand value generator ramp type", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6331 : {"name" : "vpoc demand value generator ramp acceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6332 : {"name" : "vpoc demand value generator ramp acceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6333 : {"name" : "vpoc demand value generator ramp acceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6334 : {"name" : "vpoc demand value generator ramp deceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6335 : {"name" : "vpoc demand value generator ramp deceleration", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6336 : {"name" : "vpoc demand value generator ramp deceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6340 : {"name" : "vpoc demand value generator directional dependent gain type", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc demand value generator directional dependent gain type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6341 : {"name" : "vpoc demand value generator directional dependent gain factor", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc demand value generator directional dependent gain factor", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + + 0x6342 : {"name" : "vpoc demand value generator dead band compensation type", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc demand value generator dead band compensation type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6343 : {"name" : "vpoc demand value generator dead band compensation A side", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6344 : {"name" : "vpoc demand value generator dead band compensation B side", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6345 : {"name" : "vpoc demand value generator dead band compensation threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6346 : {"name" : "vpoc demand value generator characteristic compensation type", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6350 : {"name" : "vpoc control deviation", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6351 : {"name" : "vpoc control monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc control monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6352 : {"name" : "vpoc control monitoring delay time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6353 : {"name" : "vpoc control monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6354 : {"name" : "vpoc control monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6355 : {"name" : "vpoc control monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6360 : {"name" : "vpoc dither type", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc dither type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6361 : {"name" : "vpoc dither amplitude", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6362 : {"name" : "vpoc dither frequency", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6371 : {"name" : "vpoc target window monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "vpoc target window monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6362 : {"name" : "vpoc target window monitoring switch on time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6363 : {"name" : "vpoc target window monitoring switch off time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6373 : {"name" : "vpoc target window monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6374 : {"name" : "vpoc target window monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6375 : {"name" : "vpoc target window monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6380 : {"name" : "vprc set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6381 : {"name" : "vprc actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6382 : {"name" : "vprc interface referance", "struct" : var, "need" : False, "values" : + [{"name" : "vprc interface referance", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6390 : {"name" : "vprc demand value generator demand value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6391 : {"name" : "vprc demand value generator referance value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6394 : {"name" : "vprc demand value generator hold set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63A0 : {"name" : "vprc demand value generator upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63A1 : {"name" : "vprc demand value generator lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63A2 : {"name" : "vprc demand value generator scaling factor", "struct" : var, "need" : False, "values" : + [{"name" : "vprc demand value generator scaling factor", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + + 0x63A3 : {"name" : "vprc demand value generator scaling offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63A4 : {"name" : "vprc demand value generator zero correction offset", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B0 : {"name" : "vprc demand value generator ramp type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc demand value generator ramp type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B1 : {"name" : "vprc demand value generator ramp acceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B2 : {"name" : "vprc demand value generator ramp acceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B3 : {"name" : "vprc demand value generator ramp acceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B4 : {"name" : "vprc demand value generator ramp deceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B5 : {"name" : "vprc demand value generator ramp deceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63B5 : {"name" : "vprc demand value generator ramp deceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63C0 : {"name" : "vprc demand value generator directional dependent gain type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc demand value generator directional dependent gain type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63C1 : {"name" : "vprc demand value generator directional dependent gain factor", "struct" : var, "need" : False, "values" : + [{"name" : "vprc demand value generator directional dependent gain factor", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + + 0x63C2 : {"name" : "vprc demand value generator dead band compensation type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc demand value generator dead band compensation type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63C3 : {"name" : "vprc demand value generator dead band compensation A side", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63C4 : {"name" : "vprc demand value generator dead band compensation B side", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63C5 : {"name" : "vprc demand value generator dead band compensation threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63D0 : {"name" : "vprc control deviation", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63D1 : {"name" : "vprc control monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc control monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63D2 : {"name" : "vprc control monitoring delay time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63D3 : {"name" : "vprc control monitoring treshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63D4 : {"name" : "vprc control monitoring upper treshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63D5 : {"name" : "vprc control monitoring lower treshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63E0 : {"name" : "vprc dither type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc dither type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63E1 : {"name" : "vprc dither amplitude", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63E2 : {"name" : "vprc dither frequency", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63F0 : {"name" : "vprc target window monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc target window monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63F1 : {"name" : "vprc target window monitoring switch on time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63F2 : {"name" : "vprc target window monitoring switch off time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63F3 : {"name" : "vprc target window monitoring treshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63F4 : {"name" : "vprc target window monitoring upper treshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x63F5 : {"name" : "vprc target window monitoring lower treshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x640D : {"name" : "vpqc power limit factor", "struct" : var, "need" : False, "values" : + [{"name" : "vprc power limit factor", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + + 0x640E : {"name" : "vpqc hydrostatic actual power", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6460 : {"name" : "vpqc dither type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc dither type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6461 : {"name" : "vpqc dither amplitude", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6462 : {"name" : "vpqc dither frequency", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6470 : {"name" : "vpqc target window monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "vprc target window monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6471 : {"name" : "vpqc target window monitoring switch on time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6472 : {"name" : "vpqc target window monitoring switch off time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x06, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6473 : {"name" : "vpqc target window monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6474 : {"name" : "vpqc target window monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6475 : {"name" : "vpqc target window monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x03, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6480 : {"name" : "dcol set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6490 : {"name" : "dcol demand value generator demand value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6492 : {"name" : "dcol demand value generator reference A value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6493 : {"name" : "dcol demand value generator reference B value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6494 : {"name" : "dcol demand value generator hold set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64A0 : {"name" : "dcol demand value generator upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64A1 : {"name" : "dcol demand value generator lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B0 : {"name" : "dcol demand value generator ramp type", "struct" : var, "need" : False, "values" : + [{"name" : "dcol demand value generator ramp type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B1 : {"name" : "dcol demand value generator ramp acceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B2 : {"name" : "dcol demand value generator ramp acceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B3 : {"name" : "dcol demand value generator ramp acceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B4 : {"name" : "dcol demand value generator ramp deceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B5 : {"name" : "dcol demand value generator ramp deceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x64B6 : {"name" : "dcol demand value generator ramp deceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6500 : {"name" : "dsc set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6501 : {"name" : "dsc actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6502 : {"name" : "dsc interface referance", "struct" : var, "need" : False, "values" : + [{"name" : "dsc interface referance", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6503 : {"name" : "dsc Kp", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6504 : {"name" : "dsc Ti", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6510 : {"name" : "dsc demand value generator demand value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6512 : {"name" : "dsc demand value generator referance A value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6513 : {"name" : "dsc demand value generator referance B value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6514 : {"name" : "dsc demand value generator hold set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6520 : {"name" : "dsc demand value generator upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6521 : {"name" : "dsc demand value generator lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6530 : {"name" : "dsc demand value generator ramp type", "struct" : var, "need" : False, "values" : + [{"name" : "dsc demand value generator ramp type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6531 : {"name" : "dsc demand value generator ramp acceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6532 : {"name" : "dsc demand value generator ramp acceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6533 : {"name" : "dsc demand value generator ramp acceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6534 : {"name" : "dsc demand value generator ramp deceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6535 : {"name" : "dsc demand value generator ramp deceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6536 : {"name" : "dsc demand value generator ramp deceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6550 : {"name" : "dsc control deviation", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6551 : {"name" : "dsc control monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "dsc control monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6552 : {"name" : "dsc control monitoring delay time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6553 : {"name" : "dsc control monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6554 : {"name" : "dsc control monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6555 : {"name" : "dsc control monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6556 : {"name" : "dsc control monitoring threshold Vmax", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6557 : {"name" : "dsc control monitoring upper threshold Vmax positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6558 : {"name" : "dsc control monitoring lower threshold Vmax negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6570 : {"name" : "dsc target window monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "dsc target window monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6571 : {"name" : "dsc target window monitoring switch on time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6572 : {"name" : "dsc target window monitoring switch off time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6573 : {"name" : "dsc target window monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6574 : {"name" : "dsc target window monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6575 : {"name" : "dsc target window monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6580 : {"name" : "dfpc set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6581 : {"name" : "dfpc actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6582 : {"name" : "dfpc interface referance", "struct" : var, "need" : False, "values" : + [{"name" : "dfpc interface referance", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6583 : {"name" : "dfpc Kp", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6584 : {"name" : "dfpc Td", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6585 : {"name" : "dfpc T1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6586 : {"name" : "dfpc Ti", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6587 : {"name" : "dfpc pressure sample time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6590 : {"name" : "dfpc demand value generator demand value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6592 : {"name" : "dfpc demand value generator referance A value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6593 : {"name" : "dfpc demand value generator referance B value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6594 : {"name" : "dfpc demand value generator hold set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65A0 : {"name" : "dfpc demand value generator upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65A1 : {"name" : "dfpc demand value generator lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B0 : {"name" : "dfpc demand value generator ramp type", "struct" : var, "need" : False, "values" : + [{"name" : "dfpc demand value generator ramp type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B1 : {"name" : "dfpc demand value generator ramp acceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B2 : {"name" : "dfpc demand value generator ramp acceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B3 : {"name" : "dfpc demand value generator ramp acceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B4 : {"name" : "dfpc demand value generator ramp deceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B5 : {"name" : "dfpc demand value generator ramp deceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65B6 : {"name" : "dfpc demand value generator ramp deceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D0 : {"name" : "dfpc control deviation", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D1 : {"name" : "dfpc control monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "dfpc control monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D2 : {"name" : "dfpc control monitoring delay time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D3 : {"name" : "dfpc control monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D4 : {"name" : "dfpc control monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D5 : {"name" : "dfpc control monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D6 : {"name" : "dfpc control monitoring threshold Vmax", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D7 : {"name" : "dfpc control monitoring upper threshold Vmax positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65D8 : {"name" : "dfpc control monitoring lower threshold Vmax negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65F0 : {"name" : "dfpc target window monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "dfpc target window monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65F1 : {"name" : "dfpc target window monitoring switch on time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65F2 : {"name" : "dfpc target window monitoring switch off time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65F3 : {"name" : "dfpc target window monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65F4 : {"name" : "dfpc target window monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x65F5 : {"name" : "dfpc target window monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6600 : {"name" : "dpc set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6601 : {"name" : "dpc actual value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6602 : {"name" : "dpc interface referance", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6603 : {"name" : "dpc Kp", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6604 : {"name" : "dpc Td", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6605 : {"name" : "dpc T1", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6608 : {"name" : "dpc switched integrator type", "struct" : var, "need" : False, "values" : + [{"name" : "dpc switched integrator type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6609 : {"name" : "dpc switched integrator Ti", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x660A : {"name" : "dpc switched integrator dX", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x660C : {"name" : "dpc condition feedback Kv", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x660D : {"name" : "dpc condition feedback Kc", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x660E : {"name" : "dpc condition feedback Kpp", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x660F : {"name" : "dpc condition feedback T1pp", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6610 : {"name" : "dpc demand value generator demand value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'ro', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6612 : {"name" : "dpc demand value generator referance A value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6613 : {"name" : "dpc demand value generator referance B value", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6614 : {"name" : "dpc demand value generator hold set point", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6620 : {"name" : "dpc demand value generator upper limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6621 : {"name" : "dpc demand value generator lower limit", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6630 : {"name" : "dpc demand value generator ramp type", "struct" : var, "need" : False, "values" : + [{"name" : "dpc demand value generator ramp type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6631 : {"name" : "dpc demand value generator ramp acceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6632 : {"name" : "dpc demand value generator ramp acceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6633 : {"name" : "dpc demand value generator ramp acceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6634 : {"name" : "dpc demand value generator ramp deceleration time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6635 : {"name" : "dpc demand value generator ramp deceleration time positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6636 : {"name" : "dpc demand value generator ramp deceleration time negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6637 : {"name" : "dpc demand value generator ramp velocity", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6638 : {"name" : "dpc demand value generator ramp acceleration", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6639 : {"name" : "dpc demand value generator ramp deceleration", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6650 : {"name" : "dpc control deviation", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6651 : {"name" : "dpc control monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "dpc control monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6652 : {"name" : "dpc control monitoring delay time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6653 : {"name" : "dpc control monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6654 : {"name" : "dpc control monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6655 : {"name" : "dpc control monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6656 : {"name" : "dpc control monitoring threshold Vmax", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6657 : {"name" : "dpc control monitoring upper threshold Vmax positive", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6658 : {"name" : "dpc control monitoring lower threshold Vmax negative", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6670 : {"name" : "dpc window monitoring type", "struct" : var, "need" : False, "values" : + [{"name" : "dpc window monitoring type", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6671 : {"name" : "dpc target window monitoring switch on time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6672 : {"name" : "dpc target window monitoring switch off time", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x07, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6673 : {"name" : "dpc target window monitoring threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6674 : {"name" : "dpc target window monitoring upper threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]}, + + 0x6675 : {"name" : "dpc target window monitoring lower threshold", "struct" : array, "need" : False, "values" : + [{"name" : "Number of entries", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "Value", "type" : 0x04, "access" : 'rw', "pdo" : True}, + {"name" : "SI unit", "type" : 0x05, "access" : 'rw', "pdo" : True}, + {"name" : "Prefix", "type" : 0x02, "access" : 'rw', "pdo" : True}]} +} + +AddMenuEntries = [] diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-410.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-410.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,77 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-410 +Device profile for inclinometer +""" + +Mapping = { + 0x6000 : {"name" : "resolution", "struct" : var, "need" : True, "values" : + [{"name" : "resolution", "type" : 0x06, "access" : 'rw', "pdo" : True}]}, + + 0x6010 : {"name" : "Slope_Long16", "struct" : var, "need" : True, "values" : + [{"name" : "Slope_Long16", "type" : 0x06, "access" : 'ro', "pdo" : True}]}, + + 0x6011 : {"name" : "Slope_Long16_Operating_Parameter", "struct" : var, "need" : True, "values" : + [{"name" : "Slope_Long16_Operating_Parameter", "type" : 0x05, "access" : 'rw', "pdo" : False}]}, + + 0x6012 : {"name" : "Slope_Long16_preset_value", "struct" : var, "need" : True, "values" : + [{"name" : "Slope_Long16_preset_value", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + + 0x6013 : {"name" : "Slope_Long16_Offset", "struct" : var, "need" : True, "values" : + [{"name" : "Slope_Long16_Offset", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + + 0x6014 : {"name" : "Differential_Slope_Long16_Offset", "struct" : var, "need" : True, "values" : + [{"name" : "Differential_Slope_Long16_Offset", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + + 0x6020 : {"name" : "Slope_Lateral16", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral16_Offset", "type" : 0x03, "access" : 'ro', "pdo" : True}]}, + + 0x6021 : {"name" : "Slope_Lateral16_Operating_Parameter", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral16_Operating_Parameter", "type" : 0x05, "access" : 'rw', "pdo" : False}]}, + + 0x6022 : {"name" : "Slope_Lateral16_preset_value", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral16_preset_value", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + + 0x6023 : {"name" : "Slope_Lateral16_Offset", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral16_Offset", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + + 0x6024 : {"name" : "Differential_Slope_Lateral16_Offset", "struct" : var, "need" : False, "values" : + [{"name" : "Differential_Slope_Lateral16_Offset", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + + 0x6110 : {"name" : "Slope_Long32", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Long32", "type" : 0x04, "access" : 'ro', "pdo" : True}]}, + + 0x6111 : {"name" : "Slope_Long32_Operating_Parameter", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Long32_Operating_Parameter", "type" : 0x05, "access" : 'rw', "pdo" : False}]}, + + 0x6112 : {"name" : "Slope_Long32_preset_value", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Long32_preset_value", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + + 0x6113 : {"name" : "Slope_Long32_Offset", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Long32_Offset", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + + 0x6114 : {"name" : "Differential_Slope_Long32_Offset", "struct" : var, "need" : False, "values" : + [{"name" : "Differential_Slope_Long32_Offset", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + + 0x6120 : {"name" : "Slope_Lateral32", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral32_Offset", "type" : 0x04, "access" : 'ro', "pdo" : True}]}, + + 0x6121 : {"name" : "Slope_Lateral32_Operating_Parameter", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral32_Operating_Parameter", "type" : 0x05, "access" : 'rw', "pdo" : False}]}, + + 0x6122 : {"name" : "Slope_Lateral32_preset_value", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral32_preset_value", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + + 0x6123 : {"name" : "Slope_Lateral32_Offset", "struct" : var, "need" : False, "values" : + [{"name" : "Slope_Lateral32_Offset", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + + 0x6124 : {"name" : "Differential_Slope_Lateral32_Offset", "struct" : var, "need" : False, "values" : + [{"name" : "Differential_Slope_Lateral32_Offset", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + + 0x67FF : {"name" : "Device type", "struct" : var, "need" : False, "values" : + [{"name" : "Device type", "type" : 0x07, "access" : 'ro', "pdo" : False}]} + +} + +AddMenuEntries = [] diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-418.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-418.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,96 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-418 +""" + +Mapping = { + + 0x0080 : {"name" : "BatteryPar", "struct" : array, "need" : False, "values" : + [{"name" : "Highest sub-index supported", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "Battery type", "type" : 0x05, "access" : 'rw', "pdo" : False}, + {"name" : "Ah capacity", "type" : 0x06, "access" : 'rw', "pdo" : False}, + {"name" : "Maximum charge current", "type" : 0x06, "access" : 'rw', "pdo" : False}, + {"name" : "Number of cells", "type" : 0x06, "access" : 'rw', "pdo" : False}]}, + + 0x6000 : {"name" : "Battery status", "struct" : var, "need" : True, "values" : + [{"name" : "battery_status", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x6001 : {"name" : "Charger status", "struct" : var, "need" : True, "values" : + [{"name" : "charger_status", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6010 : {"name" : "temperature", "struct" : var, "need" : True, "values" : + [{"name" : "temperature", "type" : 0x03, "access" : 'ro', "pdo" : True}]}, + + 0x6020 : {"name" : "Battery parameters", "struct" : array, "need" : True, "values" : + [{"name" : "highest sub-index supported", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "battery type", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "ah capacity", "type" : 0x06, "access" : 'ro', "pdo" : False}, + {"name" : "maximum charge current", "type" : 0x06, "access" : 'ro', "pdo" : False}, + {"name" : "number of cells", "type" : 0x06, "access" : 'ro', "pdo" : False}]}, + + 0x6030 : {"name" : "Battery serial number", "struct" : array, "need" : False, "values" : + [{"name" : "number of elements", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 1 to 4", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 5 to 8", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 9 to 10", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + + 0x6031 : {"name" : "Battery ID", "struct" : array, "need" : False, "values" : + [{"name" : "number of elements", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 1 to 4", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 5 to 8", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 9 to 12", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 13 to 16", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 17 to 20", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + + 0x6040 : {"name" : "vehicle serial number", "struct" : array, "need" : False, "values" : + [{"name" : "number of elements", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 1 to 4", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 5 to 8", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 9 to 12", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 13 to 16", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 17 to 20", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + + 0x6041 : {"name" : "vehicle ID", "struct" : array, "need" : False, "values" : + [{"name" : "number of elements", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 1 to 4", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 5 to 8", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 9 to 12", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 13 to 16", "type" : 0x07, "access" : 'ro', "pdo" : False}, + {"name" : "packed ASCII characters 17 to 20", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + + 0x6050 : {"name" : "cumulative total ah charge", "struct" : var, "need" : False, "values" : + [{"name" : "cumulative total ah charge", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + + 0x6051 : {"name" : "ah expected since last charge", "struct" : var, "need" : False, "values" : + [{"name" : "ah expected since last charge", "type" : 0x07, "access" : 'ro', "pdo" : False}]}, + + 0x6052 : {"name" : "Ah returned during last charge", "struct" : var, "need" : False, "values" : + [{"name" : "ah returned during last charge", "type" : 0x06, "access" : 'rw', "pdo" : True}]}, + + 0x6053 : {"name" : "ah since last equalization", "struct" : var, "need" : False, "values" : + [{"name" : "ah since last equalization", "type" : 0x06, "access" : 'rw', "pdo" : False}]}, + + 0x6041 : {"name" : "date of laste equalization", "struct" : array, "need" : False, "values" : + [{"name" : "number of elements", "type" : 0x05, "access" : 'ro', "pdo" : False}, + {"name" : "number of minutes", "type" : 0x06, "access" : 'rw', "pdo" : False}, + {"name" : "number of days", "type" : 0x06, "access" : 'rw', "pdo" : False}]}, + + 0x6060 : {"name" : "Battery voltage", "struct" : var, "need" : False, "values" : + [{"name" : "battery voltage", "type" : 0x07, "access" : 'ro', "pdo" : True}]}, + + 0x6070 : {"name" : "Charge current requested", "struct" : var, "need" : False, "values" : + [{"name" : "charge current requested", "type" : 0x06, "access" : 'ro', "pdo" : True}]}, + + 0x6080 : {"name" : "Charger state of charge", "struct" : var, "need" : False, "values" : + [{"name" : "charge state of charge", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6081 : {"name" : "Battery state of charge", "struct" : var, "need" : False, "values" : + [{"name" : "battery state of charge", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x6090 : {"name" : "Water level status", "struct" : var, "need" : False, "values" : + [{"name" : "Water level status", "type" : 0x05, "access" : 'ro', "pdo" : False}]} + +} + +AddMenuEntries = [] diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/DS-419.prf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/DS-419.prf Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,31 @@ +global Mapping, AddMenuEntries + +""" +MappingDictionary for DS-419 +""" + +Mapping = { + 0x6000 : {"name" : "Battery status", "struct" : var, "need" : True, "values" : + [{"name" : "battery_status", "type" : 0x05, "access" : 'rw', "pdo" : True}]}, + + 0x6001 : {"name" : "Charger status", "struct" : var, "need" : True, "values" : + [{"name" : "charger_status", "type" : 0x06, "access" : 'rw', "pdo" : True}]}, + + 0x6052 : {"name" : "Ah returned during last charge", "struct" : var, "need" : False, "values" : + [{"name" : "ah_returned_during_last_charge", "type" : 0x06, "access" : 'ro', "pdo" : True}]}, + + 0x6060 : {"name" : "Battery voltage", "struct" : var, "need" : False, "values" : + [{"name" : "battery_voltage", "type" : 0x07, "access" : 'rw', "pdo" : True}]}, + + 0x6070 : {"name" : "Charge current requested", "struct" : var, "need" : False, "values" : + [{"name" : "charge_current_requested", "type" : 0x06, "access" : 'rw', "pdo" : True}]}, + + 0x6080 : {"name" : "Charger state of charge", "struct" : var, "need" : False, "values" : + [{"name" : "charge_state_of_charge", "type" : 0x05, "access" : 'ro', "pdo" : True}]}, + + 0x6081 : {"name" : "Battery state of charge", "struct" : var, "need" : False, "values" : + [{"name" : "battery_state_of_charge", "type" : 0x05, "access" : 'rw', "pdo" : True}]} + +} + +AddMenuEntries = [] diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/objdict.xsd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/objdict.xsd Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,304 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/objdict.xsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/objdict.xsl Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,404 @@ + + + + + + + + + CANOpen object dictionary Configuration + + + + + +

Object dictionary for Node :

+

Node identity

+
    +
  • Device type (index 0x1000) : + + + + + + Undefined + + +
  • +
  • Manufacturer device name (index 0x1008) : + + + + + + Undefined + + +
  • +
  • Manufacturer hardware version (index 0x1009) : + + + + + + Undefined. Default is the compilation date of objdict.c + + +
  • +
  • Manufacturer software version (index 0x100A) : + + + + + + Undefined. Default is the compilation time of objdict.c + + +
  • +
  • Vendor id (index 0x1018, subindex 1) : + + + + + + Undefined + + +
  • +
  • Product code (index 0x1018, subindex 2) : + + + + + + Undefined + + +
  • +
  • Revision number (index 0x1018, subindex 3) : + + + + + + Undefined + + +
  • +
  • Serial number (index 0x1018, subindex 4) : + + + + + + Undefined + + +
  • +
+ + + +

Mapped variables and tables

+

+ The access of the variable is by default "rw". A read-only variable cannot be mapped in a PDO receive. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + + + +
Var NameBitsIndexSub-indexaccessType (UNS/REAL)Min valueMax value
Table NameBitsIndexSub-indexaccessType (UNS/REAL)Min valueMax value
String NameBytesIndexSub-indexaccess
+ + +
+ + + +

Number of heartbeat consumers : + +

+

This means that the node can expect heartbeats sent by nodes. Canfestival limitation : You must at least have one.

+
+ + +

Number of SDO clients : + +

+

Usualy, a slave node does not have the use of SDO clients, but + today - it is a Canfestival limitation - you must define at least one. +

+

+ The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Number of SDO servers : + 1 (cannot be changed) +

+

A Canfestival node must have exactly one SDO server, defined at index 0x1200. The user cannot change this.

+
+ + + +

PDO + + + receive. + + + transmit. + + + Undefined. Not normal !!!! + + + CobId : + + + + + + Undefined (Using default). + + + Index communication parameter : + + + + + + Undefined (Using default). + + +

+
    +
  • + Maximum of objects (ie variables) that can be embeded : + + + + + + Undefined (Using default : 8). + + +
  • +
  • + Transmission type : + + + + + + Undefined (Using default : 253). + + +
  • +
+

Default mapped objects :

+ + + + + +
Var NameBitsIndexSub-index
+ + +

About the cobId : The 4th first PDO receive defined at index 0x1400 to 0x1403, or transmit (0x1800 to 0x1803) are changed at runtime according to the DS 301, whatever the value you put here.

+

If the Index communication parameter is not defined, have a look at objdict.c to know what index have beed created.

+

It is not required to map some objects in a PDO. It can also be done by the node itself at runtime, or by an other node whith the SDO functionalitie.

+
+ + + + + + + + + + + + Undefined + + + + + + + + + + + + + + + + + + + + Undefined. Default is RW + + + + + + + + Undefined. Default is UNS + + + + + + + + Undefined + + + + + + + + Undefined + + + + + + + + [] + + + 1 to + + + + + + Undefined. Default is RW + + + + + + + + Undefined. Default is UNS + + + + + + + + Undefined + + + + + + + + Undefined + + + + + + + + + + + + + + + + + Undefined. Default is RW + + + + + +
diff -r 000000000000 -r 4472ee7c6c3e objdictgen/config/objdict_Jaxe_cfg.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/config/objdict_Jaxe_cfg.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e objdictgen/doc_index/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/doc_index/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1 @@ +*.pyc diff -r 000000000000 -r 4472ee7c6c3e objdictgen/doc_index/DS301_index.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/doc_index/DS301_index.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os + +DS301_PDF_INDEX = {0x1000: 86, 0x1001: 87, 0x1002: 87, 0x1003: 88, 0x1005: 89, 0x1006: 90, 0x1007: 90, 0x1008: 91, 0x1009: 91, 0x100A: 91, 0x100C: 92, 0x100D: 92, 0x1010: 92, 0x1011: 94, 0x1012: 97, 0x1013: 98, 0x1014: 98, 0x1015: 99, 0x1016: 100, 0x1017: 101, 0x1018: 101, 0x1020: 117, 0x1200: 103, 0x1201: 103, 0x1280: 105, 0x1400: 106, 0x1600: 109, 0x1800: 111, 0x1A00: 112} + +def OpenPDFDocIndex(index): + if index not in DS301_PDF_INDEX: + return """No documentation for this index.""" + if not os.path.isfile("../doc/301_v04000201.pdf"): + return """No documentation file available. +Please read can festival documentation to know how to obtain one.""" + try: + os.system("xpdf -remote DS301 ../doc/301_v04000201.pdf "+str(DS301_PDF_INDEX[index])+" &") + return True + except: + return """Check if xpdf is correctly installed on your computer""" + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e objdictgen/doc_index/__init__.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/doc_index/__init__.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,3 @@ +# Package initialisation + +from DS301_index import * diff -r 000000000000 -r 4472ee7c6c3e objdictgen/examples/example_objdict.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/examples/example_objdict.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,579 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include + +#include +#include "canfestival/def.h" +#include "canfestival/can.h" +#include "canfestival/objdictdef.h" +#include "canfestival/pdo.h" +#include "canfestival/sdo.h" +#include "canfestival/sync.h" +#include "canfestival/lifegrd.h" +#include "canfestival/nmtSlave.h" + +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ +UNS8 seconds = 0; // Mapped at index 0x2000, subindex 0x01 +UNS8 minutes = 0; // Mapped at index 0x2000, subindex 0x02 +UNS8 hours = 0; // Mapped at index 0x2000, subindex 0x03 +UNS8 day = 0; // Mapped at index 0x2000, subindex 0x04 +UNS32 canopenErrNB = 0; // Mapped at index 0x6000, subindex 0x00 +UNS32 canopenErrVAL = 0; // Mapped at index 0x6001, subindex 0x00 +UNS8 strTest[10] = 0; // Mapped at index 0x6002, subindex 0x00 + +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ + + + +UNS32 Linux_slave_valueRangeTest (UNS8 typeValue, UNS32 unsValue, REAL32 realValue) +{ + switch (typeValue) { + } + return 0; +} + + +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* node_id default value. + This default value is deprecated. + You should always overwrite this by using the function setNodeId(UNS8 nodeId) in your C code. +*/ +#define NODE_ID 0x01 +UNS8 Linux_slave_bDeviceNodeId = NODE_ID; + + +//*****************************************************************************/ +/* Array of message processing information */ +/* Should not be modified */ + +const UNS8 Linux_slave_iam_a_slave = 1 + + // Macros definition + +/* Beware : +index *must* be writen 4 numbers in hexa +sub_index *must* be writen 2 numbers in hexa +size_variable_in_UNS8 *must* be writen 2 numbers in hexa +*/ +#define PDO_MAP(index, sub_index, size_variable_in_bits)\ +0x ## index ## sub_index ## size_variable_in_bits + +/** This macro helps creating the object dictionary entries. + * by calling this macro + * it creates an entry in form of: 7 of entries, pointer to the entry. + */ +#define DeclareIndexTableEntry(entryname, index) { (subindex*)entryname,sizeof(entryname)/sizeof(entryname[0]), index} + +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// Make your change, depending of your application + + +/* index 0x1000 : Device type. + You have to change the value below, so + it fits your canopen-slave-module */ + + /* Not used, so, should not be modified */ + + UNS32 Linux_slave_obj1000 = 0; + subindex Linux_slave_Index1000[] = + { + { RO, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1000 } + }; + +/* index 0x1001 : Error register. + Change the entries to fit your application + Not used, so, should not be modified */ + /*const*/ UNS8 Linux_slave_obj1001 = 0x0; + /*const*/ subindex Linux_slave_Index1001[] = + { + { RO, uint8, sizeof(UNS8), (void*)&Linux_slave_obj1001 } + }; + +/* index 0x1005 : COB_ID SYNC */ + /* Should not be modified */ + UNS32 Linux_slave_obj1005 = 0x00000080; // bit 30 = 1 : device can generate a SYNC message + // Beware, it is over written when the node + // enters in reset mode + // See initResetMode() in init.c + /*const*/ subindex Linux_slave_Index1005[] = + { + { RW, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1005 } + }; + +/* index 0x1006 : SYNC period */ + // For producing the SYNC signal every n micro-seconds. + // Put 0 to not producing SYNC + /*const*/ UNS32 Linux_slave_obj1006 = 0x0; + // Default 0 to not produce SYNC // + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + /*const*/ subindex Linux_slave_Index1006[] = + { + { RW, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1006 } + }; + +/* index 0x1007 : Synchronous Window Length + Seems to be needed by DS401 to generate the SYNC signal ! */ + /*const*/ UNS32 Linux_slave_obj1007 = 0x0; /* Default 0 */ + /*const*/ subindex Linux_slave_Index1007[] = + { + { RW, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1007 } + }; + +/* index 0x1008 : Manufacturer device name */ + UNS8 Linux_slave_obj1008[] = "Appli_Slave_HC12"; /* Default 0 */ + subindex Linux_slave_Index1008[] = + { + { RO, uint32, sizeof(Linux_slave_obj1008), (void*)&Linux_slave_obj1008 } + }; + +/* index 0x1009 : Manufacturer hardware version */ + UNS8 Linux_slave_obj1009[] = "__DATE__"; /* Default 0 */ + subindex Linux_slave_Index1009[] = + { + { RO, uint32, sizeof(Linux_slave_obj1009), (void*)&Linux_slave_obj1009 } + }; + +/* index 0x100A : Manufacturer software version */ + UNS8 Linux_slave_obj100A[] = __TIME__; /* Default 0 */ + subindex Linux_slave_Index100A[] = + { + { RO, uint32, Linux_slave_sizeof(obj100A), (void*)&Linux_slave_obj100A} + }; + + + TIMER_HANDLE Linux_slave_heartBeatTimers[1] = {TIMER_NONE,}; +/* index 0x1016 : HeartBeat consumers + The nodes which can send a heartbeat */ + UNS32 Linux_slave_obj1016[] = {// Consumer time for each node + 0x00000000}; // Format 0x00NNTTTT (N=Node T=time in ms) + + UNS8 Linux_slave_obj1016_cnt = 1; // 1 nodes could send me + // their heartbeat. + subindex Linux_slave_Index1016[] = + { + { RO, uint8, sizeof(UNS8), (void*)&Linux_slave_obj1016_cnt }, + { RW, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1016[0] } + }; + +/* index 0x1017 : Heartbeat producer + Every HBProducerTime, the node sends its heartbeat */ + UNS16 Linux_slave_obj1017 = 0; //HBProducerTime in ms. If 0 : not activated + // Beware, it is over written when the + // node enters in reset mode. + // See initResetMode() in init.c + subindex Linux_slave_Index1017[] = + { + { RW, uint16, sizeof(UNS16), &Linux_slave_obj1017 } + }; + +/* index 0x1018 : Identity object */ + /** index 1018: identify object. Adjust the entries for your node/company + */ + /* Values can be modified */ + + s_identity Linux_slave_obj1018 = + { + 4, // number of supported entries + 0, // Vendor-ID (given by the can-cia) + 0, // Product Code + 0, // Revision number + 0 // serial number + }; + + subindex Linux_slave_Index1018[] = + { + { RO, uint8, sizeof(UNS8), (void*)&Linux_slave_obj1018.count }, + { RO, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1018.vendor_id}, + { RO, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1018.product_code}, + { RO, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1018.revision_number}, + { RO, uint32, sizeof(UNS32), (void*)&Linux_slave_obj1018.serial_number} + }; + +/* index 0x1200 : The SDO Server parameters */ + /* BEWARE You cannot define more than one SDO server */ + /* The values should not be modified here, + but can be changed at runtime */ + // Beware that the default values that you could put here + // will be over written at the initialisation of the node. + // See setNodeId() in init.c + s_sdo_parameter Linux_slave_obj1200 = + { 3, // Number of entries. Always 3 for the SDO + 0x601, // The cob_id transmited in CAN msg to the server + 0x581, // The cob_id received in CAN msg from the server + 0x01 // The node id of the client. Should not be modified + }; + subindex Linux_slave_Index1200[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1200.count }, + { RO, uint32, sizeof( UNS32), (void*)&Linux_slave_obj1200.cob_id_client }, + { RO, uint32, sizeof( UNS32), (void*)&Linux_slave_obj1200.cob_id_server }, + { RW, uint8, sizeof( UNS8), (void*)&Linux_slave_obj1200.node_id } + }; + +/* index 0x1280 : SDO client parameter */ + s_sdo_parameter Linux_slave_obj1280 = + { 3, // Nb of entries + 0x600, // cobid transmited to the server. The good value should be 0x600 + server nodeId + 0x580, // cobid received from the server. The good value should be 0x580 + server nodeId + 0x01 // server NodeId + }; + subindex Linux_slave_Index1280[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1280.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1280.cob_id_client }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1280.cob_id_server }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1280.node_id } + }; + +/* index 0x1400 : PDO receive communication parameter */ + s_pdo_communication_parameter Linux_slave_obj1400 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + subindex Linux_slave_Index1400[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1400.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1400.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1400.type }, + }; + +/* index 0x1401 : PDO receive communication parameter */ + s_pdo_communication_parameter Linux_slave_obj1401 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + subindex Linux_slave_Index1401[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1401.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1401.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1401.type }, + }; + +/* index 0x1402 : PDO receive communication parameter */ + s_pdo_communication_parameter Linux_slave_obj1402 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + subindex Linux_slave_Index1402[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1402.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1402.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1402.type }, + }; + +/* index 0x1600 : PDO receive mapping parameter of PDO communication index 0x1400 */ + UNS8 Linux_slave_obj1600_cnt = 0; // Number of mapped variables + UNS32 Linux_slave_obj1600_mappedVar[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }; + subindex Linux_slave_Index1600[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1600_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1600_mappedVar[7]} + }; + +/* index 0x1601 : PDO receive mapping parameter of PDO communication index 0x1401 */ + UNS8 Linux_slave_obj1601_cnt = 0; // Number of mapped variables + UNS32 Linux_slave_obj1601_mappedVar[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }; + subindex Linux_slave_Index1601[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1601_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1601_mappedVar[7]} + }; + +/* index 0x1602 : PDO receive mapping parameter of PDO communication index 0x1402 */ + UNS8 Linux_slave_obj1602_cnt = 0; // Number of mapped variables + UNS32 Linux_slave_obj1602_mappedVar[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }; + subindex Linux_slave_Index1602[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1602_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1602_mappedVar[7]} + }; + +/* index 0x1800 : PDO transmit communication parameter */ + s_pdo_communication_parameter Linux_slave_obj1800 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + subindex Linux_slave_Index1800[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1800.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1800.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1800.type }, + }; + +/* index 0x1801 : PDO transmit communication parameter */ + s_pdo_communication_parameter Linux_slave_obj1801 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + subindex Linux_slave_Index1801[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1801.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1801.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1801.type }, + }; + +/* index 0x1802 : PDO transmit communication parameter */ + s_pdo_communication_parameter Linux_slave_obj1802 = + { 2, // Largest subindex supported + 0x0, // Default COBID (overwritten at init for index 0x1400 to 0x1403) + 253 // Transmission type. See objdictdef.h + }; + subindex Linux_slave_Index1802[] = + { + { RO, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1802.count }, + { RW, uint8, sizeof( UNS32 ), (void*)&Linux_slave_obj1802.cob_id }, + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1802.type }, + }; + +/* index 0x1A00 : PDO transmit mapping parameter of PDO communication index 0x1800 */ + UNS8 Linux_slave_obj1A00_cnt = 0; // Number of mapped variables + UNS32 Linux_slave_obj1A00_mappedVar[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }; + subindex Linux_slave_Index1A00[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1A00_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A00_mappedVar[7]} + }; + +/* index 0x1A01 : PDO transmit mapping parameter of PDO communication index 0x1801 */ + UNS8 Linux_slave_obj1A01_cnt = 0; // Number of mapped variables + UNS32 Linux_slave_obj1A01_mappedVar[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }; + subindex Linux_slave_Index1A01[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1A01_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A01_mappedVar[7]} + }; + +/* index 0x1A02 : PDO transmit mapping parameter of PDO communication index 0x1802 */ + UNS8 Linux_slave_obj1A02_cnt = 0; // Number of mapped variables + UNS32 Linux_slave_obj1A02_mappedVar[] = { + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000 + }; + subindex Linux_slave_Index1A02[] = + { + { RW, uint8, sizeof( UNS8 ), (void*)&Linux_slave_obj1A02_cnt }, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[0]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[1]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[2]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[3]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[4]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[5]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[6]}, + { RW, uint32, sizeof( UNS32 ), (void*)&Linux_slave_obj1A02_mappedVar[7]} + }; + + +/* index 0x2000 : Mapped variable */ + UNS8 Linux_slave_highestSubIndex_2000 = 4; // number of subindex - 1 + subindex Linux_slave_Index2000[] = + { + { RO, uint8, sizeof (UNS8), (void*)&Linux_slave_highestSubIndex_2000 }, + { RW, uint8, sizeof (UNS8), (void*)&seconds }, + { RW, uint8, sizeof (UNS8), (void*)&minutes }, + { RW, uint8, sizeof (UNS8), (void*)&hours }, + { RW, uint8, sizeof (UNS8), (void*)&day } + }; + +/* index 0x6000 : Mapped variable */ + UNS8 Linux_slave_highestSubIndex_6000 = 0; // number of subindex - 1 + subindex Linux_slave_Index6000[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrNB } + }; + +/* index 0x6001 : Mapped variable */ + UNS8 Linux_slave_highestSubIndex_6001 = 0; // number of subindex - 1 + subindex Linux_slave_Index6001[] = + { + { RW, uint32, sizeof (UNS32), (void*)&canopenErrVAL } + }; + +/* index 0x6002 : Mapped variable */ + UNS8 Linux_slave_highestSubIndex_6002 = 0; // number of subindex - 1 + subindex Linux_slave_Index6002[] = + { + { RW, visible_string, sizeof (strTest), (void*)&strTest } + }; + +const indextable Linux_slave_objdict[] = +{ + DeclareIndexTableEntry(Linux_slave_Index1000, 0x1000), + DeclareIndexTableEntry(Linux_slave_Index1001, 0x1001), + DeclareIndexTableEntry(Linux_slave_Index1005, 0x1005), + DeclareIndexTableEntry(Linux_slave_Index1006, 0x1006), + DeclareIndexTableEntry(Linux_slave_Index1007, 0x1007), + DeclareIndexTableEntry(Linux_slave_Index1008, 0x1008), + DeclareIndexTableEntry(Linux_slave_Index1009, 0x1009), + DeclareIndexTableEntry(Linux_slave_Index100A, 0x100A), + DeclareIndexTableEntry(Linux_slave_Index1016, 0x1016), + DeclareIndexTableEntry(Linux_slave_Index1017, 0x1017), + DeclareIndexTableEntry(Linux_slave_Index1018, 0x1018), + DeclareIndexTableEntry(Linux_slave_Index1200, 0x1200), + DeclareIndexTableEntry(Linux_slave_Index1280, 0x1280), + DeclareIndexTableEntry(Linux_slave_Index1400, 0x1400), + DeclareIndexTableEntry(Linux_slave_Index1401, 0x1401), + DeclareIndexTableEntry(Linux_slave_Index1402, 0x1402), + DeclareIndexTableEntry(Linux_slave_Index1600, 0x1600), + DeclareIndexTableEntry(Linux_slave_Index1601, 0x1601), + DeclareIndexTableEntry(Linux_slave_Index1602, 0x1602), + DeclareIndexTableEntry(Linux_slave_Index1800, 0x1800), + DeclareIndexTableEntry(Linux_slave_Index1801, 0x1801), + DeclareIndexTableEntry(Linux_slave_Index1802, 0x1802), + DeclareIndexTableEntry(Linux_slave_Index1A00, 0x1A00), + DeclareIndexTableEntry(Linux_slave_Index1A01, 0x1A01), + DeclareIndexTableEntry(Linux_slave_Index1A02, 0x1A02), + DeclareIndexTableEntry(Linux_slave_Index2000, 0x2000), + DeclareIndexTableEntry(Linux_slave_Index6000, 0x6000), + DeclareIndexTableEntry(Linux_slave_Index6001, 0x6001), + DeclareIndexTableEntry(Linux_slave_Index6002, 0x6002), +}; + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 Linux_slave_count_sync[1] = {0, }; + +quick_index Linux_slave_firstIndex = { + SDO_SVR : 11, + SDO_CLT : 12, + PDO_RCV : 13, + PDO_RCV_MAP : 16, + PDO_TRS : 19, + PDO_TRS_MAP : 22 +} + +quick_index Linux_slave_lastIndex{ + SDO_SVR : 11, + SDO_CLT : 12, + PDO_RCV : 15, + PDO_RCV_MAP : 18, + PDO_TRS : 21, + PDO_TRS_MAP : 24 +} + +UNS16 Linux_slave_ObjdictSize = sizeof(Linux_slave_objdict)/sizeof(Linux_slave_objdict[0]); + diff -r 000000000000 -r 4472ee7c6c3e objdictgen/examples/example_objdict.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/examples/example_objdict.h Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,28 @@ +/* +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 +*/ +extern UNS8 seconds; // Mapped at index 0x2000, subindex 0x01 +extern UNS8 minutes; // Mapped at index 0x2000, subindex 0x02 +extern UNS8 hours; // Mapped at index 0x2000, subindex 0x03 +extern UNS8 day; // Mapped at index 0x2000, subindex 0x04 +extern UNS32 canopenErrNB; // Mapped at index 0x6000, subindex 0x00 +extern UNS32 canopenErrVAL; // Mapped at index 0x6001, subindex 0x00 +extern UNS8 strTest[10]; // Mapped at index 0x6002, subindex 0x00 diff -r 000000000000 -r 4472ee7c6c3e objdictgen/examples/example_objdict.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/examples/example_objdict.html Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,167 @@ + + + + +CANOpen object dictionary Configuration + + + +

Object dictionary for Node :

+

+Linux_slaveslave +

+

Overview

+

+ How to make the object dictionary of the node ? + First, use Jaxe (command run_objdict) to edit an xml description file +of the dictionary : objdict.xml. +Then, run the php program : makeobjetdict.php. You can launch php through a web browser +if you have installed a server, or, on Linux, you can launch php in command line : +php-cgi makeobjetdict.php. It compute the file objdict.c. Link it to + your project. +
Note : To define the node id, use in your code the function setNodeId(UNS8 nodeId) +

+

+ Then the node can be connected to the network. The master must configure it + by sending SDO. It will write values in its index, subindex. What to configure ? +

    +
  • Receiving heartbeats from which nodes ? Waiting time ?
  • +
  • Emitting heartbeats or not ? time btw 2 heartbeats ?
  • +
  • Defining a cobId for each PDO receive and transmit
  • +
  • How to transmit a PDO ? on synchro ? request ? event ?
  • +
  • What variables to put in each PDO receive and transmit ?
  • +
  • ...
  • +
+

+ To avoid configuring the node at the connection, you can put the values directly +in the dictionary objdict.c. But it is boring and unsafe because it is too easy to make +a mistake ! + + +

Number of heartbeat consumers : + 1 +

+

This means that the node can expect heartbeats sent by 1 nodes.

+

Number of SDO clients : + 1 +

+

Usualy, a slave node does not have the use of SDO clients, but + today, for the library, you must define one. The Master, which can + send SDO to "n" slaves nodes, must define here "n" SDO + clients. Remember that in most cases, the SDO protocol is used by + the master to configure a slave dictionary or read a value. In + this use, the master is the client, and the slave is the server.

+

Maximum objects in a PDO (receive or transmit) : + 8 +

+

This is defining how many variables can be transmited in a + PDO. (maximum is 8).

+

For each variable, a table is created, so if you have less room + in memory, put a value under 8.

+

Number of PDO receive : + 3 +

+

The node can receive 3 PDO.

+

The communication parameters are defined at index 0x1400 to 0x1400 + 2

+

The mapping parameters are defined at index 0x1600 to 0x1600 + 2

+

Number of PDO transmit : + 3 +

+

The node can transmit 3 PDO.

+

The communication parameters are defined at index 0x1800 to 0x1800 + 2

+

The mapping parameters are defined at index 0x1A00 to 0x1A00 + 2

+

Mapped variables and tables

+

3 tables are defined for the mapping, starting at index 0x2000, 0x6000 and 0x6200. + You must start the mapping at the beginning of one of a table, without holes in index +or subindex. For example, variables in 0x2000 and 0x2001 is ok, but variables in 0x2000 and 0x2002 is not allowed, because you are loosing room in memory. It is the same for the subindex. +

+

+ The access of the variable is by default "rw" (read-write) or "ro" (read-only). A read-only variable cannot be mapped in a PDO receive. +

+

Here are some others rules for the mapping :

+
    +
  • At an Index, you can map a variable at subindex 0x0 or 0x1, as you like.
  • +
  • To map several variables at the same Index, you must start at subindex 0x1, + because in this case, the subindex 0x0 contains the number of subindex.
  • +
  • You cannot map variables and tables at the same index.
  • +
  • The mapping of a table is always starting at subindex 0x1.
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Var NameBitsIndexSub-indexaccess
seconds80x20050x1rw
minutes80x20050x02rw
hours80x20050x3rw
day80x20050x4rw
null80x20020x0ro
canopenErrNB320x60000x0rw
canopenErrVAL320x60010x0rw
Table NameBitsIndexSub-indexaccess
table_essai[5]80x20061 to 5ro
table_encore_un_essai[3]160x20011 to 3ro
+ + diff -r 000000000000 -r 4472ee7c6c3e objdictgen/examples/example_objdict.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/examples/example_objdict.xml Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e objdictgen/gen_cfile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/gen_cfile.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,492 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +copyright_notice="""/* +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 +*/ +""" + +from node import * +from types import * + +import re, os + +word_model = re.compile('([a-zA-Z_0-9]*)') +type_model = re.compile('([\_A-Z]*)([0-9]*)') +range_model = re.compile('([\_A-Z]*)([0-9]*)\[([\-0-9]*)-([\-0-9]*)\]') + +categories = [("SDO_SVR", 0x1200, 0x127F), ("SDO_CLT", 0x1280, 0x12FF), + ("PDO_RCV", 0x1400, 0x15FF), ("PDO_RCV_MAP", 0x1600, 0x17FF), + ("PDO_TRS", 0x1800, 0x19FF), ("PDO_TRS_MAP", 0x1A00, 0x1BFF)] +index_categories = ["firstIndex", "lastIndex"] + +generated_tag = """\n/* File generated by gen_cfile.py. Should not be modified. */\n""" + +# Format a string for making a C++ variable +def FormatName(name): + wordlist = [word for word in word_model.findall(name) if word != ''] + result = '' + sep = '' + for word in wordlist: + result += "%s%s"%(sep,word) + sep = '_' + return result + +# Extract the informations from a given type name +def GetValidTypeInfos(typename): + result = type_model.match(typename) + if result: + values = result.groups() + if values[0] in ("UNSIGNED", "INTEGER") and eval(values[1]) in [i * 8 for i in xrange(1, 9)]: + return "UNS%s"%values[1], "", "uint%s"%values[1] + elif values[0] == "REAL" and eval(values[1]) in (32, 64): + return "%s%s"%(values[0], values[1]), "", "real%s"%values[1] + elif values[0] == "VISIBLE_STRING": + if values[1] == "": + return "UNS8", "[10]", "visible_string" + else: + return "UNS8", "[%s]"%values[1], "visible_string" + return None + +def WriteFile(filepath, content): + cfile = open(filepath,"w") + cfile.write(content) + cfile.close() + +def GenerateFileContent(Manager, headerfilepath): + global type + texts = {} + texts["maxPDOtransmit"] = 0 + texts["NodeName"], texts["NodeID"], texts["NodeType"] = Manager.GetCurrentNodeInfos() + internal_types = {} + texts["iam_a_slave"] = 0 + if (texts["NodeType"] == "slave"): + texts["iam_a_slave"] = 1 + + # Compiling lists of indexes + rangelist = [idx for name,idx in Manager.GetCurrentValidIndexes(0, 0x260)] + listIndex = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1000, 0xFFFF)] + communicationlist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1000, 0x11FF)] + sdolist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1200, 0x12FF)] + pdolist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x1400, 0x1BFF)] + variablelist = [idx for name,idx in Manager.GetCurrentValidIndexes(0x2000, 0xBFFF)] + +#------------------------------------------------------------------------------- +# Declaration of the value range types +#------------------------------------------------------------------------------- + + valueRangeContent = "" + strDefine = "" + strSwitch = "" + num = 0 + for index in rangelist: + rangename = Manager.GetEntryName(index) + result = range_model.match(rangename) + if result: + num += 1 + internal_types[rangename] = "valueRange_%d"%num + typeindex = Manager.GetCurrentEntry(index, 1) + typename = Manager.GetTypeName(typeindex) + typeinfos = GetValidTypeInfos(typename) + if typeinfos == None: + raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename + typename = typeinfos[0] + minvalue = str(Manager.GetCurrentEntry(index, 2)) + maxvalue = str(Manager.GetCurrentEntry(index, 3)) + strDefine += "\n#define valueRange_%d 0x%02X /* Type %s, %s < value < %s */"%(num,index,typename,minvalue,maxvalue) + strSwitch += """ case valueRange_%d: + if (*(%s*)Value < (%s)%s) return OD_VALUE_TOO_LOW; + if (*(%s*)Value > (%s)%s) return OD_VALUE_TOO_HIGH; + break;\n"""%(num,typename,typename,minvalue,typename,typename,maxvalue) + + valueRangeContent += strDefine + valueRangeContent += "\nUNS32 %(NodeName)s_valueRangeTest (UNS8 typeValue, void * value)\n{"%texts + valueRangeContent += "\n switch (typeValue) {\n" + valueRangeContent += strSwitch + valueRangeContent += " }\n return 0;\n}\n" + +#------------------------------------------------------------------------------- +# Creation of the mapped variables and object dictionary +#------------------------------------------------------------------------------- + + mappedVariableContent = "" + strDeclareHeader = "" + strDeclareCallback = "" + indexContents = {} + indexCallbacks = {} + for index in listIndex: + texts["index"] = index + strIndex = "" + entry_infos = Manager.GetEntryInfos(index) + texts["EntryName"] = entry_infos["name"] + values = Manager.GetCurrentEntry(index) + callbacks = Manager.HasCurrentEntryCallbacks(index) + if index in variablelist: + strIndex += "\n/* index 0x%(index)04X : Mapped variable %(EntryName)s */\n"%texts + else: + strIndex += "\n/* index 0x%(index)04X : %(EntryName)s. */\n"%texts + if type(values) == ListType: + texts["value"] = values[0] + strIndex += " UNS8 %(NodeName)s_highestSubIndex_obj%(index)04X = %(value)d; // number of subindex - 1\n"%texts + + # Entry type is VAR + if type(values) != ListType: + subentry_infos = Manager.GetSubentryInfos(index, 0) + typename = Manager.GetTypeName(subentry_infos["type"]) + typeinfos = GetValidTypeInfos(typename) + if typeinfos == None: + raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename + if typename not in internal_types: + internal_types[typename] = typeinfos[2] + texts["subIndexType"] = typeinfos[0] + texts["suffixe"] = typeinfos[1] + if typeinfos[2] == "visible_string": + texts["value"] = "\"%s\""%values + else: + texts["value"] = "0x%X"%values + if index in variablelist: + texts["name"] = FormatName(subentry_infos["name"]) + strDeclareHeader += "extern %(subIndexType)s %(name)s%(suffixe)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x00\n"%texts + if callbacks: + strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t// Callbacks of index0x%(index)04X\n"%texts + mappedVariableContent += "%(subIndexType)s %(name)s%(suffixe)s = %(value)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x00\n"%texts + else: + strIndex += " %(subIndexType)s %(NodeName)s_obj%(index)04X%(suffixe)s = %(value)s;\n"%texts + values = [values] + else: + + # Entry type is RECORD + if entry_infos["struct"] & OD_IdenticalSubindexes: + subentry_infos = Manager.GetSubentryInfos(index, 1) + typename = Manager.GetTypeName(subentry_infos["type"]) + typeinfos = GetValidTypeInfos(typename) + if typeinfos == None: + raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename + if typename not in internal_types: + internal_types[typename] = typeinfos[2] + texts["subIndexType"] = typeinfos[0] + texts["suffixe"] = typeinfos[1] + texts["length"] = values[0] + if index in variablelist: + texts["name"] = FormatName(entry_infos["name"]) + strDeclareHeader += "%(subIndexType)s %(name)s[%(length)d]%(suffixe)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x01 - 0x%(length)02X\n"%texts + if callbacks: + strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t// Callbacks of index0x%(index)04X\n"%texts + mappedVariableContent = "%(subIndexType)s %(name)s[] =\t\t// Mapped at index 0x%(index)04X, subindex 0x01 - 0x%(length)02X\n {\n"%texts + for subIndex, value in enumerate(values): + sep = "," + if subIndex > 0: + if subIndex == len(values)-1: + sep = "" + if typeinfos[2] == "visible_string": + value = "\"%s\""%value + else: + value = "0x%X"%value + mappedVariableContent += " %s%s\n"%(value, sep) + mappedVariableContent += " }\n" + else: + strIndex += " %(subIndexType)s %(NodeName)s_obj%(index)04X[] = \n {\n"%texts + for subIndex, value in enumerate(values): + sep = "," + if subIndex > 0: + if subIndex == len(values)-1: + sep = "" + if typeinfos[2] == "visible_string": + value = "\"%s\""%value + else: + value = str(value) + strIndex += " %s%s\n"%(value, sep) + strIndex += " };\n" + else: + + # Entry type is ARRAY + for subIndex, value in enumerate(values): + texts["subIndex"] = subIndex + if subIndex > 0: + subentry_infos = Manager.GetSubentryInfos(index, subIndex) + typename = Manager.GetTypeName(subentry_infos["type"]) + typeinfos = GetValidTypeInfos(typename) + if typeinfos == None: + raise ValueError, """!!! %s isn't a valid type for CanFestival."""%typename + if typename not in internal_types: + internal_types[typename] = typeinfos[2] + texts["subIndexType"] = typeinfos[0] + texts["suffixe"] = typeinfos[1] + if typeinfos[2] == "visible_string": + texts["value"] = "\"%s\""%value + else: + texts["value"] = "0x%X"%value + texts["name"] = FormatName(subentry_infos["name"]) + if index in variablelist: + strDeclareHeader += "extern %(subIndexType)s %(name)s%(suffixe)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x%(subIndex)02X\n"%texts + mappedVariableContent += "%(subIndexType)s %(name)s%(suffixe)s = %(value)s;\t\t// Mapped at index 0x%(index)04X, subindex 0x%(subIndex)02X\n"%texts + else: + strIndex += " %(subIndexType)s %(NodeName)s_obj%(index)04X_%(name)s%(suffixe)s = %(value)s;\n"%texts + if callbacks: + texts["name"] = FormatName(entry_infos["name"]) + strDeclareHeader += "extern ODCallback_t %(name)s_callbacks[];\t\t// Callbacks of index0x%(index)04X\n"%texts + + # Generating Dictionary C++ entry + if callbacks: + if index in variablelist: + name = FormatName(entry_infos["name"]) + else: + name = "%(NodeName)s_Index%(index)04X"%texts + strIndex += " ODCallback_t %s_callbacks[] = \n {\n"%name + for subIndex in xrange(len(values)): + strIndex += " NULL,\n" + strIndex += " };\n" + indexCallbacks[index] = "*callbacks = %s_callbacks; "%name + else: + indexCallbacks[index] = "" + strIndex += " subindex %(NodeName)s_Index%(index)04X[] = \n {\n"%texts + for subIndex in xrange(len(values)): + subentry_infos = Manager.GetSubentryInfos(index, subIndex) + if subIndex < len(values) - 1: + sep = "," + else: + sep = "" + typename = Manager.GetTypeName(subentry_infos["type"]) + typeinfos = GetValidTypeInfos(typename) + if typename.startswith("VISIBLE_STRING"): + subIndexType = "visible_string" + elif typename in internal_types: + subIndexType = internal_types[typename] + else: + subIndexType = typename + if subIndex == 0: + if entry_infos["struct"] & OD_MultipleSubindexes: + name = "%(NodeName)s_highestSubIndex_obj%(index)04X"%texts + elif index in variablelist: + name = FormatName(subentry_infos["name"]) + else: + name = FormatName("%s_obj%04X"%(texts["NodeName"], texts["index"])) + elif entry_infos["struct"] & OD_IdenticalSubindexes: + if index in variablelist: + name = "%s[%d]"%(FormatName(entry_infos["name"]), subIndex - 1) + else: + name = "%s_obj%04X[%d]"%(texts["NodeName"], texts["index"], subIndex - 1) + else: + if index in variablelist: + name = FormatName(subentry_infos["name"]) + else: + name = "%s_obj%04X_%s"%(texts["NodeName"], texts["index"], FormatName(subentry_infos["name"])) + if subIndexType == "visible_string": + sizeof = name + else: + sizeof = typeinfos[0] + params = Manager.GetCurrentParamsEntry(index, subIndex) + if params["save"]: + save = "|TO_BE_SAVE" + else: + save = "" + strIndex += " { %s%s, %s, sizeof (%s), (void*)&%s }%s\n"%(subentry_infos["access"].upper(),save,subIndexType,sizeof,name,sep) + strIndex += " };\n" + indexContents[index] = strIndex + +#------------------------------------------------------------------------------- +# Declaration of Particular Parameters +#------------------------------------------------------------------------------- + + if 0x1006 not in communicationlist: + entry_infos = Manager.GetEntryInfos(0x1006) + texts["EntryName"] = entry_infos["name"] + indexContents[0x1006] = """\n/* index 0x1006 : %(EntryName)s */ + UNS32 %(NodeName)s_obj1006 = 0; +"""%texts + + if 0x1016 in communicationlist: + texts["nombre"] = Manager.GetCurrentEntry(0x1016, 0) + else: + texts["nombre"] = 0 + entry_infos = Manager.GetEntryInfos(0x1016) + texts["EntryName"] = entry_infos["name"] + indexContents[0x1016] = """\n/* index 0x1016 : %(EntryName)s */ + UNS8 %(NodeName)s_highestSubIndex_obj1016 = 0; + UNS32 %(NodeName)s_obj1016[0]; + subindex %(NodeName)s_Index1016[0]; +"""%texts + if texts["nombre"] > 0: + strTimers = "TIMER_HANDLE %(NodeName)s_heartBeatTimers[%(nombre)d] = {TIMER_NONE,};\n"%texts + else: + strTimers = "TIMER_HANDLE %(NodeName)s_heartBeatTimers[0];\n"%texts + + if 0x1017 not in communicationlist: + entry_infos = Manager.GetEntryInfos(0x1017) + texts["EntryName"] = entry_infos["name"] + indexContents[0x1017] = """\n/* index 0x1017 : %(EntryName)s */ + UNS16 %(NodeName)s_obj1017 = 0; +"""%texts + +#------------------------------------------------------------------------------- +# Declaration of navigation in the Object Dictionary +#------------------------------------------------------------------------------- + + strDeclareIndex = "" + strDeclareSwitch = "" + strQuickIndex = "" + quick_index = {} + for index_cat in index_categories: + quick_index[index_cat] = {} + for cat, idx_min, idx_max in categories: + quick_index[index_cat][cat] = 0 + maxPDOtransmit = 0 + for i, index in enumerate(listIndex): + texts["index"] = index + strDeclareIndex += " { (subindex*)%(NodeName)s_Index%(index)04X,sizeof(%(NodeName)s_Index%(index)04X)/sizeof(%(NodeName)s_Index%(index)04X[0]), 0x%(index)04X},\n"%texts + strDeclareSwitch += " case 0x%04X: i = %d;%sbreak;\n"%(index, i, indexCallbacks[index]) + for cat, idx_min, idx_max in categories: + if idx_min <= index <= idx_max: + quick_index["lastIndex"][cat] = i + if quick_index["firstIndex"][cat] == 0: + quick_index["firstIndex"][cat] = i + if cat == "PDO_TRS": + maxPDOtransmit += 1 + texts["maxPDOtransmit"] = max(1, maxPDOtransmit) + for index_cat in index_categories: + strQuickIndex += "\nquick_index %s_%s = {\n"%(texts["NodeName"], index_cat) + sep = "," + for i, (cat, idx_min, idx_max) in enumerate(categories): + if i == len(categories) - 1: + sep = "" + strQuickIndex += " %s : %d%s\n"%(cat, quick_index[index_cat][cat], sep) + strQuickIndex += "};\n" + +#------------------------------------------------------------------------------- +# Write File Content +#------------------------------------------------------------------------------- + + fileContent = copyright_notice + generated_tag + """ +#include "%s" +"""%(headerfilepath) + + fileContent += """ +/**************************************************************************/ +/* Declaration of the mapped variables */ +/**************************************************************************/ +""" + mappedVariableContent + + fileContent += """ +/**************************************************************************/ +/* Declaration of the value range types */ +/**************************************************************************/ +""" + valueRangeContent + + fileContent += """ +/**************************************************************************/ +/* The node id */ +/**************************************************************************/ +/* node_id default value.*/ +UNS8 %(NodeName)s_bDeviceNodeId = 0x%(NodeID)02X; + +//*****************************************************************************/ +/* Array of message processing information */ + +const UNS8 %(NodeName)s_iam_a_slave = %(iam_a_slave)d; + +"""%texts + fileContent += strTimers + + fileContent += """ +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +// +// OBJECT DICTIONARY +// +//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ +"""%texts + contentlist = indexContents.keys() + contentlist.sort() + for index in contentlist: + fileContent += indexContents[index] + + fileContent += """ +const indextable %(NodeName)s_objdict[] = +{ +"""%texts + fileContent += strDeclareIndex + fileContent += """}; + +const indextable * %(NodeName)s_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks) +{ + int i; + *callbacks = NULL; + switch(wIndex){ +"""%texts + fileContent += strDeclareSwitch + fileContent += """ default: + *errorCode = OD_NO_SUCH_OBJECT; + return NULL; + } + *errorCode = OD_SUCCESSFUL; + return &%(NodeName)s_objdict[i]; +} + +// To count at which received SYNC a PDO must be sent. +// Even if no pdoTransmit are defined, at least one entry is computed +// for compilations issues. +UNS8 %(NodeName)s_count_sync[%(maxPDOtransmit)d] = {0,}; +"""%texts + fileContent += strQuickIndex + fileContent += """ +UNS16 %(NodeName)s_ObjdictSize = sizeof(%(NodeName)s_objdict)/sizeof(%(NodeName)s_objdict[0]); + +CO_Data %(NodeName)s_Data = CANOPEN_NODE_DATA_INITIALIZER(%(NodeName)s); + +"""%texts + +#------------------------------------------------------------------------------- +# Write Header File Content +#------------------------------------------------------------------------------- + + HeaderFileContent = copyright_notice + generated_tag + """ +#include "data.h" + +// prototypes of function to be filled by app +void %(NodeName)s_SDOtimeoutError(UNS8 line); +void %(NodeName)s_heartbeatError(UNS8); + +UNS8 %(NodeName)s_canSend(Message *); + +void %(NodeName)s_initialisation(); +void %(NodeName)s_preOperational(); +void %(NodeName)s_operational(); +void %(NodeName)s_stopped(); + +void %(NodeName)s_post_sync(); +void %(NodeName)s_post_TPDO(); + +// Master node data struct +extern CO_Data %(NodeName)s_Data; + +"""%texts + HeaderFileContent += strDeclareHeader + + return fileContent,HeaderFileContent + +#------------------------------------------------------------------------------- +# Main Function +#------------------------------------------------------------------------------- + +def GenerateFile(filepath, manager): + headerfilepath = os.path.splitext(filepath)[0]+".h" + content, header = GenerateFileContent(manager, os.path.split(headerfilepath)[1]) + WriteFile(filepath, content) + WriteFile(headerfilepath, header) + return True diff -r 000000000000 -r 4472ee7c6c3e objdictgen/node.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/node.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,622 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of CanFestival, a library implementing CanOpen Stack. +# +#Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +# +#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 + +import cPickle +from types import * + +""" +Dictionary of translation between access symbol and their signification +""" +AccessType = {"ro" : "Read Only", "wo" : "Write Only", "rw" : "Read/Write"} + +BoolType = {True : "True", False : "False"} +OptionType = {True : "Yes", False : "No"} + +CustomisableTypes = [(0x02, 0), (0x03, 0), (0x04, 0), (0x05, 0), (0x06, 0), (0x07, 0), + (0x08, 0), (0x09, 1), (0x0A, 1), (0x0B, 1), (0x10, 0), (0x11, 0), (0x12, 0), + (0x13, 0), (0x14, 0), (0x15, 0), (0x16, 0), (0x18, 0), (0x19, 0), (0x1A, 0), + (0x1B, 0)] + +DefaultParams = {"comment" : "", "save" : False} + +#------------------------------------------------------------------------------- +# Dictionary Mapping and Organisation +#------------------------------------------------------------------------------- + +""" +Properties of entry structure in the Object Dictionary +""" +OD_Subindex = 1 # Entry has at least one subindex +OD_MultipleSubindexes = 2 # Entry has more than one subindex +OD_IdenticalSubindexes = 4 # Subindexes of entry have the same description +OD_IdenticalIndexes = 8 # Entry has the same description on multiple indexes + +""" +Structures of entry in the Object Dictionary, sum of the properties described above +for all sorts of entries use in CAN Open specification +""" +nosub = 0 # Entry without subindex (only for type declaration) +var = 1 +array = 3 +rec = 7 +# Entries identical on multiple indexes +plurivar = 9 +pluriarray = 11 # Example : PDO Parameters +plurirec = 15 # Example : PDO Mapping + +""" +MappingDictionary is the structure used for writing a good organised Object +Dictionary. It follows the specifications of the CANOpen standard. +Change the informations within it if there is a mistake. But don't modify the +organisation of this object, it will involve in a malfunction of the application. +""" + +MappingDictionary = { + 0x0001 : {"name" : "BOOLEAN", "struct" : nosub, "size" : 1, "default" : False, "values" : []}, + 0x0002 : {"name" : "INTEGER8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []}, + 0x0003 : {"name" : "INTEGER16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []}, + 0x0004 : {"name" : "INTEGER32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []}, + 0x0005 : {"name" : "UNSIGNED8", "struct" : nosub, "size" : 8, "default" : 0, "values" : []}, + 0x0006 : {"name" : "UNSIGNED16", "struct" : nosub, "size" : 16, "default" : 0, "values" : []}, + 0x0007 : {"name" : "UNSIGNED32", "struct" : nosub, "size" : 32, "default" : 0, "values" : []}, + 0x0008 : {"name" : "REAL32", "struct" : nosub, "size" : 32, "default" : 0.0, "values" : []}, + 0x0009 : {"name" : "VISIBLE_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []}, + 0x000A : {"name" : "OCTET_STRING", "struct" : nosub, "size" : 8, "default" : "", "values" : []}, + 0x000B : {"name" : "UNICODE_STRING", "struct" : nosub, "size" : 16, "default" : "", "values" : []}, + 0x000C : {"name" : "TIME_OF_DAY", "struct" : nosub, "size" : 48, "default" : 0, "values" : []}, + 0x000D : {"name" : "TIME_DIFFERENCE", "struct" : nosub, "size" : 48, "default" : 0, "values" : []}, + 0x000F : {"name" : "DOMAIN", "struct" : nosub, "size" : 0, "default" : "", "values" : []}, + 0x0010 : {"name" : "INTEGER24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []}, + 0x0011 : {"name" : "REAL64", "struct" : nosub, "size" : 64, "default" : 0.0, "values" : []}, + 0x0012 : {"name" : "INTEGER40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []}, + 0x0013 : {"name" : "INTEGER48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []}, + 0x0014 : {"name" : "INTEGER56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []}, + 0x0015 : {"name" : "INTEGER64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []}, + 0x0016 : {"name" : "UNSIGNED24", "struct" : nosub, "size" : 24, "default" : 0, "values" : []}, + 0x0018 : {"name" : "UNSIGNED40", "struct" : nosub, "size" : 40, "default" : 0, "values" : []}, + 0x0019 : {"name" : "UNSIGNED48", "struct" : nosub, "size" : 48, "default" : 0, "values" : []}, + 0x001A : {"name" : "UNSIGNED56", "struct" : nosub, "size" : 56, "default" : 0, "values" : []}, + 0x001B : {"name" : "UNSIGNED64", "struct" : nosub, "size" : 64, "default" : 0, "values" : []}, + 0x1000 : {"name" : "Device Type", "struct" : var, "need" : True, "values" : + [{"name" : "Device Type", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x1001 : {"name" : "Error Register", "struct" : var, "need" : True, "values" : + [{"name" : "Error Register", "type" : 0x02, "access": 'ro', "pdo" : True}]}, + 0x1002 : {"name" : "Manufacturer Status Register", "struct" : var, "need" : False, "values" : + [{"name" : "Manufacturer Status Register", "type" : 0x04, "access" : 'ro', "pdo" : True}]}, + 0x1003 : {"name" : "Pre-defined Error Field", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Errors", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Standard Error Field", "type" : 0x04, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]}, + 0x1005 : {"name" : "SYNC COB ID", "struct" : var, "need" : True, "callback" : True, "values" : + [{"name" : "SYNC COB ID", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1006 : {"name" : "Communication / Cycle Period", "struct" : var, "need" : False, "callback" : True, "values" : + [{"name" : "Communication Cycle Period", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1007 : {"name" : "Synchronous Window Length", "struct" : var, "need" : False, "values" : + [{"name" : "Synchronous Window Length", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1008 : {"name" : "Manufacturer Device Name", "struct" : var, "need" : False, "values" : + [{"name" : "Manufacturer Device Name", "type" : 0x09, "access" : 'ro', "pdo" : False}]}, + 0x1009 : {"name" : "Manufacturer Hardware Version", "struct" : var, "need" : False, "values" : + [{"name" : "Manufacturer Hardware Version", "type" : 0x09, "access" : 'ro', "pdo" : False}]}, + 0x100A : {"name" : "Manufacturer Software Version", "struct" : var, "need" : False, "values" : + [{"name" : "Manufacturer Software Version", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x100C : {"name" : "Guard Time", "struct" : var, "need" : False, "values" : + [{"name" : "Guard Time", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + 0x100D : {"name" : "Life Time Factor", "struct" : var, "need" : False, "values" : + [{"name" : "Life Time Factor", "type" : 0x02, "access" : 'rw', "pdo" : False}]}, + 0x1010 : {"name" : "Store parameters", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Save All Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Save Communication Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Save Application Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Save Manufacturer Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]}, + 0x1011 : {"name" : "Restore Default Parameters", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Restore All Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Restore Communication Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Restore Application Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Restore Manufacturer Default Parameters", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7C}]}, + 0x1012 : {"name" : "TIME COB ID", "struct" : var, "need" : False, "values" : + [{"name" : "TIME COB ID", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1013 : {"name" : "High Resolution Timestamp", "struct" : var, "need" : False, "values" : + [{"name" : "High Resolution Time Stamp", "type" : 0x04, "access" : 'rw', "pdo" : True}]}, + 0x1014 : {"name" : "Emergency COB ID", "struct" : var, "need" : False, "values" : + [{"name" : "Emergency COB ID", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1015 : {"name" : "Inhibit Time Emergency", "struct" : var, "need" : False, "values" : + [{"name" : "Inhibit Time Emergency", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + 0x1016 : {"name" : "Consumer Heartbeat Time", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Consumer Heartbeat Time", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7F}]}, + 0x1017 : {"name" : "Producer Heartbeat Time", "struct" : var, "need" : False, "values" : + [{"name" : "Producer Heartbeat Time", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + 0x1018 : {"name" : "Identity", "struct" : array, "need" : True, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Vendor ID", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Product Code", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Revision Number", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Serial Number", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x1020 : {"name" : "Verify Configuration", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Configuration Date", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Configuration Time", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x1021 : {"name" : "Store EDS", "struct" : var, "need" : False, "values" : + [{"name" : "Store EDS", "type" : 0x0F, "access" : 'rw', "pdo" : False}]}, + 0x1022 : {"name" : "Storage Format", "struct" : var, "need" : False, "values" : + [{"name" : "Storage Format", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1023 : {"name" : "OS Command", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Command", "type" : 0x0A, "access" : 'rw', "pdo" : False}, + {"name" : "Status", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Reply", "type" : 0x0A, "access" : 'ro', "pdo" : False}]}, + 0x1024 : {"name" : "OS Command Mode", "struct" : var, "need" : False, "values" : + [{"name" : "OS Command Mode", "type" : 0x02, "access" : 'wo', "pdo" : False}]}, + 0x1025 : {"name" : "OS Debugger Interface", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Command", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Status", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Reply", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x1026 : {"name" : "OS Prompt", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "StdIn", "type" : 0x02, "access" : 'wo', "pdo" : True}, + {"name" : "StdOut", "type" : 0x02, "access" : 'ro', "pdo" : True}, + {"name" : "StdErr", "type" : 0x02, "access" : 'ro', "pdo" : True}]}, + 0x1027 : {"name" : "Module List", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Connected Modules", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Module %d[(sub)]", "type" : 0x03, "access" : 'ro', "pdo" : False, "nbmax" : 0xFE}]}, + 0x1028 : {"name" : "Emergency Consumer", "struct" : rec, "need" : False, "values" : + [{"name" : "Number of Consumed Emergency Objects", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Emergency Consumer", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x7E}]}, + 0x1029 : {"name" : "Error Behavior", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Error Classes", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "Communication Error", "type" : 0x02, "access" : 'rw', "pdo" : False}, + {"name" : "Device Profile", "type" : 0x02, "access" : 'rw', "pdo" : False, "nbmax" : 0xFE}]}, + 0x1200 : {"name" : "Server SDO Parameter", "struct" : array, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x1201 : {"name" : "Additional Server SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x7F, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID Client to Server (Receive SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID Server to Client (Transmit SDO)", "type" : 0x04, "access" : 'ro', "pdo" : False}, + {"name" : "Node ID of the SDO Client", "type" : 0x04, "access" : 'ro', "pdo" : False}]}, + 0x1280 : {"name" : "Client SDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x100, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID Client to Server (Transmit SDO)", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "COB ID Server to Client (Receive SDO)", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Node ID of the SDO Server", "type" : 0x04, "access" : 'rw', "pdo" : False}]}, + 0x1400 : {"name" : "Receive PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" : + [{"name" : "Highest SubIndex Supported", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID used by PDO", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Transmission Type", "type" : 0x02, "access" : 'rw', "pdo" : False}, + {"name" : "Inhibit Time", "type" : 0x03, "access" : 'rw', "pdo" : False}, + {"name" : "Compatibility Entry", "type" : 0x03, "access" : 'rw', "pdo" : False}, + {"name" : "Event Timer", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + 0x1600 : {"name" : "Receive PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "PDO %d Mapping for an application object %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]}, + 0x1800 : {"name" : "Transmit PDO %d Parameter[(idx)]", "struct" : pluriarray, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" : + [{"name" : "Highest SubIndex Supported", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "COB ID used by PDO", "type" : 0x04, "access" : 'rw', "pdo" : False}, + {"name" : "Transmission Type", "type" : 0x02, "access" : 'rw', "pdo" : False}, + {"name" : "Inhibit Time", "type" : 0x03, "access" : 'rw', "pdo" : False}, + {"name" : "Compatibility Entry", "type" : 0x03, "access" : 'rw', "pdo" : False}, + {"name" : "Event Timer", "type" : 0x03, "access" : 'rw', "pdo" : False}]}, + 0x1A00 : {"name" : "Transmit PDO %d Mapping[(idx)]", "struct" : plurirec, "incr" : 1, "nbmax" : 0x200, "need" : False, "values" : + [{"name" : "Number of Entries", "type" : 0x02, "access" : 'ro', "pdo" : False}, + {"name" : "PDO %d Mapping for a process data variable %d[(idx,sub)]", "type" : 0x04, "access" : 'rw', "pdo" : False, "nbmax" : 0x40}]}, +} + +#------------------------------------------------------------------------------- +# Definition of Node Object +#------------------------------------------------------------------------------- + +""" +Class recording the Object Dictionary entries. It checks at each modification +that the structure of the Object Dictionary stay coherent +""" + +class Node: + + def __init__(self, name = "", type = "slave", id = 0, profilename = "DS-301", profile = {}, specificmenu = []): + self.Name = name + self.Type = type + self.ID = id + self.ProfileName = profilename + self.Profile = profile + self.SpecificMenu = specificmenu + self.Dictionary = {} + self.ParamsDictionary = {} + self.DS302 = {} + self.UserMapping = {} + + """ + Return the node name + """ + def GetNodeName(self): + return self.Name + + """ + Define the node name + """ + def SetNodeName(self, name): + self.Name = name + + """ + Return the node type ("master" or "slave") + """ + def GetNodeType(self): + return self.Type + + """ + Define the node type ("master" or "slave") + """ + def SetNodeType(self, type): + self.Type = type + + """ + Return the node ID + """ + def GetNodeID(self): + return self.ID + + """ + Define the node ID + """ + def SetNodeID(self, id): + self.ID = id + + """ + Return the Specific Profile Name + """ + def GetProfileName(self): + return self.ProfileName + + """ + Define the Specific Profile Name + """ + def SetProfileName(self, profilename): + self.ProfileName = profilename + + """ + Return the Specific Profile + """ + def GetProfile(self): + return self.Profile + + """ + Define the Specific Profile + """ + def SetProfile(self, profile): + self.Profile = profile + + """ + Define the DS-302 Profile + """ + def SetDS302Profile(self, profile): + self.DS302 = profile + + """ + Define the DS-302 Profile + """ + def GetDS302Profile(self): + return self.DS302 + + """ + Return the Specific Menu Entries + """ + def GetSpecificMenu(self): + return self.SpecificMenu + + """ + Define the Specific Menu Entries + """ + def SetSpecificMenu(self, specificmenu): + self.SpecificMenu = specificmenu + + """ + Extend the Specific Menu Entries + """ + + def ExtendSpecificMenu(self, specificmenu): + self.SpecificMenu.extend(AddMenuEntries) + + """ + Function which return the different Mappings available for this node + """ + def GetMappings(self, userdefinedtoo = True): + if userdefinedtoo: + return [self.Profile, self.DS302, self.UserMapping] + else: + return [self.Profile, self.DS302] + + """ + Add a new entry in the Object Dictionary + """ + def AddEntry(self, index, subIndex = None, value = None): + if index not in self.Dictionary: + if not subIndex: + self.Dictionary[index] = value + return True + elif subIndex == 1: + self.Dictionary[index] = [value] + return True + elif subIndex > 1 and type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]) + 1: + self.Dictionary[index].append(value) + return True + return False + + """ + Warning ! Modifies an existing entry in the Object Dictionary. Can't add a new one. + """ + def SetEntry(self, index, subIndex = None, value = None): + if index in self.Dictionary: + if not subIndex: + if value != None: + self.Dictionary[index] = value + return True + elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]): + if value != None: + self.Dictionary[index][subIndex - 1] = value + return True + return False + + def SetParamsEntry(self, index, subIndex = None, comment = None, save = None, callback = None): + if not getattr(self, "ParamsDictionary", False): + self.ParamsDictionary = {} + if index in self.Dictionary: + if (comment != None or save != None or callback != None) and index not in self.ParamsDictionary: + self.ParamsDictionary[index] = {} + if subIndex == None or type(self.Dictionary[index]) != ListType and subIndex == 0: + if comment != None: + self.ParamsDictionary[index]["comment"] = comment + if save != None: + self.ParamsDictionary[index]["save"] = save + if callback != None: + self.ParamsDictionary[index]["callback"] = callback + return True + elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]): + if (comment != None or save != None or callback != None) and subIndex not in self.ParamsDictionary[index]: + self.ParamsDictionary[index][subIndex] = {} + if comment != None: + self.ParamsDictionary[index][subIndex]["comment"] = comment + if save != None: + self.ParamsDictionary[index][subIndex]["save"] = save + return True + return False + + """ + Removes an existing entry in the Object Dictionary. If a subIndex is specified + it will remove this subIndex only if it's the last of the index. If no subIndex + is specified it removes the whole index and subIndexes from the Object Dictionary. + """ + def RemoveEntry(self, index, subIndex = None): + if not getattr(self, "ParamsDictionary", False): + self.ParamsDictionary = {} + if index in self.Dictionary: + if not subIndex: + self.Dictionary.pop(index) + if index in self.ParamsDictionary: + self.ParamsDictionary.pop(index) + return True + elif type(self.Dictionary[index]) == ListType and subIndex == len(self.Dictionary[index]): + self.Dictionary[index].pop(subIndex - 1) + if index in self.ParamsDictionary: + if subIndex in self.ParamsDictionary[index]: + self.ParamsDictionary[index].pop(subIndex) + if len(self.ParamsDictionary[index]) == 0: + self.ParamsDictionary.pop(index) + if len(self.Dictionary[index]) == 0: + self.Dictionary.pop(index) + if index in self.ParamsDictionary: + self.ParamsDictionary.pop(index) + return True + return False + + """ + Check if an entry exists in the Object Dictionary and returns the answer. + """ + def IsEntry(self, index): + if index in self.Dictionary: + return True + return False + + """ + Returns the value of the entry asked. If the entry has the value "count", it + returns the number of subIndex in the entry except the first. + """ + def GetEntry(self, index, subIndex = None): + if index in self.Dictionary: + if subIndex == None: + if type(self.Dictionary[index]) == ListType: + values = [len(self.Dictionary[index])] + values.extend(self.Dictionary[index]) + return values + else: + return self.Dictionary[index] + elif subIndex == 0: + if type(self.Dictionary[index]) == ListType: + return len(self.Dictionary[index]) + else: + return self.Dictionary[index] + elif type(self.Dictionary[index]) == ListType and 0 < subIndex <= len(self.Dictionary[index]): + return self.Dictionary[index][subIndex - 1] + return None + + """ + Returns the value of the entry asked. If the entry has the value "count", it + returns the number of subIndex in the entry except the first. + """ + def GetParamsEntry(self, index, subIndex = None): + if not getattr(self, "ParamsDictionary", False): + self.ParamsDictionary = {} + if index in self.Dictionary: + if subIndex == None: + if type(self.Dictionary[index]) == ListType: + if index in self.ParamsDictionary: + result = [] + for i in xrange(len(self.Dictionary[index]) + 1): + line = DefaultParams.copy() + if i in self.ParamsDictionary[index]: + line.update(self.ParamsDictionary[index][i]) + result.append(line) + return result + else: + return [DefaultParams.copy() for i in xrange(len(self.Dictionary[index]) + 1)] + else: + result = DefaultParams.copy() + if index in self.ParamsDictionary: + result.update(self.ParamsDictionary[index]) + return result + elif subIndex == 0 and type(self.Dictionary[index]) != ListType: + result = DefaultParams.copy() + if index in self.ParamsDictionary: + result.update(self.ParamsDictionary[index]) + return result + elif type(self.Dictionary[index]) == ListType and 0 <= subIndex <= len(self.Dictionary[index]): + result = DefaultParams.copy() + if index in self.ParamsDictionary and subIndex in self.ParamsDictionary[index]: + result.update(self.Dictionary[index][subIndex]) + return result + return None + + def HasEntryCallbacks(self, index): + if not getattr(self, "ParamsDictionary", False): + self.ParamsDictionary = {} + if index in self.Dictionary and index in self.ParamsDictionary and "callback" in self.ParamsDictionary[index]: + return self.ParamsDictionary[index]["callback"] + return False + + """ + Add a new entry in the User Mapping Dictionary + """ + def AddMappingEntry(self, index, subIndex = None, name = "Undefined", struct = 0, size = None, nbmax = None, default = None, values = None): + if index not in self.UserMapping: + if values == None: + values = [] + if subIndex == None: + self.UserMapping[index] = {"name" : name, "struct" : struct, "need" : False, "values" : values} + if size != None: + self.UserMapping[index]["size"] = size + if nbmax != None: + self.UserMapping[index]["nbmax"] = nbmax + if default != None: + self.UserMapping[index]["default"] = default + return True + elif subIndex != None and subIndex == len(self.UserMapping[index]["values"]): + if values == None: + values = {} + self.UserMapping[index]["values"].append(values) + return True + return False + + """ + Warning ! Modifies an existing entry in the User Mapping Dictionary. Can't add a new one. + """ + def SetMappingEntry(self, index, subIndex = None, name = None, struct = None, size = None, nbmax = None, default = None, values = None): + if index in self.UserMapping: + if subIndex == None: + if name != None: + self.UserMapping[index]["name"] = name + if self.UserMapping[index]["struct"] & OD_IdenticalSubindexes: + self.UserMapping[index]["values"][1]["name"] = name + " %d[(sub)]" + elif not self.UserMapping[index]["struct"] & OD_MultipleSubindexes: + self.UserMapping[index]["values"][0]["name"] = name + if struct != None: + self.UserMapping[index]["struct"] = struct + if size != None: + self.UserMapping[index]["size"] = size + if nbmax != None: + self.UserMapping[index]["nbmax"] = nbmax + if default != None: + self.UserMapping[index]["default"] = default + if values != None: + self.UserMapping[index]["values"] = values + return True + elif 0 <= subIndex < len(self.UserMapping[index]["values"]) and values != None: + self.UserMapping[index]["values"][subIndex].update(values) + return True + return False + + """ + Removes an existing entry in the User Mapping Dictionary. If a subIndex is specified + it will remove this subIndex only if it's the last of the index. If no subIndex + is specified it removes the whole index and subIndexes from the User Mapping Dictionary. + """ + def RemoveMappingEntry(self, index, subIndex = None): + if index in self.UserMapping: + if subIndex == None: + self.UserMapping.pop(index) + return True + elif subIndex == len(self.UserMapping[index]["values"]) - 1: + self.UserMapping[index]["values"].pop(subIndex) + return True + return False + + def RemoveMapVariable(self, index, subIndex): + model = index << 16 + mask = 0xFFFF << 16 + if subIndex: + model += subIndex << 8 + mask = 0xFF << 8 + for i in self.Dictionary.iterkeys(): + if 0x1600 <= i <= 0x17FF or 0x1A00 <= i <= 0x1BFF: + for j,value in enumerate(self.Dictionary[i]): + if (value & mask) == model: + self.Dictionary[i][j] = 0 + + def RemoveLine(self, index, max, incr = 1): + i = index + while i < max and self.IsEntry(i + incr): + self.Dictionary[i] = self.Dictionary[i + incr] + i += incr + self.Dictionary.pop(i) + + def RemoveUserType(self, index): + type = self.GetEntry(index, 1) + for i in self.UserMapping: + for value in self.UserMapping[i]["values"]: + if value["type"] == index: + value["type"] = type + self.RemoveMappingEntry(index) + self.RemoveEntry(index) + + """ + Return a copy of the node + """ + def Copy(self): + return cPickle.loads(cPickle.dumps(self)) + + """ + Return a sorted list of indexes in Object Dictionary + """ + def GetIndexes(self): + listindex = self.Dictionary.keys() + listindex.sort() + return listindex + + """ + Print the Dictionary values + """ + def Print(self): + listindex = self.Dictionary.keys() + listindex.sort() + for index in listindex: + print "%04X : %s"%(index, self.Dictionary[index]) diff -r 000000000000 -r 4472ee7c6c3e objdictgen/nodemanager.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/nodemanager.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1237 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of CanFestival, a library implementing CanOpen Stack. +# +#Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +# +#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 + +from gnosis.xml.pickle import * +from gnosis.xml.pickle.util import setParanoia +setParanoia(0) + +from node import * +import xml_in, gen_cfile + +from types import * +import os, re + +UndoBufferLength = 20 + +type_model = re.compile('([\_A-Z]*)([0-9]*)') +range_model = re.compile('([\_A-Z]*)([0-9]*)\[([\-0-9]*)-([\-0-9]*)\]') +name_model = re.compile('(.*)\[(.*)\]') + +def IsOfType(object, typedef): + return type(object) == typedef + +#------------------------------------------------------------------------------- +# Formating Name of an Entry +#------------------------------------------------------------------------------- + +""" +Format the text given with the index and subindex defined +""" + +def StringFormat(text, idx, sub): + result = name_model.match(text) + if result: + format = result.groups() + return format[0]%eval(format[1]) + else: + return text + +#------------------------------------------------------------------------------- +# Search in a Mapping Dictionary +#------------------------------------------------------------------------------- + +""" +Return the index of the informations in the Object Dictionary in case of identical +indexes +""" +def FindIndex(index, mappingdictionary): + if index in mappingdictionary: + return index + else: + listpluri = [idx for idx in mappingdictionary.keys() if mappingdictionary[idx]["struct"] & OD_IdenticalIndexes] + listpluri.sort() + for idx in listpluri: + nb_max = mappingdictionary[idx]["nbmax"] + incr = mappingdictionary[idx]["incr"] + if idx < index < idx + incr * nb_max and (index - idx)%incr == 0: + return idx + return None + +""" +Return the index of the typename given by searching in mappingdictionary +""" +def FindTypeIndex(typename, mappingdictionary): + testdic = {} + for index, values in mappingdictionary.iteritems(): + if index < 0x1000: + testdic[values["name"]] = index + if typename in testdic: + return testdic[typename] + return None + +""" +Return the name of the type by searching in mappingdictionary +""" +def FindTypeName(typeindex, mappingdictionary): + if typeindex < 0x1000 and typeindex in mappingdictionary: + return mappingdictionary[typeindex]["name"] + return None + +""" +Return the default value of the type by searching in mappingdictionary +""" +def FindTypeDefaultValue(typeindex, mappingdictionary): + if typeindex < 0x1000 and typeindex in mappingdictionary: + return mappingdictionary[typeindex]["default"] + return None + +""" +Return the list of types defined in mappingdictionary +""" +def FindTypeList(mappingdictionary): + list = [] + for index in mappingdictionary.keys(): + if index < 0x1000: + list.append((index, mappingdictionary[index]["name"])) + return list + +""" +Return the name of an entry by searching in mappingdictionary +""" +def FindEntryName(index, mappingdictionary): + base_index = FindIndex(index, mappingdictionary) + if base_index: + infos = mappingdictionary[base_index] + if infos["struct"] & OD_IdenticalIndexes: + return StringFormat(infos["name"], (index - base_index) / infos["incr"] + 1, 0) + else: + return infos["name"] + return None + +""" +Return the informations of one entry by searching in mappingdictionary +""" +def FindEntryInfos(index, mappingdictionary): + base_index = FindIndex(index, mappingdictionary) + if base_index: + copy = mappingdictionary[base_index].copy() + if copy["struct"] & OD_IdenticalIndexes: + copy["name"] = StringFormat(copy["name"], (index - base_index) / copy["incr"] + 1, 0) + copy.pop("values") + return copy + return None + +""" +Return the informations of one subentry of an entry by searching in mappingdictionary +""" +def FindSubentryInfos(index, subIndex, mappingdictionary): + base_index = FindIndex(index, mappingdictionary) + if base_index: + struct = mappingdictionary[base_index]["struct"] + if struct & OD_Subindex: + if struct & OD_IdenticalSubindexes: + if struct & OD_IdenticalIndexes: + incr = mappingdictionary[base_index]["incr"] + else: + incr = 1 + if subIndex == 0: + return mappingdictionary[base_index]["values"][0].copy() + elif 0 < subIndex <= mappingdictionary[base_index]["values"][1]["nbmax"]: + copy = mappingdictionary[base_index]["values"][1].copy() + copy["name"] = StringFormat(copy["name"], (index - base_index) / incr + 1, subIndex) + return copy + elif struct & OD_MultipleSubindexes and 0 <= subIndex < len(mappingdictionary[base_index]["values"]): + return mappingdictionary[base_index]["values"][subIndex].copy() + elif subIndex == 0: + return mappingdictionary[base_index]["values"][0].copy() + return None + +""" +Return the list of variables that can be mapped defined in mappingdictionary +""" +def FindMapVariableList(mappingdictionary, Manager): + list = [] + for index in mappingdictionary.iterkeys(): + if Manager.IsCurrentEntry(index): + for subIndex, values in enumerate(mappingdictionary[index]["values"]): + if mappingdictionary[index]["values"][subIndex]["pdo"]: + infos = Manager.GetEntryInfos(mappingdictionary[index]["values"][subIndex]["type"]) + if mappingdictionary[index]["struct"] & OD_IdenticalSubindexes: + values = Manager.GetCurrentEntry(index) + for i in xrange(len(values)): + list.append((index, i + 1, infos["size"], StringFormat(mappingdictionary[index]["values"][subIndex]["name"],1,i))) + else: + list.append((index, subIndex, infos["size"], mappingdictionary[index]["values"][subIndex]["name"])) + return list + +""" +Return the list of mandatory indexes defined in mappingdictionary +""" +def FindMandatoryIndexes(mappingdictionary): + list = [] + for index in mappingdictionary.iterkeys(): + if index >= 0x1000 and mappingdictionary[index]["need"]: + list.append(index) + return list + + +""" +Class implementing a buffer of changes made on the current editing Object Dictionary +""" + +class UndoBuffer: + + """ + Constructor initialising buffer + """ + def __init__(self, currentstate, issaved = False): + self.Buffer = [] + self.CurrentIndex = -1 + self.MinIndex = -1 + self.MaxIndex = -1 + # if current state is defined + if currentstate: + self.CurrentIndex = 0 + self.MinIndex = 0 + self.MaxIndex = 0 + # Initialising buffer with currentstate at the first place + for i in xrange(UndoBufferLength): + if i == 0: + self.Buffer.append(currentstate) + else: + self.Buffer.append(None) + # Initialising index of state saved + if issaved: + self.LastSave = 0 + else: + self.LastSave = -1 + + """ + Add a new state in buffer + """ + def Buffering(self, currentstate): + self.CurrentIndex = (self.CurrentIndex + 1) % UndoBufferLength + self.Buffer[self.CurrentIndex] = currentstate + # Actualising buffer limits + self.MaxIndex = self.CurrentIndex + if self.MinIndex == self.CurrentIndex: + # If the removed state was the state saved, there is no state saved in the buffer + if self.LastSave == self.MinIndex: + self.LastSave = -1 + self.MinIndex = (self.MinIndex + 1) % UndoBufferLength + self.MinIndex = max(self.MinIndex, 0) + + """ + Return current state of buffer + """ + def Current(self): + return self.Buffer[self.CurrentIndex] + + """ + Change current state to previous in buffer and return new current state + """ + def Previous(self): + if self.CurrentIndex != self.MinIndex: + self.CurrentIndex = (self.CurrentIndex - 1) % UndoBufferLength + return self.Buffer[self.CurrentIndex] + return None + + """ + Change current state to next in buffer and return new current state + """ + def Next(self): + if self.CurrentIndex != self.MaxIndex: + self.CurrentIndex = (self.CurrentIndex + 1) % UndoBufferLength + return self.Buffer[self.CurrentIndex] + return None + + """ + Return True if current state is the first in buffer + """ + def IsFirst(self): + return self.CurrentIndex == self.MinIndex + + """ + Return True if current state is the last in buffer + """ + def IsLast(self): + return self.CurrentIndex == self.MaxIndex + + """ + Note that current state is saved + """ + def CurrentSaved(self): + self.LastSave = self.CurrentIndex + + """ + Return True if current state is saved + """ + def IsCurrentSaved(self): + return self.LastSave == self.CurrentIndex + + + +""" +Class which control the operations made on the node and answer to view requests +""" + +class NodeManager: + + """ + Constructor + """ + def __init__(self): + self.LastNewIndex = 0 + self.FilePaths = [] + self.FileNames = [] + self.NodeIndex = -1 + self.CurrentNode = None + self.UndoBuffers = [] + +#------------------------------------------------------------------------------- +# Type and Map Variable Lists +#------------------------------------------------------------------------------- + + """ + Generate the list of types defined for the current node + """ + def GenerateTypeList(self): + self.TypeList = "" + self.TypeTranslation = {} + list = self.GetTypeList() + sep = "" + for index, name in list: + self.TypeList += "%s%s"%(sep,name) + self.TypeTranslation[name] = index + sep = "," + + """ + Generate the list of variables that can be mapped for the current node + """ + def GenerateMapList(self): + self.MapList = "None" + self.NameTranslation = {"None" : "00000000"} + self.MapTranslation = {"00000000" : "None"} + list = self.GetMapVariableList() + for index, subIndex, size, name in list: + self.MapList += ",%s"%name + map = "%04X%02X%02X"%(index,subIndex,size) + self.NameTranslation[name] = map + self.MapTranslation[map] = name + + """ + Return the list of types defined for the current node + """ + def GetCurrentTypeList(self): + return self.TypeList + + """ + Return the list of variables that can be mapped for the current node + """ + def GetCurrentMapList(self): + return self.MapList + +#------------------------------------------------------------------------------- +# Create Load and Save Functions +#------------------------------------------------------------------------------- + + """ + Create a new node and add a new buffer for storing it + """ + def CreateNewNode(self, name, id, type, profile, filepath, NMT, options): + # Create a new node + node = Node() + # Try to load profile given + result = self.LoadProfile(profile, filepath, node) + if not IsOfType(result, StringType): + # if success, initialising node + self.CurrentNode = node + self.CurrentNode.SetNodeName(name) + self.CurrentNode.SetNodeID(id) + self.CurrentNode.SetNodeType(type) + AddIndexList = self.GetMandatoryIndexes() + if NMT == "NodeGuarding": + AddIndexList.extend([0x100C, 0x100D]) + elif NMT == "Heartbeat": + AddIndexList.append(0x1017) + for option in options: + if option == "DS302": + # Charging DS-302 profile if choosen by user + if os.path.isfile("config/DS-302.prf"): + try: + Mapping = {} + AddMenuEntries = [] + execfile("config/DS-302.prf") + self.CurrentNode.SetDS302Profile(Mapping) + self.CurrentNode.ExtendSpecificMenu(AddMenuEntries) + except: + return "Problem with DS-302! Syntax Error." + else: + return "Couldn't find DS-302 in 'config' folder!" + elif option == "GenSYNC": + AddIndexList.extend([0x1005, 0x1006]) + elif option == "Emergency": + AddIndexList.append(0x1014) + elif option == "SaveConfig": + AddIndexList.extend([0x1010, 0x1011, 0x1020]) + elif option == "StoreEDS": + AddIndexList.extend([0x1021, 0x1022]) + # Add a new buffer + self.AddNodeBuffer() + self.SetCurrentFilePath("") + # Add Mandatory indexes + self.ManageEntriesOfCurrent(AddIndexList, []) + # Regenerate lists + self.GenerateTypeList() + self.GenerateMapList() + return True + else: + return result + + """ + Load a profile in node + """ + def LoadProfile(self, profile, filepath, node): + if profile != "None": + # Try to charge the profile given + try: + execfile(filepath) + node.SetProfileName(profile) + node.SetProfile(Mapping) + node.SetSpecificMenu(AddMenuEntries) + return True + except: + return "Bad OD Profile file!\nSyntax Error." + else: + # Default profile + node.SetProfileName("None") + node.SetProfile({}) + node.SetSpecificMenu([]) + return True + + """ + Open a file and store it in a new buffer + """ + def OpenFileInCurrent(self, filepath): + # Open and load file + file = open(filepath, "r") + node = load(file) + file.close() + self.CurrentNode = node + # Add a new buffer and defining current state + self.AddNodeBuffer(self.CurrentNode.Copy(), True) + self.SetCurrentFilePath(filepath) + # Regenerate lists + self.GenerateTypeList() + self.GenerateMapList() + return True + + """ + Save current node in a file + """ + def SaveCurrentInFile(self, filepath = None): + # if no filepath given, verify if current node has a filepath defined + if not filepath: + filepath = self.GetCurrentFilePath() + if filepath == "": + return False + # Save node in file + file = open(filepath, "w") + dump(self.CurrentNode, file) + file.close() + self.SetCurrentFilePath(filepath) + # Update saved state in buffer + self.UndoBuffers[self.NodeIndex].CurrentSaved() + return True + + """ + Close current state + """ + def CloseCurrent(self, ignore = False): + # Verify if it's not forced that the current node is saved before closing it + if self.UndoBuffers[self.NodeIndex].IsCurrentSaved() or ignore: + self.RemoveNodeBuffer(self.NodeIndex) + return True + return False + + """ + Import a xml file and store it in a new buffer if no node edited + """ + def ImportCurrentFromFile(self, filepath): + # Generate node from definition in a xml file + node = xml_in.GenerateNode(filepath, self) + if node: + self.CurrentNode = node + self.GenerateTypeList() + self.GenerateMapList() + if len(self.UndoBuffers) == 0: + self.AddNodeBuffer() + self.SetCurrentFilePath("") + self.BufferCurrentNode() + return result + + """ + Build the C definition of Object Dictionary for current node + """ + def ExportCurrentToFile(self, filepath): + return gen_cfile.GenerateFile(filepath, self) + +#------------------------------------------------------------------------------- +# Add Entries to Current Functions +#------------------------------------------------------------------------------- + + """ + Add the specified number of subentry for the given entry. Verify that total + number of subentry (except 0) doesn't exceed nbmax defined + """ + def AddSubentriesToCurrent(self, index, number): + # Informations about entry + length = self.CurrentNode.GetEntry(index, 0) + infos = self.GetEntryInfos(index) + subentry_infos = self.GetSubentryInfos(index, 1) + # Get default value for subindex + if "default" in subentry_infos: + default = subentry_infos["default"] + else: + default = self.GetTypeDefaultValue(subentry_infos["type"]) + # First case entry is record + if infos["struct"] & OD_IdenticalSubindexes: + for i in xrange(1, min(number,subentry_infos["nbmax"]-length) + 1): + self.CurrentNode.AddEntry(index, length + i, default) + self.BufferCurrentNode() + # Second case entry is array, only possible for manufacturer specific + elif infos["struct"] & OD_MultipleSubindexes and 0x2000 <= index <= 0x5FFF: + values = {"name" : "Undefined", "type" : 5, "access" : "rw", "pdo" : True} + for i in xrange(1, min(number,0xFE-length) + 1): + self.CurrentNode.AddMappingEntry(index, length + i, values = values.copy()) + self.CurrentNode.AddEntry(index, length + i, 0) + self.BufferCurrentNode() + + """ + Remove the specified number of subentry for the given entry. Verify that total + number of subentry (except 0) isn't less than 1 + """ + def RemoveSubentriesFromCurrent(self, index, number): + # Informations about entry + infos = self.GetEntryInfos(index) + length = self.CurrentNode.GetEntry(index, 0) + # Entry is a record, or is an array of manufacturer specific + if infos["struct"] & OD_IdenticalSubindexes or 0x2000 <= index <= 0x5FFF and infos["struct"] & OD_IdenticalSubindexes: + for i in xrange(min(number, length - 1)): + self.RemoveCurrentVariable(index, length - i) + self.BufferCurrentNode() + + """ + Add a SDO Server to current node + """ + def AddSDOServerToCurrent(self): + # An SDO Server is already defined at index 0x1200 + if self.CurrentNode.IsEntry(0x1200): + indexlist = [self.GetLineFromIndex(0x1201)] + if None not in indexlist: + self.ManageEntriesOfCurrent(indexlist, []) + # Add an SDO Server at index 0x1200 + else: + self.ManageEntriesOfCurrent([0x1200], []) + + """ + Add a SDO Server to current node + """ + def AddSDOClientToCurrent(self): + indexlist = [self.GetLineFromIndex(0x1280)] + if None not in indexlist: + self.ManageEntriesOfCurrent(indexlist, []) + + """ + Add a Transmit PDO to current node + """ + def AddPDOTransmitToCurrent(self): + indexlist = [self.GetLineFromIndex(0x1800),self.GetLineFromIndex(0x1A00)] + if None not in indexlist: + self.ManageEntriesOfCurrent(indexlist, []) + + """ + Add a Receive PDO to current node + """ + def AddPDOReceiveToCurrent(self): + indexlist = [self.GetLineFromIndex(0x1400),self.GetLineFromIndex(0x1600)] + if None not in indexlist: + self.ManageEntriesOfCurrent(indexlist, []) + + """ + Add a list of entries defined in profile for menu item selected to current node + """ + def AddSpecificEntryToCurrent(self, menuitem): + indexlist = [] + for menu, indexes in self.CurrentNode.GetSpecificMenu(): + if menuitem == menu: + for index in indexes: + indexlist.append(self.GetLineFromIndex(index)) + if None not in indexlist: + self.ManageEntriesOfCurrent(indexlist, []) + + """ + Search the first index available for a pluri entry from base_index + """ + def GetLineFromIndex(self, base_index): + found = False + index = base_index + infos = self.GetEntryInfos(base_index) + while index < base_index + infos["incr"]*infos["nbmax"] and not found: + if not self.CurrentNode.IsEntry(index): + found = True + else: + index += infos["incr"] + if found: + return index + return None + + """ + Add entries specified in addinglist and remove entries specified in removinglist + """ + def ManageEntriesOfCurrent(self, addinglist, removinglist): + # Add all the entries in addinglist + for index in addinglist: + infos = self.GetEntryInfos(index) + if infos["struct"] & OD_MultipleSubindexes: + # First case entry is a record + if infos["struct"] & OD_IdenticalSubindexes: + subentry_infos = self.GetSubentryInfos(index, 1) + if "default" in subentry_infos: + default = subentry_infos["default"] + else: + default = self.GetTypeDefaultValue(subentry_infos["type"]) + self.CurrentNode.AddEntry(index, 1, default) + # Second case entry is a record + else: + i = 1 + subentry_infos = self.GetSubentryInfos(index, i) + while subentry_infos: + if "default" in subentry_infos: + default = subentry_infos["default"] + else: + default = self.GetTypeDefaultValue(subentry_infos["type"]) + self.CurrentNode.AddEntry(index, i, default) + i += 1 + subentry_infos = self.GetSubentryInfos(index, i) + # Third case entry is a record + else: + subentry_infos = self.GetSubentryInfos(index, 0) + if "default" in subentry_infos: + default = subentry_infos["default"] + else: + default = self.GetTypeDefaultValue(subentry_infos["type"]) + self.CurrentNode.AddEntry(index, 0, default) + # Remove all the entries in removinglist + for index in removinglist: + self.RemoveCurrentVariable(index) + self.BufferCurrentNode() + + """ + Remove an entry from current node. Analize the index to perform the correct + method + """ + def RemoveCurrentVariable(self, index, subIndex = None): + Mappings = self.CurrentNode.GetMappings() + if index < 0x1000 and subIndex == None: + type = self.CurrentNode.GetEntry(index, 1) + for i in Mappings[-1]: + for value in Mappings[-1][i]["values"]: + if value["type"] == index: + value["type"] = type + self.CurrentNode.RemoveMappingEntry(index) + self.CurrentNode.RemoveEntry(index) + elif index == 0x1200 and subIndex == None: + self.CurrentNode.RemoveEntry(0x1200) + elif 0x1201 <= index <= 0x127F and subIndex == None: + self.CurrentNode.RemoveLine(index, 0x127F) + elif 0x1280 <= index <= 0x12FF and subIndex == None: + self.CurrentNode.RemoveLine(index, 0x12FF) + elif 0x1400 <= index <= 0x15FF or 0x1600 <= index <= 0x17FF and subIndex == None: + if 0x1600 <= index <= 0x17FF and subIndex == None: + index -= 0x200 + self.CurrentNode.RemoveLine(index, 0x15FF) + self.CurrentNode.RemoveLine(index + 0x200, 0x17FF) + elif 0x1800 <= index <= 0x19FF or 0x1A00 <= index <= 0x1BFF and subIndex == None: + if 0x1A00 <= index <= 0x1BFF: + index -= 0x200 + self.CurrentNode.RemoveLine(index, 0x19FF) + self.CurrentNode.RemoveLine(index + 0x200, 0x1BFF) + else: + found = False + for menu,list in self.CurrentNode.GetSpecificMenu(): + for i in list: + iinfos = self.GetEntryInfos(i) + indexes = [i + incr * iinfos["incr"] for incr in xrange(iinfos["nbmax"])] + if index in indexes: + found = True + diff = index - i + for j in list: + jinfos = self.GetEntryInfos(j) + self.CurrentNode.RemoveLine(j + diff, j + jinfos["incr"]*jinfos["nbmax"], jinfos["incr"]) + self.CurrentNode.RemoveMapVariable(index, subIndex) + if not found: + infos = self.GetEntryInfos(index) + if not infos["need"]: + self.CurrentNode.RemoveEntry(index, subIndex) + if index in Mappings[-1]: + self.CurrentNode.RemoveMappingEntry(index, subIndex) + self.GenerateMapList() + + def AddMapVariableToCurrent(self, index, name, struct, number): + if 0x2000 <= index <= 0x5FFF: + if not self.CurrentNode.IsEntry(index): + self.CurrentNode.AddMappingEntry(index, name = name, struct = struct) + if struct == var: + values = {"name" : name, "type" : 5, "access" : "rw", "pdo" : True} + self.CurrentNode.AddMappingEntry(index, 0, values = values) + self.CurrentNode.AddEntry(index, 0, 0) + else: + values = {"name" : "Number of Entries", "type" : 2, "access" : "ro", "pdo" : False} + self.CurrentNode.AddMappingEntry(index, 0, values = values) + if struct == rec: + values = {"name" : name + " %d[(sub)]", "type" : 5, "access" : "rw", "pdo" : True, "nbmax" : 0xFE} + self.CurrentNode.AddMappingEntry(index, 1, values = values) + for i in xrange(number): + self.CurrentNode.AddEntry(index, i + 1, 0) + else: + for i in xrange(number): + values = {"name" : "Undefined", "type" : 5, "access" : "rw", "pdo" : True} + self.CurrentNode.AddMappingEntry(index, i + 1, values = values) + self.CurrentNode.AddEntry(index, i + 1, 0) + self.GenerateMapList() + self.BufferCurrentNode() + return None + else: + return "Index 0x%04X already defined!"%index + else: + return "Index 0x%04X isn't a valid index for Map Variable!"%index + + def AddUserTypeToCurrent(self, type, min, max, length): + index = 0xA0 + while index < 0x100 and self.CurrentNode.IsEntry(index): + index += 1 + if index < 0x100: + customisabletypes = self.GetCustomisableTypes() + name, valuetype = customisabletypes[type] + size = self.GetEntryInfos(type)["size"] + default = self.GetTypeDefaultValue(type) + if valuetype == 0: + self.CurrentNode.AddMappingEntry(index, name = "%s[%d-%d]"%(name, min, max), struct = 3, size = size, default = default) + self.CurrentNode.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddEntry(index, 1, type) + self.CurrentNode.AddEntry(index, 2, min) + self.CurrentNode.AddEntry(index, 3, max) + elif valuetype == 1: + self.CurrentNode.AddMappingEntry(index, name = "%s%d"%(name, length), struct = 3, size = length * size, default = default) + self.CurrentNode.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddEntry(index, 1, type) + self.CurrentNode.AddEntry(index, 2, length) + self.GenerateTypeList() + self.BufferCurrentNode() + return None + else: + return "Too many User Types have already been defined!" + +#------------------------------------------------------------------------------- +# Modify Entry and Mapping Functions +#------------------------------------------------------------------------------- + + def SetCurrentEntryCallbacks(self, index, value): + if self.CurrentNode and self.CurrentNode.IsEntry(index): + entry_infos = self.GetEntryInfos(index) + if "callback" not in entry_infos: + self.CurrentNode.SetParamsEntry(index, None, callback = value) + self.BufferCurrentNode() + + def SetCurrentEntry(self, index, subIndex, value, name, editor): + if self.CurrentNode and self.CurrentNode.IsEntry(index): + if name == "value": + if editor == "map": + value = eval("0x%s"%self.NameTranslation[value]) + self.CurrentNode.SetEntry(index, subIndex, value) + elif editor == "bool": + value = value == "True" + self.CurrentNode.SetEntry(index, subIndex, value) + else: + subentry_infos = self.GetSubentryInfos(index, subIndex) + dic = {} + for typeindex, typevalue in CustomisableTypes: + dic[typeindex] = typevalue + if dic[subentry_infos["type"]] == 0: + try: + value = eval(value, {}) + self.CurrentNode.SetEntry(index, subIndex, value) + except: + pass + else: + self.CurrentNode.SetEntry(index, subIndex, value) + elif name in ["comment", "save"]: + if editor == "option": + value = value == "Yes" + if name == "save": + self.CurrentNode.SetParamsEntry(index, subIndex, save = value) + elif name == "comment": + self.CurrentNode.SetParamsEntry(index, subIndex, comment = value) + else: + if editor == "type": + value = self.TypeTranslation[value] + elif editor == "access": + dic = {} + for abbrev,access in AccessType.iteritems(): + dic[access] = abbrev + value = dic[value] + self.CurrentNode.SetMappingEntry(index, subIndex, values = {name : value}) + if name == "name": + self.GenerateMapList() + self.BufferCurrentNode() + + def SetCurrentEntryName(self, index, name): + self.CurrentNode.SetMappingEntry(index, name=name) + self.BufferCurrentNode() + + def SetCurrentUserType(self, index, type, min, max, length): + customisabletypes = self.GetCustomisableTypes() + values, valuetype = self.GetCustomisedTypeValues(index) + name, new_valuetype = customisabletypes[type] + size = self.GetEntryInfos(type)["size"] + default = self.GetTypeDefaultValue(type) + if new_valuetype == 0: + self.CurrentNode.SetMappingEntry(index, name = "%s[%d-%d]"%(name, min, max), struct = 3, size = size, default = default) + if valuetype == 1: + self.CurrentNode.SetMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False}) + self.CurrentNode.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False}) + self.CurrentNode.SetEntry(index, 1, type) + self.CurrentNode.SetEntry(index, 2, min) + if valuetype == 1: + self.CurrentNode.AddEntry(index, 3, max) + else: + self.CurrentNode.SetEntry(index, 3, max) + elif new_valuetype == 1: + self.CurrentNode.SetMappingEntry(index, name = "%s%d"%(name, length), struct = 3, size = size, default = default) + if valuetype == 0: + self.CurrentNode.SetMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False}) + self.CurrentNode.RemoveMappingEntry(index, 3) + self.CurrentNode.SetEntry(index, 1, type) + self.CurrentNode.SetEntry(index, 2, length) + if valuetype == 0: + self.CurrentNode.RemoveEntry(index, 3) + self.BufferCurrentNode() + +#------------------------------------------------------------------------------- +# Current Buffering Management Functions +#------------------------------------------------------------------------------- + + def BufferCurrentNode(self): + self.UndoBuffers[self.NodeIndex].Buffering(self.CurrentNode.Copy()) + + def CurrentIsSaved(self): + return self.UndoBuffers[self.NodeIndex].IsCurrentSaved() + + def OneFileHasChanged(self): + result = False + for buffer in self.UndoBuffers: + result |= not buffer.IsCurrentSaved() + return result + + def GetBufferNumber(self): + return len(self.UndoBuffers) + + def LoadCurrentPrevious(self): + self.CurrentNode = self.UndoBuffers[self.NodeIndex].Previous().Copy() + + def LoadCurrentNext(self): + self.CurrentNode = self.UndoBuffers[self.NodeIndex].Next().Copy() + + def AddNodeBuffer(self, currentstate = None, issaved = False): + self.NodeIndex = len(self.UndoBuffers) + self.UndoBuffers.append(UndoBuffer(currentstate, issaved)) + self.FilePaths.append("") + self.FileNames.append("") + + def ChangeCurrentNode(self, index): + if index < len(self.UndoBuffers): + self.NodeIndex = index + self.CurrentNode = self.UndoBuffers[self.NodeIndex].Current().Copy() + self.GenerateTypeList() + self.GenerateMapList() + + def RemoveNodeBuffer(self, index): + self.UndoBuffers.pop(index) + self.FilePaths.pop(index) + self.FileNames.pop(index) + self.NodeIndex = min(self.NodeIndex, len(self.UndoBuffers) - 1) + if len(self.UndoBuffers) > 0: + self.CurrentNode = self.UndoBuffers[self.NodeIndex].Current().Copy() + self.GenerateTypeList() + self.GenerateMapList() + else: + self.CurrentNode = None + + def GetCurrentNodeIndex(self): + return self.NodeIndex + + def GetCurrentFilename(self): + return self.GetFilename(self.NodeIndex) + + def GetAllFilenames(self): + filenames = [] + for i in xrange(len(self.UndoBuffers)): + filenames.append(self.GetFilename(i)) + return filenames + + def GetFilename(self, index): + if self.UndoBuffers[index].IsCurrentSaved(): + return self.FileNames[index] + else: + return "~%s~"%self.FileNames[index] + + def SetCurrentFilePath(self, filepath): + self.FilePaths[self.NodeIndex] = filepath + if filepath == "": + self.LastNewIndex += 1 + self.FileNames[self.NodeIndex] = "Unnamed%d"%self.LastNewIndex + else: + self.FileNames[self.NodeIndex] = os.path.splitext(os.path.basename(filepath))[0] + + def GetCurrentFilePath(self): + if len(self.FilePaths) > 0: + return self.FilePaths[self.NodeIndex] + else: + return "" + + def GetCurrentBufferState(self): + first = self.UndoBuffers[self.NodeIndex].IsFirst() + last = self.UndoBuffers[self.NodeIndex].IsLast() + return not first, not last + +#------------------------------------------------------------------------------- +# Profiles Management Functions +#------------------------------------------------------------------------------- + + def GetCurrentCommunicationLists(self): + list = [] + for index in MappingDictionary.iterkeys(): + if 0x1000 <= index < 0x1200: + list.append(index) + return self.GetProfileLists(MappingDictionary, list) + + def GetCurrentDS302Lists(self): + return self.GetSpecificProfileLists(self.CurrentNode.GetDS302Profile()) + + def GetCurrentProfileLists(self): + return self.GetSpecificProfileLists(self.CurrentNode.GetProfile()) + + def GetSpecificProfileLists(self, mappingdictionary): + validlist = [] + exclusionlist = [] + for name, list in self.CurrentNode.GetSpecificMenu(): + exclusionlist.extend(list) + for index in mappingdictionary.iterkeys(): + if index not in exclusionlist: + validlist.append(index) + return self.GetProfileLists(mappingdictionary, validlist) + + def GetProfileLists(self, mappingdictionary, list): + dictionary = {} + current = [] + for index in list: + dictionary[index] = (mappingdictionary[index]["name"], mappingdictionary[index]["need"]) + if self.CurrentNode.IsEntry(index): + current.append(index) + return dictionary, current + + def CurrentDS302Defined(self): + if self.CurrentNode: + return len(self.CurrentNode.GetDS302Profile()) > 0 + return False + +#------------------------------------------------------------------------------- +# Node State and Values Functions +#------------------------------------------------------------------------------- + + def GetCurrentNodeInfos(self): + name = self.CurrentNode.GetNodeName() + id = self.CurrentNode.GetNodeID() + type = self.CurrentNode.GetNodeType() + return name, id, type + + def SetCurrentNodeInfos(self, name, id, type): + self.CurrentNode.SetNodeName(name) + self.CurrentNode.SetNodeID(id) + self.CurrentNode.SetNodeType(type) + self.BufferCurrentNode() + + def GetCurrentProfileName(self): + if self.CurrentNode: + return self.CurrentNode.GetProfileName() + return "" + + def IsCurrentEntry(self, index): + if self.CurrentNode: + return self.CurrentNode.IsEntry(index) + return False + + def GetCurrentEntry(self, index, subIndex = None): + if self.CurrentNode: + return self.CurrentNode.GetEntry(index, subIndex) + return None + + def GetCurrentParamsEntry(self, index, subIndex = None): + if self.CurrentNode: + return self.CurrentNode.GetParamsEntry(index, subIndex) + return None + + def GetCurrentValidIndexes(self, min, max): + validindexes = [] + for index in self.CurrentNode.GetIndexes(): + if min <= index <= max: + validindexes.append((self.GetEntryName(index), index)) + return validindexes + + def GetCurrentValidChoices(self, min, max): + validchoices = [] + exclusionlist = [] + for menu, indexes in self.CurrentNode.GetSpecificMenu(): + exclusionlist.extend(indexes) + good = True + for index in indexes: + good &= min <= index <= max + if good: + validchoices.append((menu, None)) + list = [index for index in MappingDictionary.keys() if index >= 0x1000] + profiles = self.CurrentNode.GetMappings(False) + for profile in profiles: + list.extend(profile.keys()) + list.sort() + for index in list: + if min <= index <= max and not self.CurrentNode.IsEntry(index) and index not in exclusionlist: + validchoices.append((self.GetEntryName(index), index)) + return validchoices + + def HasCurrentEntryCallbacks(self, index): + if self.CurrentNode and self.CurrentNode.IsEntry(index): + entry_infos = self.GetEntryInfos(index) + if "callback" in entry_infos: + return entry_infos["callback"] + return self.CurrentNode.HasEntryCallbacks(index) + return False + + def GetCurrentEntryValues(self, index): + if self.CurrentNode and self.CurrentNode.IsEntry(index): + entry_infos = self.GetEntryInfos(index) + data = [] + editors = [] + values = self.CurrentNode.GetEntry(index) + params = self.CurrentNode.GetParamsEntry(index) + if type(values) == ListType: + for i, value in enumerate(values): + data.append({"value" : value}) + data[-1].update(params[i]) + else: + data.append({"value" : values}) + data[-1].update(params) + for i, dic in enumerate(data): + infos = self.GetSubentryInfos(index, i) + dic["subindex"] = "0x%02X"%i + dic["name"] = infos["name"] + dic["type"] = self.GetTypeName(infos["type"]) + dic["access"] = AccessType[infos["access"]] + dic["save"] = OptionType[dic["save"]] + editor = {"subindex" : None, "save" : "option", "callback" : "option", "comment" : "string"} + if type(values) == ListType and i == 0: + editor["name"] = None + editor["type"] = None + editor["access"] = None + editor["value"] = None + else: + if infos["user_defined"]: + if entry_infos["struct"] & OD_IdenticalSubindexes: + editor["name"] = None + if i > 1: + editor["type"] = None + editor["access"] = None + else: + editor["type"] = "type" + editor["access"] = "access" + else: + if entry_infos["struct"] & OD_MultipleSubindexes: + editor["name"] = "string" + else: + editor["name"] = None + editor["type"] = "type" + editor["access"] = "access" + else: + editor["name"] = None + editor["type"] = None + editor["access"] = None + if index < 0x260: + editor["value"] = None + if i == 1: + dic["value"] = self.GetTypeName(dic["value"]) + elif 0x1600 <= index <= 0x17FF or 0x1A00 <= index <= 0x1C00: + editor["value"] = "map" + dic["value"] = self.MapTranslation["%08X"%dic["value"]] + else: + if dic["type"].startswith("VISIBLE_STRING"): + editor["value"] = "string" + elif dic["type"] == "BOOLEAN": + editor["value"] = "bool" + dic["value"] = BoolType[dic["value"]] + result = type_model.match(dic["type"]) + if result: + values = result.groups() + if values[0] == "INTEGER": + format = "0x%0" + str(int(values[1])/4) + "X" + dic["value"] = format%dic["value"] + editor["value"] = "string" + elif values[0] == "UNSIGNED": + editor["value"] = "number" + elif values[0] == "REAL": + editor["value"] = "float" + elif values[0] == "VISIBLE_STRING": + editor["length"] = values[0] + result = range_model.match(dic["type"]) + if result: + values = result.groups() + if values[0] in ("UNSIGNED", "REAL"): + editor["min"] = values[2] + editor["max"] = values[3] + editors.append(editor) + return data, editors + else: + return None + +#------------------------------------------------------------------------------- +# Node Informations Functions +#------------------------------------------------------------------------------- + + def GetCustomisedTypeValues(self, index): + values = self.CurrentNode.GetEntry(index) + customisabletypes = self.GetCustomisableTypes() + return values, customisabletypes[values[1]][1] + + def GetEntryName(self, index, node = True): + result = FindEntryName(index, MappingDictionary) + if result == None and node: + NodeMappings = self.CurrentNode.GetMappings() + i = 0 + while not result and i < len(NodeMappings): + result = FindEntryName(index, NodeMappings[i]) + i += 1 + return result + + def GetEntryInfos(self, index, node = True): + result = FindEntryInfos(index, MappingDictionary) + if result == None and node: + NodeMappings = self.CurrentNode.GetMappings() + i = 0 + while not result and i < len(NodeMappings): + result = FindEntryInfos(index, NodeMappings[i]) + i += 1 + return result + + def GetSubentryInfos(self, index, subIndex, node = True): + result = FindSubentryInfos(index, subIndex, MappingDictionary) + if result == None and node: + NodeMappings = self.CurrentNode.GetMappings() + i = 0 + while not result and i < len(NodeMappings): + result = FindSubentryInfos(index, subIndex, NodeMappings[i]) + if result: + result["user_defined"] = i == len(NodeMappings) - 1 and index >= 0x1000 + i += 1 + else : + result["user_defined"] = False + return result + + def GetTypeIndex(self, typename, node = True): + result = FindTypeIndex(typename, MappingDictionary) + if result == None and node: + NodeMappings = self.CurrentNode.GetMappings() + i = 0 + while not result and i < len(NodeMappings): + result = FindTypeIndex(typename, NodeMappings[i]) + i += 1 + return result + + def GetTypeName(self, typeindex, node = True): + result = FindTypeName(typeindex, MappingDictionary) + if result == None and node: + NodeMappings = self.CurrentNode.GetMappings() + i = 0 + while not result and i < len(NodeMappings): + result = FindTypeName(typeindex, NodeMappings[i]) + i += 1 + return result + + def GetTypeDefaultValue(self, typeindex, node = True): + result = FindTypeDefaultValue(typeindex, MappingDictionary) + if result == None and node: + NodeMappings = self.CurrentNode.GetMappings() + i = 0 + while not result and i < len(NodeMappings): + result = FindTypeDefaultValue(typeindex, NodeMappings[i]) + i += 1 + return result + + def GetTypeList(self, node = True): + list = FindTypeList(MappingDictionary) + if node: + for NodeMapping in self.CurrentNode.GetMappings(): + list.extend(FindTypeList(NodeMapping)) + list.sort() + return list + + def GetMapVariableList(self): + list = FindMapVariableList(MappingDictionary, self) + for NodeMapping in self.CurrentNode.GetMappings(): + list.extend(FindMapVariableList(NodeMapping, self)) + list.sort() + return list + + def GetMandatoryIndexes(self, node = True): + list = FindMandatoryIndexes(MappingDictionary) + if node: + for NodeMapping in self.CurrentNode.GetMappings(): + list.extend(FindMandatoryIndexes(NodeMapping)) + return list + + def GetCustomisableTypes(self): + dic = {} + for index, valuetype in CustomisableTypes: + name = self.GetTypeName(index) + dic[index] = [name, valuetype] + return dic + + def GetCurrentSpecificMenu(self): + if self.CurrentNode: + return self.CurrentNode.GetSpecificMenu() + return [] + + \ No newline at end of file diff -r 000000000000 -r 4472ee7c6c3e objdictgen/objdictedit.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/objdictedit.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,2327 @@ +#Boa:Frame:objdictedit +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of CanFestival, a library implementing CanOpen Stack. +# +#Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +# +#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 + +from wxPython.wx import * +from wxPython.html import * +from wxPython.grid import * +import wx +from wx.lib.anchors import LayoutAnchors +import wx.grid + +from types import * +import os, re, platform, sys, time, traceback, getopt + +__version__ = "$Revision$" + +from nodemanager import * +from node import OD_Subindex,OD_MultipleSubindexes,OD_IdenticalSubindexes,OD_IdenticalIndexes +from doc_index.DS301_index import * + +wxEVT_HTML_URL_CLICK = wxNewId() + +def EVT_HTML_URL_CLICK(win, func): + win.Connect(-1, -1, wxEVT_HTML_URL_CLICK, func) + +class wxHtmlWindowUrlClick(wxPyEvent): + def __init__(self, linkinfo): + wxPyEvent.__init__(self) + self.SetEventType(wxEVT_HTML_URL_CLICK) + self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget()) + +class wxUrlClickHtmlWindow(wxHtmlWindow): + """ HTML window that generates and OnLinkClicked event. + + Use this to avoid having to override HTMLWindow + """ + def OnLinkClicked(self, linkinfo): + wxPostEvent(self, wxHtmlWindowUrlClick(linkinfo)) + +def create(parent): + return objdictedit(parent) + +def usage(): + print "\nUsage of objectdict.py :" + print "\n %s [Filepath, ...]\n"%sys.argv[0] + +try: + opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) +except getopt.GetoptError: + # print help information and exit: + usage() + sys.exit(2) + +for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + +filesOpen = args + +ColSizes = [75, 250, 150, 125, 100, 60, 250] +ColAlignements = [wxALIGN_CENTER, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_RIGHT, wxALIGN_CENTER, wxALIGN_CENTER, wxALIGN_LEFT] +AccessList = "Read Only,Write Only,Read/Write" +BoolList = "True,False" +OptionList = "Yes,No" + +DictionaryOrganisation = [ + {"minIndex" : 0x0001, "maxIndex" : 0x0FFF, "name" : "Data Type Definitions"}, + {"minIndex" : 0x1000, "maxIndex" : 0x1029, "name" : "Communication Parameters"}, + {"minIndex" : 0x1200, "maxIndex" : 0x12FF, "name" : "SDO Parameters"}, + {"minIndex" : 0x1400, "maxIndex" : 0x15FF, "name" : "Receive PDO Parameters"}, + {"minIndex" : 0x1600, "maxIndex" : 0x17FF, "name" : "Receive PDO Mapping"}, + {"minIndex" : 0x1800, "maxIndex" : 0x19FF, "name" : "Transmit PDO Parameters"}, + {"minIndex" : 0x1A00, "maxIndex" : 0x1BFF, "name" : "Transmit PDO Mapping"}, + {"minIndex" : 0x1C00, "maxIndex" : 0x1FFF, "name" : "Other Communication Parameters"}, + {"minIndex" : 0x2000, "maxIndex" : 0x5FFF, "name" : "Manufacturer Specific"}, + {"minIndex" : 0x6000, "maxIndex" : 0x9FFF, "name" : "Standardized Device Profile"}, + {"minIndex" : 0xA000, "maxIndex" : 0xBFFF, "name" : "Standardized Interface Profile"}] + +class SubindexTable(wxPyGridTableBase): + + """ + A custom wxGrid Table using user supplied data + """ + def __init__(self, parent, data, editors, colnames): + # The base class must be initialized *first* + wxPyGridTableBase.__init__(self) + self.data = data + self.editors = editors + self.CurrentIndex = 0 + self.colnames = colnames + self.Parent = parent + # XXX + # we need to store the row length and collength to + # see if the table has changed size + self._rows = self.GetNumberRows() + self._cols = self.GetNumberCols() + + def GetNumberCols(self): + return len(self.colnames) + + def GetNumberRows(self): + return len(self.data) + + def GetColLabelValue(self, col): + if col < len(self.colnames): + return self.colnames[col] + + def GetRowLabelValues(self, row): + return row + + def GetValue(self, row, col): + if row < self.GetNumberRows(): + name = str(self.data[row].get(self.GetColLabelValue(col), "")) + return name + + def GetEditor(self, row, col): + if row < self.GetNumberRows(): + return self.editors[row].get(self.GetColLabelValue(col), "") + + def GetValueByName(self, row, colname): + return self.data[row].get(colname) + + def SetValue(self, row, col, value): + if col < len(self.colnames): + self.data[row][self.GetColLabelValue(col)] = value + + def ResetView(self, grid): + """ + (wxGrid) -> Reset the grid view. Call this to + update the grid if rows and columns have been added or deleted + """ + grid.BeginBatch() + for current, new, delmsg, addmsg in [ + (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED), + (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED), + ]: + if new < current: + msg = wxGridTableMessage(self,delmsg,new,current-new) + grid.ProcessTableMessage(msg) + elif new > current: + msg = wxGridTableMessage(self,addmsg,new-current) + grid.ProcessTableMessage(msg) + self.UpdateValues(grid) + grid.EndBatch() + + self._rows = self.GetNumberRows() + self._cols = self.GetNumberCols() + # update the column rendering scheme + self._updateColAttrs(grid) + + # update the scrollbars and the displayed part of the grid + grid.AdjustScrollbars() + grid.ForceRefresh() + + + def UpdateValues(self, grid): + """Update all displayed values""" + # This sends an event to the grid table to update all of the values + msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES) + grid.ProcessTableMessage(msg) + + def _updateColAttrs(self, grid): + """ + wxGrid -> update the column attributes to add the + appropriate renderer given the column name. + + Otherwise default to the default renderer. + """ + + for col in range(self.GetNumberCols()): + attr = wxGridCellAttr() + attr.SetAlignment(ColAlignements[col], wxALIGN_CENTRE) + grid.SetColAttr(col, attr) + grid.SetColSize(col, ColSizes[col]) + + typelist = None + accesslist = None + for row in range(self.GetNumberRows()): + editors = self.editors[row] + for col in range(self.GetNumberCols()): + editor = None + renderer = None + + colname = self.GetColLabelValue(col) + editortype = editors[colname] + if editortype: + grid.SetReadOnly(row, col, False) + if editortype == "string": + editor = wxGridCellTextEditor() + renderer = wxGridCellStringRenderer() + if colname == "value" and "length" in editors: + editor.SetParameters(editors["length"]) + elif editortype == "number": + editor = wxGridCellNumberEditor() + renderer = wxGridCellNumberRenderer() + if colname == "value" and "min" in editors and "max" in editors: + editor.SetParameters("%s,%s"%(editors["min"],editors["max"])) + elif editortype == "real": + editor = wxGridCellFloatEditor() + renderer = wxGridCellFloatRenderer() + if colname == "value" and "min" in editors and "max" in editors: + editor.SetParameters("%s,%s"%(editors["min"],editors["max"])) + elif editortype == "bool": + editor = wxGridCellChoiceEditor() + editor.SetParameters(BoolList) + elif editortype == "access": + editor = wxGridCellChoiceEditor() + editor.SetParameters(AccessList) + elif editortype == "option": + editor = wxGridCellChoiceEditor() + editor.SetParameters(OptionList) + elif editortype == "type": + editor = wxGridCellChoiceEditor() + editor.SetParameters(self.Parent.Manager.GetCurrentTypeList()) + elif editortype == "map": + editor = wxGridCellChoiceEditor() + editor.SetParameters(self.Parent.Manager.GetCurrentMapList()) + else: + grid.SetReadOnly(row, col, True) + + grid.SetCellEditor(row, col, editor) + grid.SetCellRenderer(row, col, renderer) + + grid.SetCellBackgroundColour(row, col, wxWHITE) + + def SetData(self, data): + self.data = data + + def SetEditors(self, editors): + self.editors = editors + + def GetCurrentIndex(self): + return self.CurrentIndex + + def SetCurrentIndex(self, index): + self.CurrentIndex = index + + def AppendRow(self, row_content): + self.data.append(row_content) + + def Empty(self): + self.data = [] + self.editors = [] + +[wxID_EDITINGPANEL, wxID_EDITINGPANELADDBUTTON, wxID_EDITINGPANELINDEXCHOICE, + wxID_EDITINGPANELINDEXLIST, wxID_EDITINGPANELINDEXLISTPANEL, wxID_EDITINGPANELPARTLIST, + wxID_EDITINGPANELSECONDSPLITTER, wxID_EDITINGPANELSUBINDEXGRID, + wxID_EDITINGPANELSUBINDEXGRIDPANEL, wxID_EDITINGPANELCALLBACKCHECK, +] = [wx.NewId() for _init_ctrls in range(10)] + +[wxID_EDITINGPANELINDEXLISTMENUITEMS0, wxID_EDITINGPANELINDEXLISTMENUITEMS1, + wxID_EDITINGPANELINDEXLISTMENUITEMS2, +] = [wx.NewId() for _init_coll_IndexListMenu_Items in range(3)] + +[wxID_EDITINGPANELMENU1ITEMS0, wxID_EDITINGPANELMENU1ITEMS1, +] = [wx.NewId() for _init_coll_SubindexGridMenu_Items in range(2)] + +class EditingPanel(wx.SplitterWindow): + def _init_coll_AddToListSizer_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.AddButton, 0, border=0, flag=0) + parent.AddWindow(self.IndexChoice, 0, border=0, flag=wxGROW) + + def _init_coll_SubindexGridSizer_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.CallbackCheck, 0, border=0, flag=0) + parent.AddWindow(self.SubindexGrid, 0, border=0, flag=wxGROW) + + def _init_coll_IndexListSizer_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.IndexList, 0, border=0, flag=wxGROW) + parent.AddSizer(self.AddToListSizer, 0, border=0, flag=wxGROW) + + def _init_coll_AddToListSizer_Growables(self, parent): + # generated method, don't edit + + parent.AddGrowableCol(1) + + def _init_coll_SubindexGridSizer_Growables(self, parent): + # generated method, don't edit + + parent.AddGrowableCol(0) + parent.AddGrowableRow(1) + + def _init_coll_IndexListSizer_Growables(self, parent): + # generated method, don't edit + + parent.AddGrowableCol(0) + parent.AddGrowableRow(0) + + def _init_coll_SubindexGridMenu_Items(self, parent): + # generated method, don't edit + + parent.Append(help='', id=wxID_EDITINGPANELMENU1ITEMS0, + kind=wx.ITEM_NORMAL, text='Add') + parent.Append(help='', id=wxID_EDITINGPANELMENU1ITEMS1, + kind=wx.ITEM_NORMAL, text='Delete') + self.Bind(wx.EVT_MENU, self.OnAddSubindexMenu, + id=wxID_EDITINGPANELMENU1ITEMS0) + self.Bind(wx.EVT_MENU, self.OnDeleteSubindexMenu, + id=wxID_EDITINGPANELMENU1ITEMS1) + + def _init_coll_IndexListMenu_Items(self, parent): + # generated method, don't edit + + parent.Append(help='', id=wxID_EDITINGPANELINDEXLISTMENUITEMS0, + kind=wx.ITEM_NORMAL, text='Rename') + parent.Append(help='', id=wxID_EDITINGPANELINDEXLISTMENUITEMS2, + kind=wx.ITEM_NORMAL, text='Modify') + parent.Append(help='', id=wxID_EDITINGPANELINDEXLISTMENUITEMS1, + kind=wx.ITEM_NORMAL, text='Delete') + self.Bind(wx.EVT_MENU, self.OnRenameIndexMenu, + id=wxID_EDITINGPANELINDEXLISTMENUITEMS0) + self.Bind(wx.EVT_MENU, self.OnDeleteIndexMenu, + id=wxID_EDITINGPANELINDEXLISTMENUITEMS1) + self.Bind(wx.EVT_MENU, self.OnModifyIndexMenu, + id=wxID_EDITINGPANELINDEXLISTMENUITEMS2) + + def _init_utils(self): + # generated method, don't edit + self.IndexListMenu = wx.Menu(title='') + + self.SubindexGridMenu = wx.Menu(title='') + + self._init_coll_IndexListMenu_Items(self.IndexListMenu) + self._init_coll_SubindexGridMenu_Items(self.SubindexGridMenu) + + def _init_sizers(self): + # generated method, don't edit + self.IndexListSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self.SubindexGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self.AddToListSizer = wx.FlexGridSizer(cols=2, hgap=0, rows=1, vgap=0) + + self._init_coll_IndexListSizer_Growables(self.IndexListSizer) + self._init_coll_IndexListSizer_Items(self.IndexListSizer) + self._init_coll_SubindexGridSizer_Growables(self.SubindexGridSizer) + self._init_coll_SubindexGridSizer_Items(self.SubindexGridSizer) + self._init_coll_AddToListSizer_Growables(self.AddToListSizer) + self._init_coll_AddToListSizer_Items(self.AddToListSizer) + + self.SubindexGridPanel.SetSizer(self.SubindexGridSizer) + self.IndexListPanel.SetSizer(self.IndexListSizer) + + def _init_ctrls(self, prnt): + wx.SplitterWindow.__init__(self, id=wxID_EDITINGPANEL, + name='MainSplitter', parent=prnt, point=wx.Point(0, 0), + size=wx.Size(-1, -1), style=wx.SP_3D) + self._init_utils() + self.SetNeedUpdating(True) + self.SetMinimumPaneSize(1) + + self.PartList = wx.ListBox(choices=[], id=wxID_EDITINGPANELPARTLIST, + name='PartList', parent=self, pos=wx.Point(0, 0), + size=wx.Size(-1, -1), style=0) + self.PartList.Bind(wx.EVT_LISTBOX, self.OnPartListBoxClick, + id=wxID_EDITINGPANELPARTLIST) + + self.SecondSplitter = wx.SplitterWindow(id=wxID_EDITINGPANELSECONDSPLITTER, + name='SecondSplitter', parent=self, point=wx.Point(0, + 0), size=wx.Size(-1, -1), style=wx.SP_3D) + self.SecondSplitter.SetMinimumPaneSize(1) + self.SplitHorizontally(self.PartList, self.SecondSplitter, + 110) + + self.SubindexGridPanel = wx.Panel(id=wxID_EDITINGPANELSUBINDEXGRIDPANEL, + name='SubindexGridPanel', parent=self.SecondSplitter, pos=wx.Point(0, + 0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) + + self.IndexListPanel = wx.Panel(id=wxID_EDITINGPANELINDEXLISTPANEL, + name='IndexListPanel', parent=self.SecondSplitter, pos=wx.Point(0, + 0), size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL) + self.SecondSplitter.SplitVertically(self.IndexListPanel, + self.SubindexGridPanel, 280) + + self.SubindexGrid = wx.grid.Grid(id=wxID_EDITINGPANELSUBINDEXGRID, + name='SubindexGrid', parent=self.SubindexGridPanel, pos=wx.Point(0, + 0), size=wx.Size(-1, -1), style=0) + self.SubindexGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False, + 'Sans')) + self.SubindexGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL, + False, 'Sans')) + self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, + self.OnSubindexGridCellChange) + self.SubindexGrid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, + self.OnSubindexGridRightClick) + self.SubindexGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, + self.OnSubindexGridSelectCell) + + self.CallbackCheck = wx.CheckBox(id=wxID_EDITINGPANELCALLBACKCHECK, + label='Have Callbacks', name='CallbackCheck', + parent=self.SubindexGridPanel, pos=wx.Point(0, 0), size=wx.Size(152, + 24), style=0) + self.CallbackCheck.Bind(wx.EVT_CHECKBOX, self.OnCallbackCheck, + id=wxID_EDITINGPANELCALLBACKCHECK) + + self.IndexList = wx.ListBox(choices=[], id=wxID_EDITINGPANELINDEXLIST, + name='IndexList', parent=self.IndexListPanel, pos=wx.Point(0, 0), + size=wx.Size(-1, -1), style=0) + self.IndexList.Bind(wx.EVT_LISTBOX, self.OnIndexListClick, + id=wxID_EDITINGPANELINDEXLIST) + self.IndexList.Bind(wx.EVT_RIGHT_UP, self.OnIndexListRightUp) + + self.AddButton = wx.Button(id=wxID_EDITINGPANELADDBUTTON, label='Add', + name='AddButton', parent=self.IndexListPanel, pos=wx.Point(0, 0), + size=wx.Size(50, 30), style=0) + self.AddButton.Bind(wx.EVT_BUTTON, self.OnAddButtonClick, + id=wxID_EDITINGPANELADDBUTTON) + + self.IndexChoice = wx.Choice(choices=[], id=wxID_EDITINGPANELINDEXCHOICE, + name='IndexChoice', parent=self.IndexListPanel, pos=wx.Point(50, + 0), size=wx.Size(-1, 30), style=0) + + self._init_sizers() + + def __init__(self, parent, manager): + self._init_ctrls(parent.GetNoteBook()) + self.Parent = parent + self.Manager = manager + self.ListIndex = [] + self.ChoiceIndex = [] + self.FirstCall = False + + for values in DictionaryOrganisation: + text = "\t0x%04X-0x%04X\t\t%s"%(values["minIndex"],values["maxIndex"],values["name"]) + self.PartList.Append(text) + self.Table = SubindexTable(self, [], [], ["subindex", "name", "type", "value", "access", "save", "comment"]) + self.SubindexGrid.SetTable(self.Table) + self.SubindexGrid.SetRowLabelSize(0) + self.CallbackCheck.Disable() + self.Table.ResetView(self.SubindexGrid) + + def GetSelection(self): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + subIndex = self.SubindexGrid.GetGridCursorRow() + return index, subIndex + return None + + def OnAddButtonClick(self, event): + selected = self.IndexChoice.GetStringSelection() + if selected != "": + if selected == "User Type": + self.Parent.AddUserType() + elif selected == "SDO Server": + self.Manager.AddSDOServerToCurrent() + elif selected == "SDO Client": + self.Manager.AddSDOClientToCurrent() + elif selected == "PDO Receive": + self.Manager.AddPDOReceiveToCurrent() + elif selected == "PDO Transmit": + self.Manager.AddPDOTransmitToCurrent() + elif selected == "Map Variable": + self.Parent.AddMapVariable() + elif selected in [menu for menu, indexes in self.Manager.GetCurrentSpecificMenu()]: + self.Manager.AddSpecificEntryToCurrent(selected) + else: + index = self.ChoiceIndex[self.IndexChoice.GetSelection()] + self.Manager.ManageEntriesOfCurrent([index], []) + self.Parent.RefreshBufferState() + self.RefreshIndexList() + event.Skip() + + def OnPartListBoxClick(self, event): + self.SubindexGrid.SetGridCursor(0, 0) + self.RefreshIndexList() + event.Skip() + + def OnIndexListClick(self, event): + self.SubindexGrid.SetGridCursor(0, 0) + self.RefreshTable() + event.Skip() + + def OnSubindexGridSelectCell(self, event): + wxCallAfter(self.Parent.RefreshStatusBar) + event.Skip() + +#------------------------------------------------------------------------------- +# Refresh Functions +#------------------------------------------------------------------------------- + + def RefreshIndexList(self): + selected = self.IndexList.GetSelection() + choice = self.IndexChoice.GetStringSelection() + choiceindex = self.IndexChoice.GetSelection() + if selected != wxNOT_FOUND: + selectedindex = self.ListIndex[selected] + self.IndexList.Clear() + self.IndexChoice.Clear() + i = self.PartList.GetSelection() + if i < len(DictionaryOrganisation): + values = DictionaryOrganisation[i] + self.ListIndex = [] + for name, index in self.Manager.GetCurrentValidIndexes(values["minIndex"], values["maxIndex"]): + self.IndexList.Append("0x%04X\t%s"%(index, name)) + self.ListIndex.append(index) + self.ChoiceIndex = [] + if i == 0: + self.IndexChoice.Append("User Type") + self.IndexChoice.SetStringSelection("User Type") + elif i == 2: + self.IndexChoice.Append("SDO Server") + self.IndexChoice.Append("SDO Client") + if choiceindex != wxNOT_FOUND and choice == self.IndexChoice.GetString(choiceindex): + self.IndexChoice.SetStringSelection(choice) + elif i in (3, 4): + self.IndexChoice.Append("PDO Receive") + self.IndexChoice.SetStringSelection("PDO Receive") + elif i in (5, 6): + self.IndexChoice.Append("PDO Transmit") + self.IndexChoice.SetStringSelection("PDO Transmit") + elif i == 8: + self.IndexChoice.Append("Map Variable") + self.IndexChoice.SetStringSelection("Map Variable") + else: + for name, index in self.Manager.GetCurrentValidChoices(values["minIndex"], values["maxIndex"]): + if index: + self.IndexChoice.Append("0x%04X\t%s"%(index, name)) + else: + self.IndexChoice.Append(name) + self.ChoiceIndex.append(index) + if choiceindex != wxNOT_FOUND and choice == self.IndexChoice.GetString(choiceindex): + self.IndexChoice.SetStringSelection(choice) + self.IndexChoice.Enable(self.IndexChoice.GetCount() != 0) + self.AddButton.Enable(self.IndexChoice.GetCount() != 0) + if selected == wxNOT_FOUND or selected >= len(self.ListIndex) or selectedindex != self.ListIndex[selected]: + self.Table.Empty() + self.CallbackCheck.SetValue(False) + self.CallbackCheck.Disable() + self.Table.ResetView(self.SubindexGrid) + self.Parent.RefreshStatusBar() + else: + self.IndexList.SetSelection(selected) + self.RefreshTable() + + def RefreshTable(self): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if index > 0x260: + self.CallbackCheck.Enable() + self.CallbackCheck.SetValue(self.Manager.HasCurrentEntryCallbacks(index)) + result = self.Manager.GetCurrentEntryValues(index) + if result != None: + self.Table.SetCurrentIndex(index) + data, editors = result + self.Table.SetData(data) + self.Table.SetEditors(editors) + self.Table.ResetView(self.SubindexGrid) + self.Parent.RefreshStatusBar() + +#------------------------------------------------------------------------------- +# Editing Table value function +#------------------------------------------------------------------------------- + + def OnSubindexGridCellChange(self, event): + index = self.Table.GetCurrentIndex() + subIndex = event.GetRow() + col = event.GetCol() + name = self.Table.GetColLabelValue(col) + value = self.Table.GetValue(subIndex, col) + editor = self.Table.GetEditor(subIndex, col) + self.Manager.SetCurrentEntry(index, subIndex, value, name, editor) + self.Parent.RefreshBufferState() + wxCallAfter(self.RefreshTable) + event.Skip() + + def OnCallbackCheck(self, event): + index = self.Table.GetCurrentIndex() + self.Manager.SetCurrentEntryCallbacks(index, self.CallbackCheck.GetValue()) + self.Parent.RefreshBufferState() + wxCallAfter(self.RefreshTable) + event.Skip() + +#------------------------------------------------------------------------------- +# Contextual Menu functions +#------------------------------------------------------------------------------- + + def OnIndexListRightUp(self, event): + if not self.FirstCall: + self.FirstCall = True + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if index < 0x260: + self.IndexListMenu.FindItemByPosition(0).Enable(False) + self.IndexListMenu.FindItemByPosition(1).Enable(True) + self.PopupMenu(self.IndexListMenu) + elif 0x1000 <= index <= 0x1BFF: + self.IndexListMenu.FindItemByPosition(0).Enable(False) + self.IndexListMenu.FindItemByPosition(1).Enable(False) + self.PopupMenu(self.IndexListMenu) + elif 0x2000 <= index <= 0x5FFF: + self.IndexListMenu.FindItemByPosition(0).Enable(True) + self.IndexListMenu.FindItemByPosition(1).Enable(False) + self.PopupMenu(self.IndexListMenu) + elif index >= 0x6000: + self.IndexListMenu.FindItemByPosition(0).Enable(False) + self.IndexListMenu.FindItemByPosition(1).Enable(False) + self.PopupMenu(self.IndexListMenu) + else: + self.FirstCall = False + event.Skip() + + def OnSubindexGridRightClick(self, event): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if self.Manager.IsCurrentEntry(index): + infos = self.Manager.GetEntryInfos(index) + if index >= 0x2000 and infos["struct"] & OD_MultipleSubindexes or infos["struct"] & OD_IdenticalSubindexes: + self.PopupMenu(self.SubindexGridMenu) + event.Skip() + + def OnRenameIndexMenu(self, event): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if self.Manager.IsCurrentEntry(index): + infos = self.Manager.GetEntryInfos(index) + dialog = wxTextEntryDialog(self, "Give a new name for index 0x%04X"%index, + "Rename an index", infos["name"], wxOK|wxCANCEL) + if dialog.ShowModal() == wxID_OK: + self.Manager.SetCurrentEntryName(index, dialog.GetValue()) + self.Parent.RefreshBufferState() + self.RefreshIndexList() + dialog.Destroy() + event.Skip() + + def OnModifyIndexMenu(self, event): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if self.Manager.IsCurrentEntry(index) and index < 0x260: + values, valuetype = self.Manager.GetCustomisedTypeValues(index) + dialog = UserTypeDialog(self) + dialog.SetTypeList(self.Manager.GetCustomisableTypes(), values[1]) + if valuetype == 0: + dialog.SetValues(min = values[2], max = values[3]) + elif valuetype == 1: + dialog.SetValues(length = values[2]) + if dialog.ShowModal() == wxID_OK: + type, min, max, length = dialog.GetValues() + self.Manager.SetCurrentUserType(index, type, min, max, length) + self.Parent.RefreshBufferState() + self.RefreshIndexList() + event.Skip() + + def OnDeleteIndexMenu(self, event): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if self.Manager.IsCurrentEntry(index): + self.Manager.ManageEntriesOfCurrent([],[index]) + self.Parent.RefreshBufferState() + self.RefreshIndexList() + event.Skip() + + def OnAddSubindexMenu(self, event): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if self.Manager.IsCurrentEntry(index): + dialog = wxTextEntryDialog(self, "Number of subindexes to add:", + "Add subindexes", "1", wxOK|wxCANCEL) + if dialog.ShowModal() == wxID_OK: + number = eval(dialog.GetValue()) + if type(number) == IntType: + self.Manager.AddSubentriesToCurrent(index, number) + self.Parent.RefreshBufferState() + self.RefreshIndexList() + else: + message = wxMessageDialog(self, "An integer is required!", "ERROR", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + event.Skip() + + def OnDeleteSubindexMenu(self, event): + selected = self.IndexList.GetSelection() + if selected != wxNOT_FOUND: + index = self.ListIndex[selected] + if self.Manager.IsCurrentEntry(index): + dialog = wxTextEntryDialog(self, "Number of subindexes to delete:", + "Delete subindexes", "1", wxOK|wxCANCEL) + if dialog.ShowModal() == wxID_OK: + number = eval(dialog.GetValue()) + if type(number) == IntType: + self.Manager.RemoveSubentriesFromCurrent(index, number) + self.Parent.RefreshBufferState() + self.RefreshIndexList() + else: + message = wxMessageDialog(self, "An integer is required!", "ERROR", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + event.Skip() + +[wxID_OBJDICTEDIT, wxID_OBJDICTEDITFILEOPENED, + wxID_OBJDICTEDITHELPBAR, +] = [wx.NewId() for _init_ctrls in range(3)] + +[wxID_OBJDICTEDITADDMENUITEMS0, wxID_OBJDICTEDITADDMENUITEMS1, + wxID_OBJDICTEDITADDMENUITEMS2, wxID_OBJDICTEDITADDMENUITEMS3, + wxID_OBJDICTEDITADDMENUITEMS4, wxID_OBJDICTEDITADDMENUITEMS5, +] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)] + +[wxID_OBJDICTEDITFILEMENUITEMS0, wxID_OBJDICTEDITFILEMENUITEMS1, + wxID_OBJDICTEDITFILEMENUITEMS2, wxID_OBJDICTEDITFILEMENUITEMS4, + wxID_OBJDICTEDITFILEMENUITEMS5, wxID_OBJDICTEDITFILEMENUITEMS6, + wxID_OBJDICTEDITFILEMENUITEMS7, wxID_OBJDICTEDITFILEMENUITEMS8, +] = [wx.NewId() for _init_coll_FileMenu_Items in range(8)] + +[wxID_OBJDICTEDITEDITMENUITEMS0, wxID_OBJDICTEDITEDITMENUITEMS1, + wxID_OBJDICTEDITEDITMENUITEMS2, wxID_OBJDICTEDITEDITMENUITEMS4, + wxID_OBJDICTEDITEDITMENUITEMS6, wxID_OBJDICTEDITEDITMENUITEMS7, + wxID_OBJDICTEDITEDITMENUITEMS8, +] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)] + +[wxID_OBJDICTEDITHELPMENUITEMS0, wxID_OBJDICTEDITHELPMENUITEMS1, + wxID_OBJDICTEDITHELPMENUITEMS2, +] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)] + +class objdictedit(wx.Frame): + def _init_coll_menuBar1_Menus(self, parent): + # generated method, don't edit + + parent.Append(menu=self.FileMenu, title='File') + parent.Append(menu=self.EditMenu, title='Edit') + parent.Append(menu=self.AddMenu, title='Add') + parent.Append(menu=self.HelpMenu, title='Help') + + def _init_coll_EditMenu_Items(self, parent): + # generated method, don't edit + + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS4, + kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R') + parent.AppendSeparator() + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS1, + kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z') + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS0, + kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y') + parent.AppendSeparator() + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS6, + kind=wx.ITEM_NORMAL, text='Node infos') + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS2, + kind=wx.ITEM_NORMAL, text='DS-301 Profile') + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS8, + kind=wx.ITEM_NORMAL, text='DS-302 Profile') + parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS7, + kind=wx.ITEM_NORMAL, text='Other Profile') + self.Bind(wx.EVT_MENU, self.OnUndoMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS1) + self.Bind(wx.EVT_MENU, self.OnRedoMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS0) + self.Bind(wx.EVT_MENU, self.OnCommunicationMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS2) + self.Bind(wx.EVT_MENU, self.OnRefreshMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS4) + self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS6) + self.Bind(wx.EVT_MENU, self.OnEditProfileMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS7) + self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu, + id=wxID_OBJDICTEDITEDITMENUITEMS8) + + def _init_coll_HelpMenu_Items(self, parent): + # generated method, don't edit + + parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS0, + kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1') + parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS1, + kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2') + parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS2, + kind=wx.ITEM_NORMAL, text='About') + self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu, + id=wxID_OBJDICTEDITHELPMENUITEMS0) + self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu, + id=wxID_OBJDICTEDITHELPMENUITEMS1) + self.Bind(wx.EVT_MENU, self.OnAboutMenu, + id=wxID_OBJDICTEDITHELPMENUITEMS2) + + def _init_coll_FileMenu_Items(self, parent): + # generated method, don't edit + + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS5, + kind=wx.ITEM_NORMAL, text='New\tCTRL+N') + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS0, + kind=wx.ITEM_NORMAL, text='Open\tCTRL+O') + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS1, + kind=wx.ITEM_NORMAL, text='Save\tCTRL+S') + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS6, + kind=wx.ITEM_NORMAL, text='Save As...\tALT+S') + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS2, + kind=wx.ITEM_NORMAL, text='Close\tCTRL+W') + parent.AppendSeparator() + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS7, + kind=wx.ITEM_NORMAL, text='Import XML file') + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS8, + kind=wx.ITEM_NORMAL, text='Build Dictionary\tCTRL+B') + parent.AppendSeparator() + parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS4, + kind=wx.ITEM_NORMAL, text='Exit') + self.Bind(wx.EVT_MENU, self.OnOpenMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS0) + self.Bind(wx.EVT_MENU, self.OnSaveMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS1) + self.Bind(wx.EVT_MENU, self.OnCloseMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS2) + self.Bind(wx.EVT_MENU, self.OnQuitMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS4) + self.Bind(wx.EVT_MENU, self.OnNewMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS5) + self.Bind(wx.EVT_MENU, self.OnSaveAsMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS6) + self.Bind(wx.EVT_MENU, self.OnImportMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS7) + self.Bind(wx.EVT_MENU, self.OnExportMenu, + id=wxID_OBJDICTEDITFILEMENUITEMS8) + + def _init_coll_AddMenu_Items(self, parent): + # generated method, don't edit + + parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS0, + kind=wx.ITEM_NORMAL, text='SDO Server') + parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS1, + kind=wx.ITEM_NORMAL, text='SDO Client') + parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS2, + kind=wx.ITEM_NORMAL, text='PDO Transmit') + parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS3, + kind=wx.ITEM_NORMAL, text='PDO Receive') + parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS4, + kind=wx.ITEM_NORMAL, text='Map Variable') + parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS5, + kind=wx.ITEM_NORMAL, text='User Type') + self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu, + id=wxID_OBJDICTEDITADDMENUITEMS0) + self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu, + id=wxID_OBJDICTEDITADDMENUITEMS1) + self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu, + id=wxID_OBJDICTEDITADDMENUITEMS2) + self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu, + id=wxID_OBJDICTEDITADDMENUITEMS3) + self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu, + id=wxID_OBJDICTEDITADDMENUITEMS4) + self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu, + id=wxID_OBJDICTEDITADDMENUITEMS5) + + def _init_coll_HelpBar_Fields(self, parent): + # generated method, don't edit + parent.SetFieldsCount(3) + + parent.SetStatusText(number=0, text='') + parent.SetStatusText(number=1, text='') + parent.SetStatusText(number=2, text='') + + parent.SetStatusWidths([100, 110, -1]) + + def _init_utils(self): + # generated method, don't edit + self.menuBar1 = wx.MenuBar() + self.menuBar1.SetEvtHandlerEnabled(True) + + self.FileMenu = wx.Menu(title='') + + self.EditMenu = wx.Menu(title='') + + self.AddMenu = wx.Menu(title='') + + self.HelpMenu = wx.Menu(title='') + + self._init_coll_menuBar1_Menus(self.menuBar1) + self._init_coll_FileMenu_Items(self.FileMenu) + self._init_coll_EditMenu_Items(self.EditMenu) + self._init_coll_AddMenu_Items(self.AddMenu) + self._init_coll_HelpMenu_Items(self.HelpMenu) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Frame.__init__(self, id=wxID_OBJDICTEDIT, name='objdictedit', + parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700), + style=wx.DEFAULT_FRAME_STYLE, title='Objdictedit') + self._init_utils() + self.SetClientSize(wx.Size(1000, 700)) + self.SetMenuBar(self.menuBar1) + self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_OBJDICTEDIT) + + self.FileOpened = wx.Notebook(id=wxID_OBJDICTEDITFILEOPENED, + name='FileOpened', parent=self, pos=wx.Point(0, 0), + size=wx.Size(0, 0), style=0) + self.FileOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, + self.OnFileSelectedChanged, id=wxID_OBJDICTEDITFILEOPENED) + + self.HelpBar = wx.StatusBar(id=wxID_OBJDICTEDITHELPBAR, name='HelpBar', + parent=self, style=wxST_SIZEGRIP) + self._init_coll_HelpBar_Fields(self.HelpBar) + self.SetStatusBar(self.HelpBar) + + def __init__(self, parent): + self._init_ctrls(parent) + self.HtmlFrameOpened = [] + + self.Manager = NodeManager() + for filepath in filesOpen: + self.Manager.OpenFileInCurrent(filepath) + new_editingpanel = EditingPanel(self, self.Manager) + self.FileOpened.AddPage(new_editingpanel, "") + self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex()) + if self.Manager.CurrentDS302Defined(): + self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True) + else: + self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False) + self.RefreshEditMenu() + self.RefreshBufferState() + self.RefreshProfileMenu() + self.RefreshMainMenu() + + self.RefreshBufferState() + self.RefreshTitle() + self.RefreshMainMenu() + + def GetNoteBook(self): + return self.FileOpened + + def OnAddSDOServerMenu(self, event): + self.Manager.AddSDOServerToCurrent() + self.RefreshBufferState() + self.RefreshCurrentIndexList() + event.Skip() + + def OnAddSDOClientMenu(self, event): + self.Manager.AddSDOClientToCurrent() + self.RefreshBufferState() + self.RefreshCurrentIndexList() + event.Skip() + + def OnAddPDOTransmitMenu(self, event): + self.Manager.AddPDOTransmitToCurrent() + self.RefreshBufferState() + self.RefreshCurrentIndexList() + event.Skip() + + def OnAddPDOReceiveMenu(self, event): + self.Manager.AddPDOReceiveToCurrent() + self.RefreshBufferState() + self.RefreshCurrentIndexList() + event.Skip() + + def OnAddMapVariableMenu(self, event): + self.AddMapVariable() + event.Skip() + + def OnAddUserTypeMenu(self, event): + self.AddUserType() + event.Skip() + + def OnFileSelectedChanged(self, event): + selected = self.FileOpened.GetSelection() + self.Manager.ChangeCurrentNode(selected) + self.RefreshBufferState() + self.RefreshProfileMenu() + event.Skip() + + def OnHelpDS301Menu(self, event): + selected = self.FileOpened.GetSelection() + if selected >= 0: + window = self.FileOpened.GetPage(selected) + result = window.GetSelection() + if result: + index, subIndex = result + result = OpenPDFDocIndex(index) + if type(result) == StringType: + message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + event.Skip() + + def OnHelpCANFestivalMenu(self, event): + self.OpenHtmlFrame("CAN Festival Reference", "../doc/canfestival.html", wx.Size(1000, 600)) + event.Skip() + + def OnAboutMenu(self, event): + self.OpenHtmlFrame("About CAN Festival", "../doc/about.html", wx.Size(500, 450)) + event.Skip() + + def OpenHtmlFrame(self, title, file, size): + if title not in self.HtmlFrameOpened: + self.HtmlFrameOpened.append(title) + window = HtmlFrame(self, self.HtmlFrameOpened) + window.SetTitle(title) + window.SetHtmlPage(file) + window.SetClientSize(size) + window.Show() + + def OnQuitMenu(self, event): + self.Close() + event.Skip() + + def OnCloseFrame(self, event): + if self.Manager.OneFileHasChanged(): + dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close Application", wxYES_NO|wxCANCEL|wxICON_QUESTION) + answer = dialog.ShowModal() + dialog.Destroy() + if answer == wxID_YES: + self.Manager.ChangeCurrentNode(0) + for i in xrange(self.FileOpened.GetPageCount()): + if self.Manager.CurrentIsSaved(): + self.Manager.CloseCurrent() + else: + self.Save() + self.Manager.CloseCurrent(True) + event.Skip() + elif answer == wxID_NO: + for i in xrange(self.FileOpened.GetPageCount()): + self.Manager.CloseCurrent(True) + wxCallAfter(self.Close) + event.Skip() + else: + event.Skip() + +#------------------------------------------------------------------------------- +# Refresh Functions +#------------------------------------------------------------------------------- + + def RefreshTitle(self): + if self.FileOpened.GetPageCount() > 0: + self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename()) + else: + self.SetTitle("Objdictedit") + + def OnRefreshMenu(self, event): + self.RefreshCurrentIndexList() + event.Skip() + + def RefreshCurrentIndexList(self): + selected = self.FileOpened.GetSelection() + window = self.FileOpened.GetPage(selected) + window.RefreshIndexList() + + def RefreshStatusBar(self): + window = self.FileOpened.GetPage(self.FileOpened.GetSelection()) + selection = window.GetSelection() + if selection: + index, subIndex = selection + if self.Manager.IsCurrentEntry(index): + self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0) + self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1) + entryinfos = self.Manager.GetEntryInfos(index) + name = entryinfos["name"] + category = "Optional" + if entryinfos["need"]: + category = "Mandatory" + struct = "VAR" + number = "" + if entryinfos["struct"] & OD_IdenticalIndexes: + number = " possibly defined %d times"%entryinfos["nbmax"] + if entryinfos["struct"] & OD_IdenticalSubindexes: + struct = "REC" + elif entryinfos["struct"] & OD_MultipleSubindexes: + struct = "ARRAY" + text = "%s: %s entry of struct %s%s."%(name,category,struct,number) + self.HelpBar.SetStatusText(text, 2) + else: + for i in xrange(3): + self.HelpBar.SetStatusText("", i) + else: + for i in xrange(3): + self.HelpBar.SetStatusText("", i) + + def RefreshMainMenu(self): + if self.FileOpened.GetPageCount() > 0: + self.menuBar1.EnableTop(1, True) + self.menuBar1.EnableTop(2, True) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, True) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, True) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, True) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, True) + else: + self.menuBar1.EnableTop(1, False) + self.menuBar1.EnableTop(2, False) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, False) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, False) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, False) + self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, False) + + def RefreshEditMenu(self): + if self.FileOpened.GetPageCount() > 0: + undo, redo = self.Manager.GetCurrentBufferState() + self.EditMenu.FindItemByPosition(2).Enable(undo) + self.EditMenu.FindItemByPosition(3).Enable(redo) + else: + self.EditMenu.FindItemByPosition(2).Enable(False) + self.EditMenu.FindItemByPosition(3).Enable(False) + + def RefreshProfileMenu(self): + profile = self.Manager.GetCurrentProfileName() + edititem = self.EditMenu.FindItemByPosition(8) + length = self.AddMenu.GetMenuItemCount() + for i in xrange(length-6): + additem = self.AddMenu.FindItemByPosition(6) + self.AddMenu.Delete(additem.GetId()) + if profile not in ("None", "DS-301"): + edititem.SetText("%s Profile"%profile) + edititem.Enable(True) + self.AddMenu.AppendSeparator() + for text, indexes in self.Manager.GetCurrentSpecificMenu(): + new_id = wx.NewId() + self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text) + self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id) + else: + edititem.SetText("Other Profile") + edititem.Enable(False) + + +#------------------------------------------------------------------------------- +# Buffer Functions +#------------------------------------------------------------------------------- + + def RefreshBufferState(self): + fileopened = self.Manager.GetAllFilenames() + for idx, filename in enumerate(fileopened): + self.FileOpened.SetPageText(idx, filename) + self.RefreshEditMenu() + self.RefreshTitle() + + def OnUndoMenu(self, event): + self.Manager.LoadCurrentPrevious() + self.RefreshCurrentIndexList() + self.RefreshBufferState() + event.Skip() + + def OnRedoMenu(self, event): + self.Manager.LoadCurrentNext() + self.RefreshCurrentIndexList() + self.RefreshBufferState() + event.Skip() + + +#------------------------------------------------------------------------------- +# Load and Save Funtions +#------------------------------------------------------------------------------- + + def OnNewMenu(self, event): + self.FilePath = "" + dialog = CreateNodeDialog(self) + if dialog.ShowModal() == wxID_OK: + name, id, type = dialog.GetValues() + if name != "": + good = not name[0].isdigit() + for item in name.split("_"): + good &= item.isalnum() + else: + good = False + if good: + profile,filepath = dialog.GetProfile() + NMT = dialog.GetNMTManagement() + options = dialog.GetOptions() + result = self.Manager.CreateNewNode(name, id, type, profile, filepath, NMT, options) + if not IsOfType(result, StringType): + new_editingpanel = EditingPanel(self, self.Manager) + self.FileOpened.AddPage(new_editingpanel, "") + self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex()) + self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False) + if "DS302" in options: + self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True) + self.RefreshBufferState() + self.RefreshProfileMenu() + self.RefreshMainMenu() + else: + message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + else: + message = wxMessageDialog(self, "Node name can't be undefined or start with a digit and must be composed of alphanumerical characters or underscore!", "ERROR", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + event.Skip() + + def OnOpenMenu(self, event): + filepath = self.Manager.GetCurrentFilePath() + if filepath != "": + directory = os.path.dirname(filepath) + else: + directory = os.getcwd() + dialog = wxFileDialog(self, "Choose a file", directory, "", "OD files (*.od)|*.od|All files|*.*", wxOPEN) + if dialog.ShowModal() == wxID_OK: + filepath = dialog.GetPath() + if os.path.isfile(filepath): + result = self.Manager.OpenFileInCurrent(filepath) + if type(result) != StringType: + new_editingpanel = EditingPanel(self, self.Manager) + self.FileOpened.AddPage(new_editingpanel, "") + self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex()) + if self.Manager.CurrentDS302Defined(): + self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True) + else: + self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False) + self.RefreshEditMenu() + self.RefreshBufferState() + self.RefreshProfileMenu() + self.RefreshMainMenu() + else: + message = wxMessageDialog(self, e.args[0], "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + event.Skip() + + def OnSaveMenu(self, event): + self.Save() + event.Skip() + + def OnSaveAsMenu(self, event): + self.SaveAs() + evant.Skip() + + def Save(self): + result = self.Manager.SaveCurrentInFile() + if not result: + self.SaveAs() + elif type(result) != StringType: + self.RefreshBufferState() + else: + message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + + def SaveAs(self): + filepath = self.Manager.GetCurrentFilePath() + if filepath != "": + directory, filename = os.path.split(filepath) + else: + directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0] + dialog = wxFileDialog(self, "Choose a file", directory, filename, "OD files (*.od)|*.od|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT) + if dialog.ShowModal() == wxID_OK: + filepath = dialog.GetPath() + if os.path.isdir(os.path.dirname(filepath)): + result = self.Manager.SaveCurrentInFile(filepath) + if type(result) != StringType: + self.RefreshBufferState() + else: + message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + else: + message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + + def OnCloseMenu(self, event): + answer = wxID_YES + result = self.Manager.CloseCurrent() + if not result: + dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close File", wxYES_NO|wxCANCEL|wxICON_QUESTION) + answer = dialog.ShowModal() + dialog.Destroy() + if answer == wxID_YES: + self.OnSaveMenu(event) + if self.Manager.CurrentIsSaved(): + self.Manager.CloseCurrent() + elif answer == wxID_NO: + self.Manager.CloseCurrent(True) + if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber(): + current = self.FileOpened.GetSelection() + self.FileOpened.DeletePage(current) + if self.FileOpened.GetPageCount() > 0: + self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1)) + self.RefreshBufferState() + self.RefreshMainMenu() + event.Skip() + + +#------------------------------------------------------------------------------- +# Import and Export Functions +#------------------------------------------------------------------------------- + + def OnImportMenu(self, event): + dialog = wxFileDialog(self, "Choose a file", os.getcwd(), "", "XML OD files (*.xml)|*.xml|All files|*.*", wxOPEN) + if dialog.ShowModal() == wxID_OK: + filepath = dialog.GetPath() + if os.path.isfile(filepath): + result = self.Manager.ImportCurrentFromFile(filepath) + if result: + if self.FileOpened.GetPageCount() == 0: + new_editingpanel = EditingPanel(self, self.Manager) + self.FileOpened.AddPage(new_editingpanel, "") + self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex()) + self.RefreshBufferState() + self.RefreshCurrentIndexList() + self.RefreshProfileMenu() + self.RefreshMainMenu() + message = wxMessageDialog(self, "Import successful", "Information", wxOK|wxICON_INFORMATION) + message.ShowModal() + message.Destroy() + dialog.Destroy() + event.Skip() + + def OnExportMenu(self, event): + dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "CANFestival OD files (*.c)|*.c|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT) + if dialog.ShowModal() == wxID_OK: + filepath = dialog.GetPath() + if os.path.isdir(os.path.dirname(filepath)): + path, extend = os.path.splitext(filepath) + if extend in ("", "."): + filepath = path + ".c" + result = self.Manager.ExportCurrentToFile(filepath) + if result: + message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION) + message.ShowModal() + message.Destroy() + else: + message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + event.Skip() + +#------------------------------------------------------------------------------- +# Editing Profiles functions +#------------------------------------------------------------------------------- + + def OnCommunicationMenu(self, event): + dictionary,current = self.Manager.GetCurrentCommunicationLists() + self.EditProfile("Edit DS-301 Profile", dictionary, current) + event.Skip() + + def OnOtherCommunicationMenu(self, event): + dictionary,current = self.Manager.GetCurrentDS302Lists() + self.EditProfile("Edit DS-301 Profile", dictionary, current) + event.Skip() + + def OnEditProfileMenu(self, event): + title = "Edit %s Profile"%self.Manager.GetCurrentProfileName() + dictionary,current = self.Manager.GetCurrentProfileLists() + self.EditProfile(title, dictionary, current) + event.Skip() + + def EditProfile(self, title, dictionary, current): + dialog = CommunicationDialog(self) + dialog.SetTitle(title) + dialog.SetIndexDictionary(dictionary) + dialog.SetCurrentList(current) + dialog.RefreshLists() + if dialog.ShowModal() == wxID_OK: + new_profile = dialog.GetCurrentList() + addinglist = [] + removinglist = [] + for index in new_profile: + if index not in current: + addinglist.append(index) + for index in current: + if index not in new_profile: + removinglist.append(index) + self.Manager.ManageEntriesOfCurrent(addinglist, removinglist) + self.Manager.GenerateMapList() + self.Manager.BufferCurrentNode() + self.RefreshBufferState() + self.RefreshCurrentIndexList() + dialog.Destroy() + + def GetProfileCallBack(self, text): + def ProfileCallBack(event): + self.Manager.AddSpecificEntryToCurrent(text) + self.RefreshBufferState() + self.RefreshCurrentIndexList() + event.Skip() + return ProfileCallBack + +#------------------------------------------------------------------------------- +# Edit Node informations function +#------------------------------------------------------------------------------- + + def OnNodeInfosMenu(self, event): + dialog = NodeInfosDialog(self) + name,id,type = self.Manager.GetCurrentNodeInfos() + profile = self.Manager.GetCurrentProfileName() + dialog.SetProfiles([profile]) + dialog.SetValues(name, id, type, profile) + if dialog.ShowModal() == wxID_OK: + name,id,type,profile = dialog.GetValues() + self.Manager.SetCurrentNodeInfos(name, id, type) + self.RefreshBufferState() + self.RefreshProfileMenu() + event.Skip() + + +#------------------------------------------------------------------------------- +# Add User Types and Variables +#------------------------------------------------------------------------------- + + def AddMapVariable(self): + dialog = MapVariableDialog(self) + if dialog.ShowModal() == wxID_OK: + index, name, struct, number = dialog.GetValues() + result = self.Manager.AddMapVariableToCurrent(index, name, struct, number) + if type(result) != StringType: + self.RefreshBufferState() + self.RefreshCurrentIndexList() + else: + message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + + def AddUserType(self): + dialog = UserTypeDialog(self) + dialog.SetTypeList(self.Manager.GetCustomisableTypes()) + if dialog.ShowModal() == wxID_OK: + type, min, max, length = dialog.GetValues() + result = self.Manager.AddUserTypeToCurrent(type, min, max, length) + if not IsOfType(result, StringType): + self.RefreshBufferState() + self.RefreshCurrentIndexList() + else: + message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + dialog.Destroy() + + + +#------------------------------------------------------------------------------- +# Editing Communication Dialog +#------------------------------------------------------------------------------- + + +[wxID_COMMUNICATIONDIALOG, wxID_COMMUNICATIONDIALOGMAINPANEL, + wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES, wxID_COMMUNICATIONDIALOGCURRENTINDEXES, + wxID_COMMUNICATIONDIALOGSELECT, wxID_COMMUNICATIONDIALOGUNSELECT, + wxID_COMMUNICATIONDIALOGSTATICTEXT1, wxID_COMMUNICATIONDIALOGSTATICTEXT2 +] = [wx.NewId() for _init_ctrls in range(8)] + +class CommunicationDialog(wx.Dialog): + def _init_coll_flexGridSizer1_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.MainPanel, 0, border=0, flag=0) + + def _init_sizers(self): + # generated method, don't edit + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Dialog.__init__(self, id=wxID_COMMUNICATIONDIALOG, + name='CommunicationDialog', parent=prnt, pos=wx.Point(234, 216), + size=wx.Size(726, 437), style=wx.DEFAULT_DIALOG_STYLE, + title='Edit Communication Profile') + self.SetClientSize(wx.Size(726, 437)) + + self.MainPanel = wx.Panel(id=wxID_COMMUNICATIONDIALOGMAINPANEL, + name='MainPanel', parent=self, pos=wx.Point(0, 0), + size=wx.Size(688, 382), style=wx.TAB_TRAVERSAL) + self.MainPanel.SetAutoLayout(True) + + self.PossibleIndexes = wx.ListBox(choices=[], + id=wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES, + name='PossibleIndexes', parent=self.MainPanel, pos=wx.Point(40, + 48), size=wx.Size(280, 320), style=wxLB_EXTENDED) + self.PossibleIndexes.Bind(wx.EVT_LEFT_DCLICK, self.OnPossibleIndexesDClick, + id=wxID_COMMUNICATIONDIALOGPOSSIBLEINDEXES) + + self.CurrentIndexes = wx.ListBox(choices=[], + id=wxID_COMMUNICATIONDIALOGCURRENTINDEXES, name='CurrentIndexes', + parent=self.MainPanel, pos=wx.Point(400, 48), size=wx.Size(280, + 320), style=wxLB_EXTENDED) + self.CurrentIndexes.Bind(wx.EVT_LEFT_DCLICK, self.OnCurrentIndexesDClick, + id=wxID_COMMUNICATIONDIALOGCURRENTINDEXES) + + self.Select = wx.Button(id=wxID_COMMUNICATIONDIALOGSELECT, label='>>', + name='Select', parent=self.MainPanel, pos=wx.Point(345, 136), + size=wx.Size(32, 32), style=0) + self.Select.Bind(wx.EVT_BUTTON, self.OnSelectButton, + id=wxID_COMMUNICATIONDIALOGSELECT) + + self.Unselect = wx.Button(id=wxID_COMMUNICATIONDIALOGUNSELECT, + label='<<', name='Unselect', parent=self.MainPanel, + pos=wx.Point(345, 216), size=wx.Size(32, 30), style=0) + self.Unselect.Bind(wx.EVT_BUTTON, self.OnUnselectButton, + id=wxID_COMMUNICATIONDIALOGUNSELECT) + + self.staticText1 = wx.StaticText(id=wxID_COMMUNICATIONDIALOGSTATICTEXT1, + label='Possible Profile Indexes :', name='staticText1', + parent=self.MainPanel, pos=wx.Point(40, 24), size=wx.Size(156, + 17), style=0) + + self.staticText2 = wx.StaticText(id=wxID_COMMUNICATIONDIALOGSTATICTEXT2, + label='Current Profile Indexes :', name='staticText2', + parent=self.MainPanel, pos=wx.Point(400, 24), size=wx.Size(152, + 17), style=0) + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) + self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER) + self.AllList = [] + self.CurrentList = [] + self.IndexDictionary = {} + + def SetIndexDictionary(self, dictionary): + self.IndexDictionary = dictionary + + def SetCurrentList(self, list): + self.CurrentList = [] + self.CurrentList.extend(list) + self.CurrentList.sort() + + def GetCurrentList(self): + return self.CurrentList + + def RefreshLists(self): + self.PossibleIndexes.Clear() + self.CurrentIndexes.Clear() + self.AllList = [] + for index in self.IndexDictionary.iterkeys(): + if index not in self.CurrentList: + self.AllList.append(index) + self.AllList.sort() + for index in self.AllList: + self.PossibleIndexes.Append("0x%04X\t%s"%(index, self.IndexDictionary[index][0])) + for index in self.CurrentList: + if index in self.IndexDictionary: + self.CurrentIndexes.Append("0x%04X\t%s"%(index, self.IndexDictionary[index][0])) + + def OnPossibleIndexesDClick(self, event): + self.SelectPossible() + event.Skip() + + def OnCurrentIndexesDClick(self, event): + self.UnselectCurrent() + event.Skip() + + def OnSelectButton(self, event): + self.SelectPossible() + event.Skip() + + def OnUnselectButton(self, event): + self.UnselectCurrent() + event.Skip() + + def SelectPossible(self): + selected = self.PossibleIndexes.GetSelections() + for i in selected: + self.CurrentList.append(self.AllList[i]) + self.CurrentList.sort() + self.RefreshLists() + + def UnselectCurrent(self): + selected = self.CurrentIndexes.GetSelections() + for i in selected: + if not self.IndexDictionary[self.CurrentList[i]][1]: + self.CurrentList.pop(i) + self.CurrentList.sort() + self.RefreshLists() + + + +#------------------------------------------------------------------------------- +# Create Map Variable Dialog +#------------------------------------------------------------------------------- + + +[wxID_MAPVARIABLEDIALOG, wxID_MAPVARIABLEDIALOGINDEX, + wxID_MAPVARIABLEDIALOGINDEXNAME, wxID_MAPVARIABLEDIALOGMAINPANEL, + wxID_MAPVARIABLEDIALOGNUMBER, wxID_MAPVARIABLEDIALOGRADIOBUTTON1, + wxID_MAPVARIABLEDIALOGRADIOBUTTON2, wxID_MAPVARIABLEDIALOGRADIOBUTTON3, + wxID_MAPVARIABLEDIALOGSTATICTEXT1, wxID_MAPVARIABLEDIALOGSTATICTEXT2, + wxID_MAPVARIABLEDIALOGSTATICTEXT3, wxID_MAPVARIABLEDIALOGSTATICTEXT4, +] = [wx.NewId() for _init_ctrls in range(12)] + +class MapVariableDialog(wx.Dialog): + def _init_coll_flexGridSizer1_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.MainPanel, 0, border=0, flag=0) + + def _init_sizers(self): + # generated method, don't edit + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Dialog.__init__(self, id=wxID_MAPVARIABLEDIALOG, + name='CommunicationDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(444, 186), style=wx.DEFAULT_DIALOG_STYLE, + title='Add Map Variable') + self.SetClientSize(wx.Size(444, 186)) + + self.MainPanel = wx.Panel(id=wxID_MAPVARIABLEDIALOGMAINPANEL, + name='MainPanel', parent=self, pos=wx.Point(0, 0), + size=wx.Size(431, 142), style=wx.TAB_TRAVERSAL) + self.MainPanel.SetAutoLayout(True) + + self.staticText1 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT1, + label='Index :', name='staticText1', parent=self.MainPanel, + pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0) + + self.radioButton1 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON1, + label='VAR', name='radioButton1', parent=self.MainPanel, + pos=wx.Point(208, 48), size=wx.Size(72, 24), style=0) + self.radioButton1.SetValue(True) + self.radioButton1.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton1Click, + id=wxID_MAPVARIABLEDIALOGRADIOBUTTON1) + + self.radioButton2 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON2, + label='REC', name='radioButton2', parent=self.MainPanel, + pos=wx.Point(208, 96), size=wx.Size(96, 24), style=0) + self.radioButton2.SetValue(False) + self.radioButton2.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton2Click, + id=wxID_MAPVARIABLEDIALOGRADIOBUTTON2) + + self.radioButton3 = wx.RadioButton(id=wxID_MAPVARIABLEDIALOGRADIOBUTTON3, + label='ARRAY', name='radioButton3', parent=self.MainPanel, + pos=wx.Point(208, 72), size=wx.Size(80, 24), style=0) + self.radioButton3.SetValue(False) + self.radioButton3.Bind(wx.EVT_RADIOBUTTON, self.OnRadioButton3Click, + id=wxID_MAPVARIABLEDIALOGRADIOBUTTON3) + + self.staticText2 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT2, + label='Type :', name='staticText2', parent=self.MainPanel, + pos=wx.Point(208, 24), size=wx.Size(38, 17), style=0) + + self.IndexName = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGINDEXNAME, + name='IndexName', parent=self.MainPanel, pos=wx.Point(24, 104), + size=wx.Size(152, 24), style=0, value='Undefined') + + self.staticText3 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT3, + label='Name :', name='staticText3', parent=self.MainPanel, + pos=wx.Point(24, 80), size=wx.Size(47, 17), style=0) + + self.Index = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGINDEX, name='Index', + parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(152, + 25), style=0, value='0x2000') + + self.staticText4 = wx.StaticText(id=wxID_MAPVARIABLEDIALOGSTATICTEXT4, + label='Number :', name='staticText4', parent=self.MainPanel, + pos=wx.Point(312, 80), size=wx.Size(88, 16), style=0) + + self.Number = wx.TextCtrl(id=wxID_MAPVARIABLEDIALOGNUMBER, + name='Number', parent=self.MainPanel, pos=wx.Point(312, 104), + size=wx.Size(112, 24), style=wx.TE_RIGHT, value='0') + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) + self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER) + self.staticText4.Enable(False) + self.Number.Enable(False) + + def GetValues(self): + if self.radioButton1.GetValue(): + struct = 1 + elif self.radioButton3.GetValue(): + struct = 3 + elif self.radioButton2.GetValue(): + struct = 7 + name = self.IndexName.GetValue() + index = eval(self.Index.GetValue()) + number = eval(self.Number.GetValue()) + return index, name, struct, number + + def OnRadioButton1Click(self, event): + self.staticText4.Enable(False) + self.Number.Enable(False) + event.Skip() + + def OnRadioButton2Click(self, event): + self.staticText4.Enable(True) + self.Number.Enable(True) + event.Skip() + + def OnRadioButton3Click(self, event): + self.staticText4.Enable(True) + self.Number.Enable(True) + event.Skip() + + + +#------------------------------------------------------------------------------- +# Create User Type Dialog +#------------------------------------------------------------------------------- + + +[wxID_USERTYPEDIALOG, wxID_USERTYPEDIALOGLENGTH, wxID_USERTYPEDIALOGMAINPANEL, + wxID_USERTYPEDIALOGMAX, wxID_USERTYPEDIALOGMIN, + wxID_USERTYPEDIALOGSTATICBOX1, wxID_USERTYPEDIALOGSTATICTEXT1, + wxID_USERTYPEDIALOGSTATICTEXT2, wxID_USERTYPEDIALOGSTATICTEXT3, + wxID_USERTYPEDIALOGSTATICTEXT4, wxID_USERTYPEDIALOGTYPE, +] = [wx.NewId() for _init_ctrls in range(11)] + +class UserTypeDialog(wx.Dialog): + def _init_coll_flexGridSizer1_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.MainPanel, 0, border=0, flag=0) + + def _init_sizers(self): + # generated method, don't edit + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Dialog.__init__(self, id=wxID_USERTYPEDIALOG, name='UserTypeDialog', + parent=prnt, pos=wx.Point(376, 223), size=wx.Size(444, 228), + style=wx.DEFAULT_DIALOG_STYLE, title='Add User Type') + self.SetClientSize(wx.Size(444, 228)) + + self.MainPanel = wx.Panel(id=wxID_USERTYPEDIALOGMAINPANEL, + name='MainPanel', parent=self, pos=wx.Point(0, 0), + size=wx.Size(431, 182), style=wx.TAB_TRAVERSAL) + self.MainPanel.SetAutoLayout(True) + + self.staticText1 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT1, + label='Type :', name='staticText1', parent=self.MainPanel, + pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0) + + self.staticBox1 = wx.StaticBox(id=wxID_USERTYPEDIALOGSTATICBOX1, + label='Values', name='staticBox1', parent=self.MainPanel, + pos=wx.Point(200, 24), size=wx.Size(224, 144), style=0) + + self.staticText2 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT2, + label='Minimum :', name='staticText2', parent=self.MainPanel, + pos=wx.Point(216, 48), size=wx.Size(67, 17), style=0) + + self.Min = wx.TextCtrl(id=wxID_USERTYPEDIALOGMIN, name='Min', + parent=self.MainPanel, pos=wx.Point(296, 48), size=wx.Size(112, + 24), style=wx.TE_RIGHT, value='0') + + self.staticText3 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT3, + label='Maximum :', name='staticText3', parent=self.MainPanel, + pos=wx.Point(216, 88), size=wx.Size(71, 17), style=0) + + self.Max = wx.TextCtrl(id=wxID_USERTYPEDIALOGMAX, name='Max', + parent=self.MainPanel, pos=wx.Point(296, 88), size=wx.Size(112, + 25), style=wx.TE_RIGHT, value='0') + + self.staticText4 = wx.StaticText(id=wxID_USERTYPEDIALOGSTATICTEXT4, + label='Length :', name='staticText4', parent=self.MainPanel, + pos=wx.Point(216, 128), size=wx.Size(52, 17), style=0) + + self.Length = wx.TextCtrl(id=wxID_USERTYPEDIALOGLENGTH, name='Length', + parent=self.MainPanel, pos=wx.Point(296, 128), size=wx.Size(112, + 25), style=wx.TE_RIGHT, value='0') + + self.Type = wx.Choice(choices=[], id=wxID_USERTYPEDIALOGTYPE, + name='Type', parent=self.MainPanel, pos=wx.Point(24, 48), + size=wx.Size(160, 24), style=0) + self.Type.Bind(wx.EVT_CHOICE, self.OnTypeChoice, + id=wxID_USERTYPEDIALOGTYPE) + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) + self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER) + self.TypeDictionary = {} + + def SetValues(self, min = None, max = None, length = None): + if min != None: + self.Min.SetValue(str(min)) + if max != None: + self.Max.SetValue(str(max)) + if length != None: + self.Length.SetValue(str(length)) + + def SetTypeList(self, typedic, type = None): + self.Type.Clear() + list = [] + for index, (name, valuetype) in typedic.iteritems(): + self.TypeDictionary[name] = (index, valuetype) + list.append((index, name)) + list.sort() + for index, name in list: + self.Type.Append(name) + if type != None: + self.Type.SetStringSelection(typedic[type][0]) + self.RefreshValues() + + def OnTypeChoice(self, event): + self.RefreshValues() + event.Skip() + + def RefreshValues(self): + name = self.Type.GetStringSelection() + if name != "": + valuetype = self.TypeDictionary[name][1] + if valuetype == 0: + self.staticText2.Enable(True) + self.staticText3.Enable(True) + self.staticText4.Enable(False) + self.Min.Enable(True) + self.Max.Enable(True) + self.Length.Enable(False) + elif valuetype == 1: + self.staticText2.Enable(False) + self.staticText3.Enable(False) + self.staticText4.Enable(True) + self.Min.Enable(False) + self.Max.Enable(False) + self.Length.Enable(True) + else: + self.staticText2.Enable(False) + self.staticText3.Enable(False) + self.staticText4.Enable(False) + self.Min.Enable(False) + self.Max.Enable(False) + self.Length.Enable(False) + + def GetValues(self): + name = self.Type.GetStringSelection() + type = self.TypeDictionary[name][0] + min = eval(self.Min.GetValue()) + max = eval(self.Max.GetValue()) + length = eval(self.Length.GetValue()) + return type, min, max, length + + + +#------------------------------------------------------------------------------- +# Editing Node Infos Dialog +#------------------------------------------------------------------------------- + + +[wxID_NODEINFOSDIALOG, wxID_NODEINFOSDIALOGMAINPANEL, + wxID_NODEINFOSDIALOGNAME, wxID_NODEINFOSDIALOGNODEID, + wxID_NODEINFOSDIALOGPROFILE, wxID_NODEINFOSDIALOGSTATICTEXT1, + wxID_NODEINFOSDIALOGSTATICTEXT2, wxID_NODEINFOSDIALOGSTATICTEXT3, + wxID_NODEINFOSDIALOGSTATICTEXT4, wxID_NODEINFOSDIALOGTYPE, +] = [wx.NewId() for _init_ctrls in range(10)] + +class NodeInfosDialog(wx.Dialog): + def _init_coll_flexGridSizer1_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.MainPanel, 0, border=0, flag=0) + + def _init_sizers(self): + # generated method, don't edit + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Dialog.__init__(self, id=wxID_NODEINFOSDIALOG, + name='NodeInfosDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(249, 250), style=wx.DEFAULT_DIALOG_STYLE, + title='Node Infos') + self.SetClientSize(wx.Size(249, 250)) + + self.MainPanel = wx.Panel(id=wxID_NODEINFOSDIALOGMAINPANEL, + name='MainPanel', parent=self, pos=wx.Point(0, 0), + size=wx.Size(231, 264), style=wx.TAB_TRAVERSAL) + self.MainPanel.SetAutoLayout(True) + + self.staticText1 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT1, + label='Name :', name='staticText1', parent=self.MainPanel, + pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0) + + self.staticText2 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT2, + label='Node ID :', name='staticText2', parent=self.MainPanel, + pos=wx.Point(24, 80), size=wx.Size(67, 17), style=0) + + self.staticText3 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT3, + label='Type :', name='staticText3', parent=self.MainPanel, + pos=wx.Point(24, 136), size=wx.Size(71, 17), style=0) + + self.Type = wx.Choice(choices=[], id=wxID_NODEINFOSDIALOGTYPE, + name='Type', parent=self.MainPanel, pos=wx.Point(24, 160), + size=wx.Size(200, 24), style=0) + + self.Name = wx.TextCtrl(id=wxID_NODEINFOSDIALOGNAME, name='Name', + parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(200, + 25), style=0, value='') + + self.NodeID = wx.TextCtrl(id=wxID_NODEINFOSDIALOGNODEID, name='NodeID', + parent=self.MainPanel, pos=wx.Point(24, 104), size=wx.Size(200, + 25), style=wx.TE_RIGHT, value='') + + self.staticText4 = wx.StaticText(id=wxID_NODEINFOSDIALOGSTATICTEXT4, + label='Profile :', name='staticText4', parent=self.MainPanel, + pos=wx.Point(24, 192), size=wx.Size(47, 17), style=0) + + self.Profile = wx.Choice(choices=[], id=wxID_NODEINFOSDIALOGPROFILE, + name='Profile', parent=self.MainPanel, pos=wx.Point(24, 216), + size=wx.Size(200, 24), style=0) + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) + self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER) + self.Type.Append("master") + self.Type.Append("slave") + self.staticText4.Hide() + self.Profile.Hide() + + def SetProfiles(self, profiles): + for profile in profiles: + self.Profile.Append(profile) + + def SetValues(self, name, id, type, profile): + self.Name.SetValue(name) + self.NodeID.SetValue("0x%02X"%id) + self.Type.SetStringSelection(type) + self.Profile.SetStringSelection(profile) + + def GetValues(self): + name = self.Name.GetValue() + nodeid = eval(self.NodeID.GetValue()) + type = self.Type.GetStringSelection() + profile = self.Profile.GetStringSelection() + return name, nodeid, type, profile + + + +#------------------------------------------------------------------------------- +# Create New Node Dialog +#------------------------------------------------------------------------------- + + +[wxID_CREATENODEDIALOG, wxID_CREATENODEDIALOGEMERGENCY, + wxID_CREATENODEDIALOGGENSYNC, wxID_CREATENODEDIALOGMAINPANEL, + wxID_CREATENODEDIALOGNAME, wxID_CREATENODEDIALOGNMT_HEARTBEAT, + wxID_CREATENODEDIALOGNMT_NODEGUARDING, wxID_CREATENODEDIALOGNMT_NONE, + wxID_CREATENODEDIALOGNODEID, wxID_CREATENODEDIALOGPROFILE, + wxID_CREATENODEDIALOGSAVECONFIG, wxID_CREATENODEDIALOGSTATICTEXT1, + wxID_CREATENODEDIALOGSTATICTEXT2, wxID_CREATENODEDIALOGSTATICTEXT3, + wxID_CREATENODEDIALOGSTATICTEXT4, wxID_CREATENODEDIALOGSTATICTEXT5, + wxID_CREATENODEDIALOGSTATICTEXT6, wxID_CREATENODEDIALOGSTOREEDS, + wxID_CREATENODEDIALOGTYPE, +] = [wx.NewId() for _init_ctrls in range(19)] + +class CreateNodeDialog(wx.Dialog): + def _init_coll_flexGridSizer1_Items(self, parent): + # generated method, don't edit + + parent.AddWindow(self.MainPanel, 0, border=0, flag=0) + + def _init_sizers(self): + # generated method, don't edit + self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0) + + self._init_coll_flexGridSizer1_Items(self.flexGridSizer1) + + self.SetSizer(self.flexGridSizer1) + + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Dialog.__init__(self, id=wxID_CREATENODEDIALOG, + name='CreateNodeDialog', parent=prnt, pos=wx.Point(376, 223), + size=wx.Size(451, 316), style=wx.DEFAULT_DIALOG_STYLE, + title='Create a new Node') + self.SetClientSize(wx.Size(451, 316)) + + self.MainPanel = wx.Panel(id=wxID_CREATENODEDIALOGMAINPANEL, + name='MainPanel', parent=self, pos=wx.Point(0, 0), + size=wx.Size(440, 278), style=wx.TAB_TRAVERSAL) + self.MainPanel.SetAutoLayout(True) + + self.staticText1 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT1, + label='Name :', name='staticText1', parent=self.MainPanel, + pos=wx.Point(24, 24), size=wx.Size(156, 17), style=0) + + self.staticText2 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT2, + label='Node ID :', name='staticText2', parent=self.MainPanel, + pos=wx.Point(24, 80), size=wx.Size(67, 17), style=0) + + self.staticText3 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT3, + label='Type :', name='staticText3', parent=self.MainPanel, + pos=wx.Point(24, 136), size=wx.Size(71, 17), style=0) + + self.Type = wx.Choice(choices=[], id=wxID_CREATENODEDIALOGTYPE, + name='Type', parent=self.MainPanel, pos=wx.Point(24, 160), + size=wx.Size(200, 24), style=0) + + self.Name = wx.TextCtrl(id=wxID_CREATENODEDIALOGNAME, name='Name', + parent=self.MainPanel, pos=wx.Point(24, 48), size=wx.Size(200, + 25), style=0, value='') + + self.NodeID = wx.TextCtrl(id=wxID_CREATENODEDIALOGNODEID, name='NodeID', + parent=self.MainPanel, pos=wx.Point(24, 104), size=wx.Size(200, + 25), style=wx.TE_RIGHT, value='') + + self.staticText4 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT4, + label='Profile :', name='staticText4', parent=self.MainPanel, + pos=wx.Point(24, 192), size=wx.Size(47, 17), style=0) + + self.Profile = wx.Choice(choices=[], id=wxID_CREATENODEDIALOGPROFILE, + name='Profile', parent=self.MainPanel, pos=wx.Point(24, 216), + size=wx.Size(200, 24), style=0) + self.Profile.Bind(wx.EVT_CHOICE, self.OnProfileChoice, + id=wxID_CREATENODEDIALOGPROFILE) + + self.staticText5 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT5, + label='Network Management :', name='staticText5', + parent=self.MainPanel, pos=wx.Point(256, 24), size=wx.Size(152, + 16), style=0) + + self.NMT_None = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_NONE, + label='None', name='NMT_None', parent=self.MainPanel, + pos=wx.Point(256, 40), size=wx.Size(114, 24), style=0) + self.NMT_None.SetValue(True) + + self.NMT_NodeGuarding = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_NODEGUARDING, + label='Node Guarding', name='NMT_NodeGuarding', + parent=self.MainPanel, pos=wx.Point(256, 64), size=wx.Size(128, + 24), style=0) + self.NMT_NodeGuarding.SetValue(False) + + self.NMT_Heartbeat = wx.RadioButton(id=wxID_CREATENODEDIALOGNMT_HEARTBEAT, + label='Heartbeat', name='NMT_Heartbeat', parent=self.MainPanel, + pos=wx.Point(256, 88), size=wx.Size(114, 24), style=0) + self.NMT_Heartbeat.SetValue(False) + + self.staticText6 = wx.StaticText(id=wxID_CREATENODEDIALOGSTATICTEXT6, + label='Options :', name='staticText6', parent=self.MainPanel, + pos=wx.Point(256, 128), size=wx.Size(72, 17), style=0) + + self.DS302 = wx.CheckBox(id=wxID_CREATENODEDIALOGGENSYNC, + label='DS-302 Profile', name='DS302', parent=self.MainPanel, + pos=wx.Point(256, 144), size=wx.Size(128, 24), style=0) + self.DS302.SetValue(False) + + self.GenSYNC = wx.CheckBox(id=wxID_CREATENODEDIALOGGENSYNC, + label='Generate SYNC', name='GenSYNC', parent=self.MainPanel, + pos=wx.Point(256, 168), size=wx.Size(128, 24), style=0) + self.GenSYNC.SetValue(False) + + self.Emergency = wx.CheckBox(id=wxID_CREATENODEDIALOGEMERGENCY, + label='Emergency support', name='Emergency', + parent=self.MainPanel, pos=wx.Point(256, 192), size=wx.Size(152, + 24), style=0) + self.Emergency.SetValue(False) + + self.SaveConfig = wx.CheckBox(id=wxID_CREATENODEDIALOGSAVECONFIG, + label='Save Configuration', name='SaveConfig', + parent=self.MainPanel, pos=wx.Point(256, 216), size=wx.Size(152, + 24), style=0) + self.SaveConfig.SetValue(False) + + self.StoreEDS = wx.CheckBox(id=wxID_CREATENODEDIALOGSTOREEDS, + label='Store EDS', name='StoreEDS', parent=self.MainPanel, + pos=wx.Point(256, 240), size=wx.Size(144, 24), style=0) + self.StoreEDS.SetValue(False) + + self._init_sizers() + + def __init__(self, parent): + self._init_ctrls(parent) + self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL) + self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_CENTER) + self.Type.Append("master") + self.Type.Append("slave") + self.Type.SetStringSelection("slave") + self.ListProfile = {"None" : ""} + self.Profile.Append("None") + self.Directory = os.path.join(os.getcwd(), "config") + listfiles = os.listdir(self.Directory) + listfiles.sort() + for item in listfiles: + name, extend = os.path.splitext(item) + if os.path.isfile(os.path.join(self.Directory, item)) and extend == ".prf" and name != "DS-302": + self.ListProfile[name] = os.path.join(self.Directory, item) + self.Profile.Append(name) + self.Profile.Append("Other") + self.Profile.SetStringSelection("None") + + def GetValues(self): + name = self.Name.GetValue() + nodeid = 0 + if self.NodeID.GetValue() != "": + nodeid = eval(self.NodeID.GetValue()) + type = self.Type.GetStringSelection() + return name, nodeid, type + + def GetProfile(self): + name = self.Profile.GetStringSelection() + return name, self.ListProfile[name] + + def GetNMTManagement(self): + if self.NMT_None.GetValue(): + return "None" + elif self.NMT_NodeGuarding.GetValue(): + return "NodeGuarding" + elif self.NMT_Heartbeat.GetValue(): + return "Heartbeat" + return None + + def GetOptions(self): + options = [] + if self.DS302.GetValue(): + options.append("DS302") + if self.GenSYNC.GetValue(): + options.append("GenSYNC") + if self.Emergency.GetValue(): + options.append("Emergency") + if self.SaveConfig.GetValue(): + options.append("SaveConfig") + if self.StoreEDS.GetValue(): + options.append("StoreEDS") + return options + + def OnProfileChoice(self, event): + if self.Profile.GetStringSelection() == "Other": + dialog = wxFileDialog(self, "Choose a file", self.Directory, "", "OD Profile files (*.prf)|*.prf|All files|*.*", wxOPEN) + dialog.ShowModal() + filepath = dialog.GetPath() + dialog.Destroy() + if os.path.isfile(filepath): + name = os.path.splitext(os.path.basename(filepath))[0] + self.ListProfile[name] = filepath + length = self.Profile.GetCount() + self.Profile.Insert(name, length - 2) + self.Profile.SetStringSelection(name) + else: + self.Profile.SetStringSelection("None") + event.Skip() + + + +#------------------------------------------------------------------------------- +# Html Frame +#------------------------------------------------------------------------------- + + +[wxID_HTMLFRAME, wxID_HTMLFRAMEHTMLCONTENT, +] = [wx.NewId() for _init_ctrls in range(2)] + +class HtmlFrame(wx.Frame): + def _init_ctrls(self, prnt): + # generated method, don't edit + wx.Frame.__init__(self, id=wxID_HTMLFRAME, name='HtmlFrame', + parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616), + style=wx.DEFAULT_FRAME_STYLE, title='') + self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_HTMLFRAME) + + self.HtmlContent = wxUrlClickHtmlWindow(id=wxID_HTMLFRAMEHTMLCONTENT, + name='HtmlContent', parent=self, pos=wx.Point(0, 0), + size=wx.Size(-1, -1), style=wxHW_SCROLLBAR_AUTO|wxHW_NO_SELECTION) + EVT_HTML_URL_CLICK(self.HtmlContent, self.OnLinkClick) + + def __init__(self, parent, opened): + self._init_ctrls(parent) + self.HtmlFrameOpened = opened + + def SetHtmlCode(self, htmlcode): + self.HtmlContent.SetPage(htmlcode) + + def SetHtmlPage(self, htmlpage): + self.HtmlContent.LoadPage(htmlpage) + + def OnCloseFrame(self, event): + self.HtmlFrameOpened.remove(self.GetTitle()) + event.Skip() + + def OnLinkClick(self, event): + url = event.linkinfo[0] + try: + import webbrowser + except ImportError: + wxMessageBox('Please point your browser at: %s' % url) + else: + webbrowser.open(url) + + +#------------------------------------------------------------------------------- +# Exception Handler +#------------------------------------------------------------------------------- + +Max_Traceback_List_Size = 20 + +def Display_Exception_Dialog(e_type,e_value,e_tb): + trcbck_lst = [] + for i,line in enumerate(traceback.extract_tb(e_tb)): + trcbck = " " + str(i+1) + ". " + if line[0].find(os.getcwd()) == -1: + trcbck += "file : " + str(line[0]) + ", " + else: + trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", " + trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2]) + trcbck_lst.append(trcbck) + + # Allow clicking.... + cap = wx.Window_GetCapture() + if cap: + cap.ReleaseMouse() + + dlg = wx.SingleChoiceDialog(None, + """ +An error happens. + +Click on OK for saving an error report. + +Please contact LOLITech at: ++33 (0)3 29 52 95 67 +bugs_objdictedit@lolitech.fr + + +Error: +""" + + str(e_type) + " : " + str(e_value), + "Error", + trcbck_lst) + try: + res = (dlg.ShowModal() == wx.ID_OK) + finally: + dlg.Destroy() + + return res + +def Display_Error_Dialog(e_value): + message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR) + message.ShowModal() + message.Destroy() + +def get_last_traceback(tb): + while tb.tb_next: + tb = tb.tb_next + return tb + + +def format_namespace(d, indent=' '): + return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()]) + + +ignored_exceptions = [] # a problem with a line in a module is only reported once per session + +def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]): + + def handle_exception(e_type, e_value, e_traceback): + traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func + last_tb = get_last_traceback(e_traceback) + ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno) + if str(e_value).startswith("!!!"): + Display_Error_Dialog(e_value) + elif ex not in ignored_exceptions: + ignored_exceptions.append(ex) + result = Display_Exception_Dialog(e_type,e_value,e_traceback) + if result: + info = { + 'app-title' : wx.GetApp().GetAppName(), # app_title + 'app-version' : app_version, + 'wx-version' : wx.VERSION_STRING, + 'wx-platform' : wx.Platform, + 'python-version' : platform.python_version(), #sys.version.split()[0], + 'platform' : platform.platform(), + 'e-type' : e_type, + 'e-value' : e_value, + 'date' : time.ctime(), + 'cwd' : os.getcwd(), + } + if e_traceback: + info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value) + last_tb = get_last_traceback(e_traceback) + exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred + info['locals'] = format_namespace(exception_locals) + if 'self' in exception_locals: + info['self'] = format_namespace(exception_locals['self'].__dict__) + + output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w') + lst = info.keys() + lst.sort() + for a in lst: + output.write(a+":\n"+str(info[a])+"\n\n") + + #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args) + sys.excepthook = handle_exception + +if __name__ == '__main__': + app = wxPySimpleApp() + wxInitAllImageHandlers() + + # Install a exception handle for bug reports + wxAddExceptHook(os.getcwd(),__version__) + + frame = objdictedit(None) + + frame.Show() + app.MainLoop() diff -r 000000000000 -r 4472ee7c6c3e objdictgen/objdictedit.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/objdictedit.sh Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,24 @@ +#!/bin/sh + +#This file is part of CanFestival, a library implementing CanOpen Stack. +# +#Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +# +#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 + +# Xbootclasspath option added to workaround bugs in Java 1.4 +java -Xbootclasspath/p:jaxe/lib/xml-apis.jar:jaxe/lib/xerces.jar:jaxe/lib/xalan.jar -classpath jaxe/lib/Jaxe.jar:jaxe/lib/xml-apis.jar:jaxe/lib/xerces.jar:jaxe/lib/xalan.jar:jaxe/lib/jakarta-oro-2.0.8.jar:jaxe/lib/jazzy.jar jaxe/Jaxe config/objdict_Jaxe_cfg.xml diff -r 000000000000 -r 4472ee7c6c3e objdictgen/objdictgen.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/objdictgen.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of CanFestival, a library implementing CanOpen Stack. +# +#Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +# +#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 + +import getopt,sys,os +from types import * + +from nodemanager import * + +def usage(): + print "\nUsage of objdictgen.py :" + print "\n %s XMLFilePath CFilePath\n"%sys.argv[0] + +try: + opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) +except getopt.GetoptError: + # print help information and exit: + usage() + sys.exit(2) + +for o, a in opts: + if o in ("-h", "--help"): + usage() + sys.exit() + +fileIn = "" +fileOut = "" +if len(args) == 2: + fileIn = args[0] + fileOut = args[1] +else: + usage() + sys.exit() + +if __name__ == '__main__': + if fileIn != "" and fileOut != "": + manager = NodeManager() + if os.path.isfile(fileIn): + print "Parsing input file" + result = manager.ImportCurrentFromFile(fileIn) + if type(result) != UnicodeType: + Node = result + else: + print result + sys.exit(-1) + else: + print "%s is not a valid file!"%fileIn + sys.exit(-1) + print "Writing output file" + result = manager.ExportCurrentToFile(fileOut) + if type(result) == UnicodeType: + print result + sys.exit(-1) + print "All done" + diff -r 000000000000 -r 4472ee7c6c3e objdictgen/xml_in.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/objdictgen/xml_in.py Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,453 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +#This file is part of CanFestival, a library implementing CanOpen Stack. +# +#Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD +# +#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 + +from xml.parsers import expat + +import node +from node import * + +maxObjects = 8 + +currentPDOIndex = 0 +currentBitsMapped = 0 +currentMaxObjects = 0 +currentNbMappedObjects = 0 + +nextPdoIndex = {"rx":0x1400,"tx":0x1800} + +valid_elements = ["node","heartbeat_consumers","sdo_clients","pdo","mapped_object", + "pdo_param","pdo_receive","pdo_transmit","mapped_variable","mapped_table", + "mapped_string_variable","mapped_string_table"] + +#------------------------------------------------------------------------------- +# Callback method of parse +#------------------------------------------------------------------------------- + +def StartElement(name, attrs): + if name in valid_elements: + if name == "node": + startNode(attrs) + elif name == "heartbeat_consumers": + startHeartBeatConsumers(attrs) + elif name == "sdo_clients": + startSdoClients(attrs) + elif name in ["pdo_param","pdo_receive","pdo_transmit"]: + raise ValueError, """!!! The XML grammar has changed. +Please, open your xml file, delete the tags pdo_param, pdo_receive and pdo_transmit. +Use instead the tag pdo for each pdo to create, and (optional) use the tag mapped_object (menu pdo/map and object ...).""" + elif name == "pdo": + startPdo(attrs) + elif name == "mapped_object": + startMappedObject(attrs) + elif name == "mapped_variable": + startMappedVariable(attrs) + elif name == "mapped_table": + startMappedTable(attrs) + elif name == "mapped_string_variable": + startMappedVariable(attrs) + elif name == "mapped_string_table": + startMappedTable(attrs) + +def EndElement(name): + if name in valid_elements: + if name == "node": + stopNode() + +def CharacterData(data): + pass + +#------------------------------------------------------------------------------- +# Creation of Node +#------------------------------------------------------------------------------- + +def startNode(attrs): + name = attrs["name"] + Node.SetNodeName(name) + + if "node_id" in attrs and len(attrs["node_id"]) > 0: + node_id = eval(attrs["node_id"]) + else: + node_id = 0x01 # We define here a default node_id. + Node.SetNodeID(node_id) + + typeNode = attrs["type_node"] + Node.SetNodeType(typeNode) + + if "device_type_1000" in attrs: + device_type = eval(attrs["device_type_1000"]) + else: + device_type = 0 + Node.AddEntry(0x1000, 0, device_type) + Node.AddEntry(0x1001, 0, 0) + Node.AddEntry(0x1005, 0, 0x00000080) + Node.AddEntry(0x1006, 0, 0) + Node.AddEntry(0x1007, 0, 0) + + if "manufacturer_device_name_1008" in attrs: + manufacturer_device_name = attrs["manufacturer_device_name_1008"] + else: + manufacturer_device_name = "" + Node.AddEntry(0x1008, 0, manufacturer_device_name) + + if "manufacturer_hardware_version_1009" in attrs: + manufacturer_hardware_version = attrs["manufacturer_hardware_version_1009"] + else: + manufacturer_hardware_version = "__DATE__" + Node.AddEntry(0x1009, 0, manufacturer_hardware_version) + + if "manufacturer_software_version_100A" in attrs: + manufacturer_software_version = attrs["manufacturer_software_version_100A"] + else: + manufacturer_software_version = 0 + Node.AddEntry(0x100A, 0, manufacturer_software_version) + + if "vendor_id_1018" in attrs: + vendor_id = eval(attrs["vendor_id_1018"]) + else: + vendor_id = 0 + if "product_code_1018" in attrs: + product_code = eval(attrs["product_code_1018"]) + else: + product_code = 0 + if "revision_number_1018" in attrs: + revision_number = eval(attrs["revision_number_1018"]) + else: + revision_number = 0 + if "serial_number_1018" in attrs: + serial_number = eval(attrs["serial_number_1018"]) + else: + serial_number = 0 + Node.AddEntry(0x1018, 1, vendor_id) + Node.AddEntry(0x1018, 2, product_code) + Node.AddEntry(0x1018, 3, revision_number) + Node.AddEntry(0x1018, 4, serial_number) + +def stopNode(): + heartBeatProducer() + sdoServer() + +#------------------------------------------------------------------------------- +# Creation of PDO in Object Dictionary +#------------------------------------------------------------------------------- + +def startPdo(attrs): + global currentPdoIndex + global currentMaxObjects + global currentNbMappedObjects + global currentBitsMapped + global maxObjects + + cobId = 0 + transmissionType = 253 # Default is on request. Why not ? + + # Find the type of the PDO and search the index of the last added + type = attrs["type_rx_tx"] + index = nextPdoIndex[type] + + # If the index of the PDO is define, verify that it has a good index + if "index_communication_parameter" in attrs: + index = eval(attrs["index_communication_parameter"]) + if type == "rx" and not 0x1400 <= index <= 0x15FF: + raise ValueError, """!!! Abort because Index PDO receive : 0x%04X not valid. +Valid index is 0x1400 ... 0x15FF"""%index + if type == "tx" and not 0x1800 <= index <= 0x19FF: + raise ValueError, """!!! Abort because Index PDO transmit : 0x%04X not valid. +Valid index is 0x1800 ... 0x19FF"""%index + + # Extract the PDO communication parameters + if "cob_id" == attrs: + cobId = eval(attrs["cob_id"]) + if "max_objects_in_pdo" == attrs: + maxObjects = eval(attrs["max_objects_in_pdo"]) + if "transmission_type" in attrs: + transmissionType = eval(attrs["transmission_type"]) + + if Node.IsEntry(index): + raise ValueError, """!!! Abort because the PDO at index : 0x%04X have been already defined."""%index + + # Communication parameters + Node.AddEntry(index, 1, cobId) + Node.AddEntry(index, 2, transmissionType) + + # Mapping parameters + mapping_index = index + 0x200 + for i in xrange(1, maxObjects + 1): + Node.AddEntry(mapping_index, i, 0x0) + + currentPdoIndex = index + currentMaxObjects = maxObjects + currentBitsMapped = 0 + currentNbMappedObjects = 0 + + nextPdoIndex[type] = index + 1 + +def startMappedObject(attrs): + global currentPdoIndex + global currentMaxObjects + global currentNbMappedObjects + global currentBitsMapped + + index = currentPdoIndex + mapping_index = index + 0x200 + + indexObject = eval(attrs["index"]) + subIndexObject = eval(attrs["sub_index"]) + sizeInBitsObject = eval(attrs["size_in_bits"]) + + if currentMaxObjects == 0: + raise ValueError, """!!! Abort because of a bogue for mapped object (defined at index 0x%04X, subIndex 0x%025X) +in PDO. index : 0x%04X is undefined."""%(indexObject,subindexObject,mapping_index) + if currentNbMappedObjects >= currentMaxObjects: + raise ValueError, """!!! Abort mapping object (defined at index 0x%04X, subIndex 0x%02X) +in PDO index 0x%04X. max objects (%d) reached."""%(IndexObject,subIndexObject,mapping_index,pdo[mapping_index]["maxObjects"]) + if currentBitsMapped + sizeInBitsObject > 64: + raise ValueError, """!!! Abort mapping object (defined at index 0x%04X, subIndex 0x%02X) +in PDO index 0x%04X. No room to put %d bits in the PDO."""%(IndexObject,subIndexObject,mapping_index,sizeInBitsObject) + + value = eval("0x%04X%02X%02X"%(indexObject,subIndexObject,sizeInBitsObject)) + Node.SetEntry(mapping_index, currentNbMappedObjects + 1, value) + + currentNbMappedObjects += 1 + currentBitsMapped += sizeInBitsObject + +#------------------------------------------------------------------------------- +# Creation of mapped variable and table +#------------------------------------------------------------------------------- + +def startMappedVariable(attrs): + name = attrs["name"] + index = eval(attrs["index"]) + subIndex = eval(attrs["sub_index"]) + + if "size_in_bits" in attrs: + size = eval(attrs["size_in_bits"]) # Numeric variable + if "type" in attrs: + type = attrs["type"] + if (type == "UNS"): + type = "UNSIGNED" + else: # Default type + type = "UNSIGNED" + typename = "%s%d"%(type,size) + + type_index = Manager.GetTypeIndex(typename, False) + if type_index == None: + raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : Unrecognized type : %s"""%(name,index,subIndex,typename) + + # Begin ValueRange support + if "min_value" in attrs or "max_value" in attrs: + if "min_value" in attrs and "max_value" in attrs: + minValue = eval(attrs["min_value"]) + maxValue = eval(attrs["max_value"]) + if (minValue > maxValue): + raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : error in value-range : min > max"""%(name,index,subIndex) + else: + raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : You have defined only a min or a max value. \nIf you define one, you must define both."""%(name,index,subIndex) + + type_index = findRangeType(type_index, minValue, maxValue) + if type_index == None: + raise ValueError, """!!! Sorry, too many different value range have been defined""" + # End ValueRange support + + if "size_in_byte" in attrs: + size = eval(attrs["size_in_byte"]) # String variable + type_index = findStringType(Manager.GetTypeIndex("VISIBLE_STRING", False), size) + if type_index == None: + raise ValueError, """!!! Sorry, too many different string length have been defined""" + + if "access" in attrs: + access = attrs["access"].lower() + else: + access = "rw" # default value + + if index < 0x2000 or index > 0xBFFF: + raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : Variable can't be defined using this index-subindex."""%(name,index,subIndex) + + if subIndex == 0: + Node.AddMappingEntry(index, name = name, struct = 1) + elif subIndex == 1: + Node.AddMappingEntry(index, struct = 3) + Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False}) + result = Node.AddMappingEntry(index, subIndex, values = {"name" : name, "type" : type_index, "access" : access, "pdo" : True}) + + if result: + Node.AddEntry(index, subIndex, 0) + else: + raise ValueError, """!!! ERROR : For variable "%s" at index 0x%04X, subindex 0x%02X : Unable to map"""%(name,index,subIndex) + +def startMappedTable(attrs): + name = attrs["name"] + number_elements = eval(attrs["number_elements"]) + index = eval(attrs["index"]) + + if "size_in_bits" in attrs: + size = eval(attrs["size_in_bits"]) # Numeric variable + if "type" in attrs: + type = attrs["type"] + if (type == "UNS"): + type = "UNSIGNED" + else: # Default type + type = "UNSIGNED" + typename = "%s%d"%(type,size) + + type_index = Manager.GetTypeIndex(typename, False) + if type_index == None: + raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : Unrecognized type : %s"""%(name,index,typename) + + # Begin ValueRange support + if "min_value" in attrs or "max_value" in attrs: + if "min_value" in attrs and "max_value" in attrs: + minValue = eval(attrs["min_value"]) + maxValue = eval(attrs["max_value"]) + if (minValue > maxValue): + raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : error in value-range : min > max"""%(name,index) + else: + raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : You have defined only a min or a max value. \nIf you define one, you must define both."""%(name,index) + + type_index = findRangeType(type_index, minValue, maxValue) + if type_index == None: + raise ValueError, """!!! Sorry, too many different value range have been defined""" + # End ValueRange support + + if "size_in_byte" in attrs: + size = eval(attrs["size_in_byte"]) # String variable + type_index = findStringType(Manager.GetTypeIndex("VISIBLE_STRING", False), size) + if type_index == None: + raise ValueError, """!!! Sorry, too many different string length have been defined""" + + if "access" in attrs: + access = attrs["access"].lower() + else: + access = "rw" # default value + + if index < 0x2000 or index > 0xBFFF: + raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : Variable can't be defined using this index-subindex."""%(name,index) + + result = Node.AddMappingEntry(index, name = name, struct = 7) + if not result: + raise ValueError, """!!! ERROR : For table \"%s\" at index 0x%04X : Unable to map because a variable or a table is using this index"""%(name,index) + Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False}) + Node.AddMappingEntry(index, 1, values = {"name" : name, "type" : type_index, "access" : access, "pdo" : True, "nbmax" : number_elements}) + + for subIndex in xrange(1,number_elements+1): + Node.AddEntry(index, subIndex, 0) + +def findRangeType(type, minValue, maxValue): + index = 0xA0 + while index < 0x100 and Node.IsEntry(index): + current_type = Node.GetEntry(index, 1) + if current_type == type: + current_minValue = Node.GetEntry(index, 2) + current_maxValue = Node.GetEntry(index, 3) + if current_minValue == minValue and current_maxValue == maxValue: + return index + index += 1 + if index < 0x100: + infos = Manager.GetEntryInfos(type, False) + name = "%s[%d-%d]"%(infos["name"], minValue, maxValue) + Node.AddMappingEntry(index, name = name, struct = 3, size = infos["size"], default = infos["default"]) + Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False}) + Node.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False}) + Node.AddMappingEntry(index, 2, values = {"name" : "Minimum Value", "type" : type, "access" : "ro", "pdo" : False}) + Node.AddMappingEntry(index, 3, values = {"name" : "Maximum Value", "type" : type, "access" : "ro", "pdo" : False}) + Node.AddEntry(index, 1, type) + Node.AddEntry(index, 2, minValue) + Node.AddEntry(index, 3, maxValue) + return index + return None + +def findStringType(type, length): + index = 0xA0 + while index < 0x100 and Node.IsEntry(index): + current_type = Node.GetEntry(index, 1) + if current_type == type: + current_length = Node.GetEntry(index, 2) + if current_length == length: + return index + index += 1 + if index < 0x100: + infos = Manager.GetEntryInfos(type, False) + name = "%s%d"%(Manager.GetTypeName(type), length) + Node.AddMappingEntry(index, name = name, struct = 3, size = infos["size"], default = infos["default"]) + Node.AddMappingEntry(index, 0, values = {"name" : "Number of Entries", "type" : 0x02, "access" : "ro", "pdo" : False}) + Node.AddMappingEntry(index, 1, values = {"name" : "Type", "type" : 0x02, "access" : "ro", "pdo" : False}) + Node.AddMappingEntry(index, 2, values = {"name" : "Length", "type" : 0x02, "access" : "ro", "pdo" : False}) + Node.AddEntry(index, 1, type) + Node.AddEntry(index, 2, length) + return index + return None + +#------------------------------------------------------------------------------- +# Creation HeartBeat Producer & Consumers +#------------------------------------------------------------------------------- + +def heartBeatProducer(): + Node.AddEntry(0x1017, 0, 0) + +def startHeartBeatConsumers(attrs): + nombre = eval(attrs["nombre"]) + for i in xrange(nombre): + Node.AddEntry(0x1016, i + 1, 0) + +#------------------------------------------------------------------------------- +# Creation of SDO Server & Clients +#------------------------------------------------------------------------------- + +def sdoServer(): + Node.AddEntry(0x1200, 1, 0x600 + Node.GetNodeID()) + Node.AddEntry(0x1200, 2, 0x580 + Node.GetNodeID()) + +def startSdoClients(attrs): + nombre = eval(attrs["nombre"]) + for i in xrange(nombre): + Node.AddEntry(0x1280 + i, 1, 0x600) + Node.AddEntry(0x1280 + i, 2, 0x580) + Node.AddEntry(0x1280 + i, 3, 0) + +#------------------------------------------------------------------------------- +# Parse file with Saxe +#------------------------------------------------------------------------------- + +def ParseFile(filepath): + xmlfile = open(filepath,"r") + Parser = expat.ParserCreate() + Parser.StartElementHandler = StartElement + Parser.EndElementHandler = EndElement + Parser.CharacterDataHandler = CharacterData + ParserStatus = Parser.ParseFile(xmlfile) + xmlfile.close() + +def GenerateNode(filepath, manager): + global Node + global Manager + Manager = manager + Node = node.Node() + ParseFile(filepath) + return Node + +#------------------------------------------------------------------------------- +# Main Function +#------------------------------------------------------------------------------- + +if __name__ == '__main__': + ParseFile("test.xml") + diff -r 000000000000 -r 4472ee7c6c3e src/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/.cvsignore Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,2 @@ +Makefile +libcanfestival.a diff -r 000000000000 -r 4472ee7c6c3e src/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Makefile.in Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,123 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +PROG_CFLAGS = SUB_PROG_CFLAGS +LIBS = -lm +SHAREDLIBOPT = -shared +OS_NAME = SUB_OS_NAME +ARCH_NAME = SUB_ARCH_NAME +PREFIX = SUB_PREFIX +BINUTILS_PREFIX = SUB_BINUTILS_PREFIX +TARGET = SUB_TARGET +LSS_ENABLE=SUB_LSS_ENABLE +LED_ENABLE=SUB_LED_ENABLE +NVRAM_ENABLE=SUB_NVRAM_ENABLE +CAN_DRIVER = SUB_CAN_DRIVER +TIMERS_DRIVER = SUB_TIMERS_DRIVER +TIMERS_ENABLE = SUB_TIMERS_ENABLE + +INCLUDES = -I../include -I../include/$(TARGET) -I../include/$(CAN_DRIVER) -I../include/$(TIMERS_DRIVER) -I../drivers/$(TARGET) + +OBJS = $(TARGET)_objacces.o $(TARGET)_lifegrd.o $(TARGET)_sdo.o\ + $(TARGET)_pdo.o $(TARGET)_sync.o $(TARGET)_nmtSlave.o $(TARGET)_nmtMaster.o $(TARGET)_states.o + +# ecos driver shortcuts timer.c +ifeq ($(TIMERS_ENABLE),YES) +OBJS += $(TARGET)_timer.o +endif + +# # # # Target specific paramters # # # # + +ifeq ($(TARGET),ecos_lpc2138_sja1000) +ECOS_GLOBAL_CFLAGS=-mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -Os -ffunction-sections -fdata-sections -fno-exceptions -finline-functions +ECOS_GLOBAL_LDFLAGS=-mcpu=arm7tdmi -Wl,--gc-sections -Wl,-static -nostdlib +endif + +ifeq ($(TARGET),hcs12) +OPT_CFLAGS = -Os +PROGDEFINES = -mnoshort -Wall -Wmissing-prototypes -fno-strict-aliasing +endif + +ifeq ($(TARGET),generic) +OPT_CFLAGS = -O2 +endif + +# # # # Options # # # # + +ifeq ($(LSS_ENABLE),YES) +OBJS += $(TARGET)_lss.o +SRC_HFILES += ../include/lss.h +endif + +ifeq ($(LED_ENABLE),YES) +OBJS += $(TARGET)_led.o +SRC_HFILES += ../include/led.h +endif + +ifeq ($(NVRAM_ENABLE),YES) +OBJS += $(TARGET)_nvram.o +SRC_HFILES += ../include/nvram.h +endif + +ifeq ($(TIMERS_ENABLE),YES) +OBJS += $(TARGET)_timer.o +endif + + +CFLAGS = SUB_OPT_CFLAGS + +all: canfestival + +canfestival: libcanfestival.a + +libcanfestival.a: $(OBJS) + @echo " " + @echo "*********************************************" + @echo "**Building [libcanfestival.a]" + @echo "*********************************************" + $(BINUTILS_PREFIX)ar rc $@ $(OBJS) + $(BINUTILS_PREFIX)ranlib $@ + +$(TARGET)_%o: %c + @echo " " + @echo "*********************************************" + @echo "**Compiling $< -> $@" + @echo "*********************************************" + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: libcanfestival.a + mkdir -p $(PREFIX)/lib/ + mkdir -p $(PREFIX)/include/canfestival + cp libcanfestival.a $(PREFIX)/lib/ + cp ../include/*.h $(PREFIX)/include/canfestival + +uninstall: + rm -f $(PREFIX)/lib/libcanfestival.a + rm -rf $(PREFIX)/include/canfestival + +clean: + rm -f $(OBJS) libcanfestival.a + +mrproper: clean + diff -r 000000000000 -r 4472ee7c6c3e src/led.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/led.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,318 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: CANopen Canada (canfestival@canopencanada.ca) + +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 + + DS-303-3 + LED implementation +*/ + +#include +#include + +#include +#include + +#include + +#include +#include + +#include "led.h" + + +void led_start_timer(CO_Data *, UNS32 t0); +void led_stop_timer(void); +void led_set_green(UNS8 on); +void led_set_red(UNS8 on); +void led_callback(CO_Data* d, UNS32 id); + + +// 0 = always off, 1 = always on, 2 = flashing +static UNS8 led_state_red, led_state_green; + +static UNS16 led_sequence_red, led_seq_index_red; +static UNS16 led_sequence_green, led_seq_index_green; + +static UNS8 led_error_code = LED_NO_ERROR; + +const char *led_sequence_table[6] = // up and downs of the sequence +{ + "01", // flickering + "01", // blinking + "100000", // single flash + "10100000", // double flash + "1010100000", // triple flash + "101010100000" // quadruple flash +}; + + +void led_set_state(CO_Data *d, int state) +{ + switch(state) + { + case Initialisation: +/* + must create a timer for the leds with the scheduler +*/ + break; + case LED_AUTOBITRATE: + led_state_green = 2; + led_sequence_green = 0; + break; + case Pre_operational: + led_state_green = 2; + led_sequence_green = 1; + break; + case Stopped: + led_state_green = 2; + led_sequence_green = 2; + break; + case LED_PRG_DOWNLOAD: + led_state_green = 2; + led_sequence_green = 4; + break; + case Operational: + led_state_green = 1; + break; + } + + if (state == LED_AUTOBITRATE) + led_start_timer(d, 50); + + else if (led_state_green < 2 && led_state_red < 2) + { + led_stop_timer(); + + led_set_green(led_state_green); + led_set_red(led_state_red); + } + + else + led_start_timer(d, 200); +} + + +void led_set_error(CO_Data *d, UNS8 error) +{ + if (error == LED_NO_ERROR) + { + led_error_code = error; + + led_state_green = 0; + } + + else if (error == LED_AUTOBITRATE) + { + led_error_code = error; + + led_state_red = 2; + led_sequence_red = 0; + + led_start_timer(d, 50); + } + + else if (error > led_error_code) + { + led_error_code = error; + + if (error & LED_INVALID_CONFIG) + { + led_state_red = 2; + led_sequence_red = 1; + } + + else if (error & LED_WARNING_LIMIT_REACH) + { + led_state_red = 2; + led_sequence_red = 2; + } + + else if (error & LED_ERROR_CTRL_EVENT) + { + led_state_red = 2; + led_sequence_red = 3; + } + + else if (error & LED_SYNC_ERROR) + { + led_state_red = 2; + led_sequence_red = 4; + } + + else if (error & LED_EVENT_TIMER_ERROR) + { + led_state_red = 2; + led_sequence_green = 5; + } + + else if (error & LED_BUS_OFF) + { + led_state_green = 1; + } + + led_start_timer(d, 200); + led_set_red(led_state_red); + } + + if (led_state_green < 2 && led_state_red < 2) + { + led_stop_timer(); + + led_set_green(led_state_green); + led_set_red(led_state_red); + } +} + + +void led_start_timer(CO_Data* d, UNS32 tm) +{ + SetAlarm(d, 0, &led_callback, MS_TO_TIMEVAL(tm), MS_TO_TIMEVAL(tm)); + + led_seq_index_red = 0; + led_seq_index_green = 0; +} + + +void led_stop_timer(void) +{ +} + + +void led_callback(CO_Data *d, UNS32 id) +{ + unsigned char bits = 0; + + // RED LED + if (led_sequence_table[led_sequence_red][led_seq_index_red] == '1') + { + if (led_state_red > 0) + bits = 1; + /* led_set_red(1); */ + } + else + { + /*if (led_state_red != 1) + led_set_red(0);*/ + } + + led_seq_index_red++; + if (led_seq_index_red > strlen(led_sequence_table[led_sequence_red])) + led_seq_index_red = 0; + + // GREEN LED + if (led_sequence_table[led_sequence_green][led_seq_index_green] == '1') + { + if (led_state_green > 0) + bits = bits | 2; + /* led_set_green(1); */ + } + else + { + /* if (led_state_green != 1) + led_set_green(0); */ + } + + led_seq_index_green++; + if (led_seq_index_green > strlen(led_sequence_table[led_sequence_green])) + led_seq_index_green = 0; + + led_set_redgreen(bits); +} + + + + + +/* +char state(state); + + +Input function to set all the bihaviour indicator +typical state are: + NoError + RedLED=off + AutoBitRate_LSS + RedLED=flickering + GreenLED=flickering + InvalidConfiguration + RedLED=blinking + WarningLimitReached + RedLED=singleflash + ErrorControlEvent + RedLED=doubleflash + SyncError + RedLED=tripleflash + EventTimerError + RedLED=quadrupleflash + BusOFF + RedLED=on + PRE_OPERATIONAL + GreenLED=blinking + STOPPED + GreenLED=singleflash + Programm_Firmware_download + GreenLED=tripleflash + OPERATIONNAL + GreenLED=on +*/ + +/* +case LEDbihaviour: + on + + flickeringerror + RedLED(on) + RedLED(off) + flickeringerror + GreenLED(off) + GreenLED(on) + blinking + + singleflash + + doubleflash + + tripleflash + + quadrupleflash + + off +*/ + +/* +char LED(bitLEDs); +*/ + +/* +Output function to call the driver. + if bit=0, then turn LED Off + if bit=1, then turn LED On + +bit# color name +0 red error/status +1 green run/status +2 +3 +4 +5 +6 +7 +*/ + diff -r 000000000000 -r 4472ee7c6c3e src/lifegrd.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lifegrd.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,160 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include "lifegrd.h" + +e_nodeState getNodeState (CO_Data* d, UNS8 nodeId) +{ + e_nodeState networkNodeState = d->NMTable[nodeId]; + return networkNodeState; +} + +// The Consumer Timer Callback +void ConsumerHearbeatAlarm(CO_Data* d, UNS32 id) +{ + //MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00); + + // call heartbeat error with NodeId + (*d->heartbeatError)((UNS8)( ((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16 )); +} + +/* Retourne le node-id */ +void proceedNODE_GUARD(CO_Data* d, Message* m ) +{ + UNS8 nodeId = (UNS8) GET_NODE_ID((*m)); + + if((m->rtr == 1) ) /* Notice that only the master can have sent this node guarding request */ + { // Receiving a NMT NodeGuarding (request of the state by the master) + // only answer to the NMT NodeGuarding request, the master is not checked (not implemented) + if (nodeId == *d->bDeviceNodeId ) + { + Message msg; + msg.cob_id.w = *d->bDeviceNodeId + 0x700; + msg.len = (UNS8)0x01; + msg.rtr = 0; + msg.data[0] = d->nodeState; + if (d->toggle) + { + msg.data[0] |= 0x80 ; + d->toggle = 0 ; + } + else + d->toggle = 1 ; + // send the nodeguard response. + MSG_WAR(0x3130, "Sending NMT Nodeguard to master, state: ", d->nodeState); + (*d->canSend)(&msg ); + } + + }else{ // Not a request CAN + + MSG_WAR(0x3110, "Received NMT nodeId : ", nodeId); + /* the slave's state receievd is stored in the NMTable */ + // The state is stored on 7 bit + d->NMTable[nodeId] = (e_nodeState) ((*m).data[0] & 0x7F) ; + + /* Boot-Up frame reception */ + if ( d->NMTable[nodeId] == Initialisation) + { + // The device send the boot-up message (Initialisation) + // to indicate the master that it is entered in pre_operational mode + // Because the device enter automaticaly in pre_operational mode, + // the pre_operational mode is stored +// NMTable[bus_id][nodeId] = Pre_operational; + MSG_WAR(0x3100, "The NMT is a bootup from node : ", nodeId); + } + + if( d->NMTable[nodeId] != Unknown_state ) { + UNS8 index, ConsummerHeartBeat_nodeId ; + for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ ) + { + ConsummerHeartBeat_nodeId = (UNS8)( ((d->ConsumerHeartbeatEntries[index]) & (UNS32)0x00FF0000) >> (UNS8)16 ); + if ( nodeId == ConsummerHeartBeat_nodeId ) + { + TIMEVAL time = ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ; + // Renew alarm for next heartbeat. + DelAlarm(d->ConsumerHeartBeatTimers[index]); + d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0); + } + } + } + } +} + +// The Consumer Timer Callback +void ProducerHearbeatAlarm(CO_Data* d, UNS32 id) +{ + if(*d->ProducerHeartBeatTime) + { + Message msg; + // Time expired, the heartbeat must be sent immediately + // generate the correct node-id: this is done by the offset 1792 + // (decimal) and additionaly + // the node-id of this device. + msg.cob_id.w = *d->bDeviceNodeId + 0x700; + msg.len = (UNS8)0x01; + msg.rtr = 0; + msg.data[0] = d->nodeState; // No toggle for heartbeat ! + // send the heartbeat + MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState); + (*d->canSend)(&msg ); + }else{ + d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer); + } +} + + +void heartbeatInit(CO_Data* d) +{ + UNS8 index; // Index to scan the table of heartbeat consumers + + d->toggle = 0; + + for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ ) + { + TIMEVAL time = (UNS16) ( (d->ConsumerHeartbeatEntries[index]) & (UNS32)0x0000FFFF ) ; + //MSG_WAR(0x3121, "should_time : ", should_time ) ; + if ( time ) + { + d->ConsumerHeartBeatTimers[index] = SetAlarm(d, index, &ConsumerHearbeatAlarm, MS_TO_TIMEVAL(time), 0); + } + } + + if ( *d->ProducerHeartBeatTime ) + { + TIMEVAL time = *d->ProducerHeartBeatTime; + d->ProducerHeartBeatTimer = SetAlarm(d, 0, &ProducerHearbeatAlarm, MS_TO_TIMEVAL(time), MS_TO_TIMEVAL(time)); + } +} + + +void heartbeatStop(CO_Data* d) +{ + UNS8 index; + for( index = (UNS8)0x00; index < *d->ConsumerHeartbeatCount; index++ ) + { + d->ConsumerHeartBeatTimers[index + 1] = DelAlarm(d->ConsumerHeartBeatTimers[index + 1]);; + } + + d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);; +} + diff -r 000000000000 -r 4472ee7c6c3e src/lss.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lss.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,740 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: CANopen Canada (canfestival@canopencanada.ca) + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include + +#include +#include +#include +#include +#include "can_driver.h" + +#ifdef LED_ENABLE +#include "led.h" +#else +#define led_set_state(a,b) +#endif + +#include "lss.h" + + + +/* + NOTES + + 1. since in the LSS protocol all LSS Slave use the same COB, only 1 Slave + must be allowed to communicate with the Master + + 2. the Master always take the iniative. the Slave is only allowed to transmit + within a confirmed service + + 3. requesting message (from the Master) using COB-ID 2021 and response messages + (from the Slave) using COB-ID 2020 +*/ + +/* + 0 = this slave is not talking to the master + 1 = this slave is talking to the master (this slave has been selected via ) +*/ +int slave_selector; + +int current_mode; + +int lss_table_selector, lss_table_index; + + +/* slave storing the information sent by the master */ +UNS32 lss_buffer[10]; +/* + how this buffer is used + + for a SLAVE + [0..3] used to store the LSS Address + [4..9] use by LSS Identify Remort Slave + + for the MASTER + [0..3] hold the answer from the slave regarding its ID +*/ + + +void lss_copy(UNS8 *data, UNS32 value) +/* transfert 32 bits value into uns8 data vector */ +{ + data[0] = value & 0xff; + data[1] = (value>>8) & 0xff; + data[2] = (value>>16) & 0xff; + data[3] = (value>>24) & 0xff; +} + + +UNS32 lss_get_value(UNS8 *data) +/* build a 'UNS32' value from a 'unsigned char' vector */ +{ + return data[0] + (data[1]<<8) + (data[2]<<16) + (data[3]<<24); +} + + +void lss_init_msg(Message *msg) +{ + msg->cob_id.w = 0; + msg->rtr = 0; + msg->len = 0; + msg->data[0] = 0; + msg->data[1] = 0; + msg->data[2] = 0; + msg->data[3] = 0; + msg->data[4] = 0; + msg->data[5] = 0; + msg->data[6] = 0; + msg->data[7] = 0; +} + + +void lss_SwitchModeGlobal(CO_Data *d, UNS32 mode) +/* + this service is used to switch all LSS slaves in the network between operation + mode and configuration mode. +*/ +{ + Message msg; + lss_init_msg(&msg); + + /* + sending a COB-ID 2021 + [0] = 4 (for switch mode global) + [1] = 0 for operation mode, = 1 for configuration mode + [2..7] = 0 reserved + */ + + if (!(d->iam_a_slave)) + { + msg.cob_id.w = 0x07E5 /* 2021 */; + + msg.len = 2; + msg.data[0] = 4; + msg.data[1] = (UNS8)mode; + + /* transmit */ + (*d->canSend)(&msg); + } + else + { + /* set mode global */ + current_mode = mode; + } +} + + +void lss_SwitchModeSelective_master(CO_Data *d, UNS32 *LSSaddr) +/* + LSS address : + vendor-id : provided by CiA + identical to the CANopen identity object + + select the slave corresponding to this ADDRESS +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (d->iam_a_slave) /* not the master */ + return; + + msg.cob_id.w = 0x07E5 /* 2021 */; + msg.len=5; + + msg.data[0] = 64; + lss_copy(msg.data+1, LSSaddr[0]); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 65; + lss_copy(msg.data+1, LSSaddr[1]); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 66; + lss_copy(msg.data+1, LSSaddr[2]); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 67; + lss_copy(msg.data+1, LSSaddr[3]); + /* transmit */ + (*d->canSend)(&msg); +} + + +UNS32 lss_validate_address(CO_Data* d) +{ +#if 0 + extern s_identity obj1018; + + /* maybe we should go throught getODentry but those + data are 1) RO and 2) the proper ID of this device */ +#else + UNS32 r, vendor_id, product_code, revision_number, serial_number; + UNS8 sz = sizeof(UNS32), dt = int32; + + r = getODentry(d, 0x1018, 1, (void *)&vendor_id, &sz, &dt, 0); + r = getODentry(d, 0x1018, 2, (void *)&product_code, &sz, &dt, 0); + r = getODentry(d, 0x1018, 3, (void *)&revision_number, &sz, &dt, 0); + r = getODentry(d, 0x1018, 4, (void *)&serial_number, &sz, &dt, 0); + +#endif + /* + if + lss_buffer[0] == vendor-id + lss_buffer[1] == product code + lss_buffer[2] == revision + lss_buffer[3] == serial + + then return 1 + else return 0; + */ + + if (lss_buffer[0] == vendor_id && + lss_buffer[1] == product_code && + lss_buffer[2] == revision_number && + lss_buffer[3] == serial_number) + { + return 1; + } + + return 0; +} + + +void lss_SwitchModeSelective_slave(CO_Data *d) +/* + SwitchModeSelective for the SLAVE + received the frames from the master and start building + the lss address +*/ +{ + Message msg; + lss_init_msg(&msg); + + /* + the master broadcast the address of a particular slave + for 64,65 and 66 store the partial address + when 67 arrive process the call and asknowledge if necessary + */ + + if (lss_validate_address(d)) + { + /* slave should transmit cob_id 2020 */ + msg.cob_id.w = 0x07E4 /* 2020 */; + + msg.len = 2; + msg.data[0] = 68; + msg.data[1] = (UNS8)current_mode; + + /* transmit */ + (*d->canSend)(&msg); + } + + /* reset the address */ + lss_buffer[0] = 0; + lss_buffer[1] = 0; + lss_buffer[2] = 0; + lss_buffer[3] = 0; +} + + +void lss_ConfigureNode_ID(CO_Data *d, UNS32 node_id) +/* + through this service the LSS Master configures the NMT-address + parameter of a LSS slave. +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (!(d->iam_a_slave)) + { + msg.cob_id.w = 0x07E5 /* 2021 */; + + msg.len = 2; + msg.data[0] = 17; + msg.data[1] = (UNS8)node_id; + + /* transmit */ + (*d->canSend)(&msg); + } + else + { + /* + receiving NODE ID from the master + */ + + /* + error code + 0 = success + 1 = node id out of range + 2..254 = reserved + 255 = implementation specific error occured + spec error = mode detailed error + */ + msg.cob_id.w = 0x07E4 /* 2020 */; + + msg.len = 3; + msg.data[0] = 17; + /* msg.data[1] = error code */ + /* msg.data[2] = spec error */ + + /* transmit */ + (*d->canSend)(&msg); + } +} + + +void lss_ConfigureBitTimingParameters(CO_Data *d, + UNS32 table_selector, + UNS32 table_index) +/* + this service allows all LSS slaves in configuration mode. + must be followed by an Activate Bit Timing Parameters +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (!(d->iam_a_slave)) + { + msg.cob_id.w = 0x07E5 /* 2021 */; + + msg.len = 3; + msg.data[0] = 19; + msg.data[1] = (UNS8)table_selector; + msg.data[2] = (UNS8)table_index; + + /* transmit */ + (*d->canSend)(&msg); + } + else + { + UNS8 error_code; + + /* validate if this baudrate is possible */ + if (table_selector == 0 && baudrate_valid(table_index) == 1) + { + lss_table_selector = table_selector; + lss_table_index = table_index; + } + else + error_code = 1; /* bit timing not supported */ + + msg.cob_id.w = 0x07E4 /* 2020 */; + + msg.len = 3; + msg.data[0] = 19; + msg.data[1] = error_code; + msg.data[2] = 0; + + /* transmit */ + (*d->canSend)(&msg); + } + + led_set_state(d, LED_AUTOBITRATE); +} + + +void lss_ActivateBitTimingParameters_master(CO_Data *d, unsigned short switch_delay) +/* + switch_delay in ms + + switch_delay has to be longer than the longest timeof any node + in the network to avoid that a node already switches while another + stills transmist the old bit timing parameters +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (d->iam_a_slave) + return; + + msg.cob_id.w = 0x07E5 /* 2021 */; + + msg.len = 3; + msg.data[0] = 21; + msg.data[1] = (UNS8)(switch_delay & 0xff); + msg.data[2] = (UNS8)((switch_delay >> 8) & 0xff); + +#ifdef LED_ENABLE + led_set_state(LED_AUTOBITRATE); +#endif + /* transmit */ + (*d->canSend)(&msg); +} + + +void lss_ActivateBitTimingParameters_slave(UNS8 byte_low, UNS8 byte_high) +{ + /* rebuild the delay value (short) from the 2 (UNS8) data */ + unsigned short switch_delay = byte_low + (((UNS16)byte_high)<<8); + + /* set the baudrate to the value proposed by the master */ + if (lss_table_selector == 0) + baudrate_set(lss_table_index); + + /* wait for switch_delay ms before continuing */ +} + + +void lss_StoreConfiguredParameters(CO_Data *d) +/* + store configured parameters into non-volatile storage +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (!(d->iam_a_slave)) + { + msg.cob_id.w = 0x07E5 /* 2021 */; + + msg.len = 1; + msg.data[0] = 23; + + /* transmit */ + (*d->canSend)(&msg); + } + else + { + msg.cob_id.w = 0x07E4 /* 2020 */; + + msg.data[0] = 23; + /* msg.data[1] = error code; */ + /* msg.data[2] = spec err */ + + /* transmit */ + (*d->canSend)(&msg); + } +} + + +void lss_InquireLSSAddress_master(CO_Data *d, int flag) +/* + this service allows to determine the LSS-address parameters of a LSS-slave in + configuration mode + + request 1 single item of the LSS address + 0 = request vendor-id + 1 = request product-id + 2 = request revision + 3 = request serial +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (!(d->iam_a_slave)) + { + msg.cob_id.w = 0x07E5 /* 2021 */; + + msg.len = 1; + msg.data[0] = 90 + flag; + + /* transmit */ + (*d->canSend)(&msg); + } +} + + +int lss_InquireLSSAddress_slave(CO_Data *d, int cs) +{ + Message msg; + lss_init_msg(&msg); + + if (!(d->iam_a_slave)) /* not a slave */ + return -1; + + UNS32 value = 0; + + switch(cs) + { + case 90: + value = 0; /* = vendor id */ + break; + case 91: + value = 0; /* = product code */ + break; + case 92: + value = 0; /* = revision */ + break; + case 93: + value = 0; /* = serial */ + break; + } + + if (value > 0) + { + msg.cob_id.w = 0x07E4 /* 2020 */; + + msg.len=5; + msg.data[0] = cs; + lss_copy(msg.data+1, value); + + /* transmit */ + (*d->canSend)(&msg); + + return 0; + } + + return -1; +} + + +void lss_IdentifyRemoteSlaves(CO_Data *d, + UNS32 vendor_id, + UNS32 product_code, + UNS32 rev_low, + UNS32 rev_high, + UNS32 serial_low, + UNS32 serial_high) +/* + throught this service, the LSS Master requests all LSS slave whose LSS address + meets the LSSaddr_sel to idenfity themselves through LSS Identify Slave +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (!(d->iam_a_slave)) + { + /* + request answers from all slaves corresponding + to the revision and serial range of values + */ + + msg.cob_id.w = 0x07E5 /* 2021 */; + msg.len=5; + + msg.data[0] = 70; + lss_copy(msg.data+1, vendor_id); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 71; + lss_copy(msg.data+1, product_code); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 72; /* revision number low */ + lss_copy(msg.data+1, rev_low); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 73; /* revision number high */ + lss_copy(msg.data+1, rev_high); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 74; /* serial number low */ + lss_copy(msg.data+1, serial_low); + /* transmit */ + (*d->canSend)(&msg); + + msg.data[0] = 75; /* serial number high */ + lss_copy(msg.data+1, serial_high); + /* transmit */ + (*d->canSend)(&msg); + } +} + + +int lss_validate_range_addr(CO_Data *d) +{ + /* + if + + lss_buffer[4] == vendor_id + lss_buffer[5] == product code + lss_buffer[6] <= revision <= lss_buffer[7] + lss_buffer[8] <= serial <= lss_buffer[9] + + then return 1 + else return 0 + */ + + UNS32 r, vendor_id, product_code, revision_number, serial_number; + UNS8 sz = sizeof(UNS32), dt = int32; + + r = getODentry(d, 0x1018, 1, (void *)&vendor_id, &sz, &dt, 0); + r = getODentry(d, 0x1018, 2, (void *)&product_code, &sz, &dt, 0); + r = getODentry(d, 0x1018, 3, (void *)&revision_number, &sz, &dt, 0); + r = getODentry(d, 0x1018, 4, (void *)&serial_number, &sz, &dt, 0); + + if (lss_buffer[4] == vendor_id && + lss_buffer[5] == product_code && + lss_buffer[6] <= revision_number && + revision_number <= lss_buffer[7] && + lss_buffer[8] <= serial_number && + serial_number <= lss_buffer[9]) + { + return 1; + } + + return 0; +} + + +void lss_IdentifySlave(CO_Data *d) +/* + through this service, an LSS slave indicates that it is a slave + with LSS address within the LSSaddr_sel +*/ +{ + Message msg; + lss_init_msg(&msg); + + if (lss_validate_range_addr(d)) + { + msg.cob_id.w = 0x07E4 /* 2020 */; + + msg.len = 1; + msg.data[0] = 79; + + /* transmit */ + (*d->canSend)(&msg); + } + + /* reset */ + lss_buffer[4] = 0; + lss_buffer[5] = 0; + lss_buffer[6] = 0; + lss_buffer[7] = 0; + lss_buffer[8] = 0; + lss_buffer[9] = 0; +} + + +int lss_process_msg(CO_Data *d, Message *msg) +{ + /* process the incoming message */ + if (msg->cob_id.w == 0x07E4 /* 2020 */) + { + // should be the master + // a slave just answered + switch(msg->data[0]) + { + /* slave acknowledging the SwitchModeSelective call */ + case 68: + /* msg->data[1] contains the 'mode global' value from the slave*/ + break; + + /* a slave had acknowledged the call from LSS Identify Remote Slave */ + case 79: + break; + + /* the slave acknowledged and sent the requested data */ + case 90: + lss_buffer[0] = lss_get_value(msg->data+1); + /* action ? */ + break; + case 91: + lss_buffer[1] = lss_get_value(msg->data+1); + /* action ? */ + break; + case 92: + lss_buffer[2] = lss_get_value(msg->data+1); + /* action ? */ + break; + case 93: + lss_buffer[3] = lss_get_value(msg->data+1); + /* action ? */ + break; + } + } + + else if (msg->cob_id.w == 0x07E5 /* 2021 */) + { + // should be a slave + // the master sent a request + switch(msg->data[0]) + { + case 4: + lss_SwitchModeGlobal(d, msg->data[1]); + break; + + case 17: + lss_ConfigureNode_ID(d, msg->data[1]); + break; + + case 19: + lss_ConfigureBitTimingParameters(d, msg->data[1], msg->data[2]); + break; + case 21: + lss_ActivateBitTimingParameters_slave(msg->data[1], msg->data[2]); + break; + + /* Switch Mode Selective */ + case 64: + lss_buffer[0] = lss_get_value(msg->data+1); + break; + case 65: + lss_buffer[1] = lss_get_value(msg->data+1); + break; + case 66: + lss_buffer[2] = lss_get_value(msg->data+1); + break; + case 67: + lss_buffer[3] = lss_get_value(msg->data+1); + lss_SwitchModeSelective_slave(d); + break; + + /* Identify Remote Slave */ + case 70: + lss_buffer[4] = lss_get_value(msg->data+1); + break; + case 71: + lss_buffer[5] = lss_get_value(msg->data+1); + break; + case 72: + lss_buffer[6] = lss_get_value(msg->data+1); + break; + case 73: + lss_buffer[7] = lss_get_value(msg->data+1); + break; + case 74: + lss_buffer[8] = lss_get_value(msg->data+1); + break; + case 75: + lss_buffer[9] = lss_get_value(msg->data+1); + lss_IdentifySlave(d); + break; + + /* Inquire Identify of Slave */ + case 90: + case 91: + case 92: + case 93: + lss_InquireLSSAddress_slave(d, msg->data[0]); + break; + } + } + + return 0; +} diff -r 000000000000 -r 4472ee7c6c3e src/nmtMaster.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nmtMaster.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,83 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "nmtMaster.h" + +/******************************************************************************/ +UNS8 masterSendNMTstateChange(CO_Data* d, UNS8 Node_ID, UNS8 cs) +{ + Message m; + + MSG_WAR(0x3501, "Send_NMT cs : ", cs); + MSG_WAR(0x3502, " to node : ", Node_ID); + /* message configuration */ + m.cob_id.w = 0x0000; /*(NMT) << 7*/ + m.rtr = NOT_A_REQUEST; + m.len = 2; + m.data[0] = cs; + m.data[1] = Node_ID; + + return (*d->canSend)(&m); +} + + +/****************************************************************************/ +UNS8 masterSendNMTnodeguard(CO_Data* d, UNS8 nodeId) +{ + Message m; + + MSG_WAR(0x3503, "Send_NODE_GUARD to node : ", nodeId); + + /* message configuration */ + m.cob_id.w = nodeId | (NODE_GUARD << 7); + m.rtr = REQUEST; + m.len = 1; + + return (*d->canSend)(&m); +} + +/******************************************************************************/ +void masterRequestNodeState(CO_Data* d, UNS8 nodeId) +{ + // FIXME: should warn for bad toggle bit. + + /* NMTable configuration to indicate that the master is waiting + * for a Node_Guard frame from the slave whose node_id is ID */ + d->NMTable[nodeId] = Unknown_state; // A state that does not exist + + if (nodeId == 0) { // NMT broadcast + UNS8 i = 0; + for (i = 0 ; i < NMT_MAX_NODE_ID ; i++) { + d->NMTable[i] = Unknown_state; + } + } + masterSendNMTnodeguard(d,nodeId); +} + + + + + + + + + diff -r 000000000000 -r 4472ee7c6c3e src/nmtSlave.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nmtSlave.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,89 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "nmtSlave.h" +#include "states.h" + +/*******************************************************************)*********/ +/* put the slave in the state wanted by the master */ +void proceedNMTstateChange(CO_Data* d, Message *m) +{ + if( d->nodeState == Pre_operational || + d->nodeState == Operational || + d->nodeState == Stopped ) { + + MSG_WAR(0x3400, "NMT received. for node : ", (*m).data[1]); + + // Check if this NMT-message is for this node + // byte 1 = 0 : all the nodes are concerned (broadcast) + + if( ( (*m).data[1] == 0 ) || ( (*m).data[1] == *d->bDeviceNodeId ) ){ + + switch( (*m).data[0]){ // command specifier (cs) + case NMT_Start_Node: + if ( (d->nodeState == Pre_operational) || (d->nodeState == Stopped) ) + setState(d,Operational); + break; + + case NMT_Stop_Node: + if ( d->nodeState == Pre_operational || + d->nodeState == Operational ) + setState(d,Stopped); + break; + + case NMT_Enter_PreOperational: + if ( d->nodeState == Operational || + d->nodeState == Stopped ) + setState(d,Pre_operational); + break; + + case NMT_Reset_Node: + setState(d,Initialisation); + break; + + case NMT_Reset_Comunication: + setState(d,Initialisation); + break; + + }// end switch + + }// end if( ( (*m).data[1] == 0 ) || ( (*m).data[1] == bDeviceNodeId ) ) + } +} + + +/*****************************************************************************/ +UNS8 slaveSendBootUp(CO_Data* d) +{ + Message m; + + MSG_WAR(0x3407, "Send a Boot-Up msg ", 0); + + /* message configuration */ + m.cob_id.w = NODE_GUARD << 7 | *d->bDeviceNodeId; + m.rtr = NOT_A_REQUEST; + m.len = 1; + m.data[0] = 0x00; + + return (*d->canSend)(&m); +} + diff -r 000000000000 -r 4472ee7c6c3e src/nvram.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nvram.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,109 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + + Author: CANopen Canada (canfestival@canopencanada.ca) + +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 +*/ +/* + nvram.c + + save the content of the dictionnary into non-volatile memory + the order of storage must be the same as the order of retrieving + + note (1) + may need to store/retrieve specific data from non-volatile + in that case, we need to address where it is stored + without storing the address in a vector + - solution 1 : walk throught the list without action until the + sought object is found. + +*/ + +#include +#include +#include +#include +#include "can_driver.h" + + +int canSaveData(indextable *dict, int max_index) +{ + int i, j; + + if (nvram_open() < 0) + return -1; + + subindex *pSubindex; + + for(i=0; i infinite loop if it fails. + UNS32 errorCode; + UNS8 szData; + const indextable *ptrTable; + ODCallback_t *Callback; + + ptrTable = (*d->scanIndexOD)(wIndex, &errorCode, &Callback); + + if (errorCode != OD_SUCCESSFUL) + return errorCode; + if( ptrTable->bSubCount <= bSubindex ) { + // Subindex not found + accessDictionaryError(wIndex, bSubindex, 0, 0, OD_NO_SUCH_SUBINDEX); + return OD_NO_SUCH_SUBINDEX; + } + + if (checkAccess && !(ptrTable->pSubindex[bSubindex].bAccessType & WO)) { + accessDictionaryError(wIndex, bSubindex, 0, 0, OD_WRITE_NOT_ALLOWED); + return OD_READ_NOT_ALLOWED; + } + + *pDataType = ptrTable->pSubindex[bSubindex].bDataType; + szData = ptrTable->pSubindex[bSubindex].size; + + if( *pExpectedSize == 0 || + *pExpectedSize == szData || + (*pDataType == visible_string && *pExpectedSize > szData)) // We allow to fetch a shorter string than expected + { + #ifdef CANOPEN_BIG_ENDIAN + { + // data must be transmited with low byte first + UNS8 i, j = 0; + for ( i = ptrTable->pSubindex[bSubindex].size - 1 ; i >= 0 ; i--) { + ((char*)pDestData)[j++] = ((char*)ptrTable->pSubindex[bSubindex].pObject)[i]; + } + } + #else + memcpy(pDestData, ptrTable->pSubindex[bSubindex].pObject,*pExpectedSize); + #endif + *pExpectedSize = szData; + return OD_SUCCESSFUL; + }else{ + *pExpectedSize = szData; + accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, OD_LENGTH_DATA_INVALID); + return OD_LENGTH_DATA_INVALID; + } +} + +UNS32 setODentry( CO_Data* d, + UNS16 wIndex, + UNS8 bSubindex, + void * pSourceData, + UNS8 * pExpectedSize, + UNS8 checkAccess) +{ + UNS8 szData; + UNS8 dataType; + UNS32 errorCode; + const indextable *ptrTable; + ODCallback_t *Callback; + + ptrTable =(*d->scanIndexOD)(wIndex, &errorCode, &Callback); + if (errorCode != OD_SUCCESSFUL) + return errorCode; + + if( ptrTable->bSubCount <= bSubindex ) { + // Subindex not found + accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_NO_SUCH_SUBINDEX); + return OD_NO_SUCH_SUBINDEX; + } + if (checkAccess && !(ptrTable->pSubindex[bSubindex].bAccessType & RO)) { + accessDictionaryError(wIndex, bSubindex, 0, *pExpectedSize, OD_WRITE_NOT_ALLOWED); + return OD_WRITE_NOT_ALLOWED; + } + + + dataType = ptrTable->pSubindex[bSubindex].bDataType; + szData = ptrTable->pSubindex[bSubindex].size; + + if( *pExpectedSize == 0 || + *pExpectedSize == szData || + (dataType == visible_string && *pExpectedSize < szData)) // We allow to store a shorter string than entry size + { + errorCode = (*d->valueRangeTest)(dataType, pSourceData); + if (errorCode) { + accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, errorCode); + return errorCode; + } + #ifdef CANOPEN_BIG_ENDIAN + { + // data must be transmited with low byte first + UNS8 i, j = 0; + for ( i = ptrTable->pSubindex[bSubindex].size - 1 ; i >= 0 ; i--) { + ((char*)ptrTable->pSubindex[bSubindex].pObject)[i] = ((char*)pSourceData)[j++]; + } + } + #else + memcpy(ptrTable->pSubindex[bSubindex].pObject,pSourceData, *pExpectedSize); + #endif + *pExpectedSize = szData; + + // Callbacks + if(Callback && Callback[bSubindex]){ + (*Callback[bSubindex])(d, ptrTable, bSubindex); + } + + // TODO : Store dans NVRAM + // if (ptrTable->pSubindex[bSubindex].bAccessType & TO_BE_SAVED) + return OD_SUCCESSFUL; + }else{ + *pExpectedSize = szData; + accessDictionaryError(wIndex, bSubindex, szData, *pExpectedSize, OD_LENGTH_DATA_INVALID); + return OD_LENGTH_DATA_INVALID; + } +} + + +const indextable * scanIndexOD (CO_Data* d, UNS16 wIndex, UNS32 *errorCode, ODCallback_t **Callback) +{ + return (*d->scanIndexOD)(wIndex, errorCode, Callback); +} + +UNS32 RegisterSetODentryCallBack(CO_Data* d, UNS16 wIndex, UNS8 bSubindex, ODCallback_t Callback) +{ + UNS32 errorCode; + ODCallback_t *CallbackList; + + scanIndexOD (d, wIndex, &errorCode, &CallbackList); + if(errorCode == OD_SUCCESSFUL && CallbackList) + CallbackList[bSubindex] = Callback; + return errorCode; +} + diff -r 000000000000 -r 4472ee7c6c3e src/pdo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pdo.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,453 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "pdo.h" +#include "objacces.h" + +/****************************************************************************/ +UNS8 sendPDO(CO_Data* d, s_PDO pdo, UNS8 req) +{ + UNS8 i; + if( d->nodeState == Operational ) { + Message m; + + /* Message copy for sending */ + m.cob_id.w = pdo.cobId & 0x7FF; // Because the cobId is 11 bytes length + if ( req == NOT_A_REQUEST ) { + UNS8 i; + m.rtr = NOT_A_REQUEST; + m.len = pdo.len; + //memcpy(&m.data, &pdo.data, m.len); + // This Memcpy depends on packing structure. Avoid + for (i = 0 ; i < pdo.len ; i++) + m.data[i] = pdo.data[i]; + } + else { + m.rtr = REQUEST; + m.len = 0; + } + + MSG_WAR(0x3901, "sendPDO cobId :", m.cob_id.w); + MSG_WAR(0x3902, " Nb octets : ", m.len); + for (i = 0 ; i < m.len ; i++) { + MSG_WAR(0x3903," data : ", m.data[i]); + } + + return (*d->canSend)(&m); + } // end if + return 0xFF; +} + +/***************************************************************************/ +UNS8 PDOmGR(CO_Data* d, UNS32 cobId) //PDO Manager +{ + UNS8 res; + UNS8 i; + s_PDO pdo; + + MSG_WAR(0x3905, "PDOmGR",0); + + /* if PDO is waiting for transmission, + preparation of the message to send */ + pdo.cobId = cobId; + pdo.len = d->process_var.count; + //memcpy(&(pdo.data), &(process_var.data), pdo.len); + // Ce memcpy devrait être portable + for ( i = 0 ; i < pdo.len ; i++) + pdo.data[i] = d->process_var.data[i]; + + res = sendPDO(d, pdo, NOT_A_REQUEST); + + return res; +} + +/**************************************************************************/ +UNS8 buildPDO(CO_Data* d, UNS16 index) +{ // DO NOT USE MSG_ERR because the macro may send a PDO -> infinite loop if it fails. + UNS16 ind; + UNS8 subInd; + + UNS8 * pMappingCount = NULL; // count of mapped objects... + // pointer to the var which is mapped to a pdo +// void * pMappedAppObject = NULL; + // pointer fo the var which holds the mapping parameter of an mapping entry + UNS32 * pMappingParameter = NULL; + + UNS8 Size; + UNS8 dataType; + UNS8 offset; + UNS16 offsetObjdict; + UNS16 offsetObjdictPrm; + UNS32 objDict; + + subInd=(UNS8)0x00; + offset = 0x00; + ind = index - 0x1800; + + MSG_WAR(0x3910,"Prepare PDO to send index :", index); + + /* only operational state allows PDO transmission */ + if( d->nodeState != Operational ) { + MSG_WAR(0x2911, "Unable to send the PDO (node not in OPERATIONAL mode). Node : ", index); + return 0xFF; + } + offsetObjdictPrm = d->firstIndex->PDO_TRS; + offsetObjdict = d->firstIndex->PDO_TRS_MAP; + + if (offsetObjdictPrm && offsetObjdict) + { + /* get mapped objects number to transmit with this PDO */ + pMappingCount = (d->objdict + offsetObjdict + ind)->pSubindex[0].pObject; + MSG_WAR(0x3912, "Nb maped objects : ",* pMappingCount); + MSG_WAR(0x3913, " at index : ", 0x1A00 + ind); + while (subInd < *pMappingCount) { // Loop on mapped variables + /* get mapping parameters */ + pMappingParameter = (d->objdict + offsetObjdict + ind)->pSubindex[subInd + 1].pObject; + MSG_WAR(0x3914, "Get the mapping at index : ", (UNS16)0x1A00 + ind); + MSG_WAR(0x3915, " subIndex : ", subInd + 1); + MSG_WAR(0x3916, " value : ", *(UNS32 *)pMappingParameter); + // Get the mapped variable + Size = ((UNS8)(((*pMappingParameter) & 0xFF) >> 3)); + objDict = getODentry(d, (UNS16)((*pMappingParameter) >> 16), + (UNS8)(((*pMappingParameter) >> 8 ) & 0x000000FF), + (void *)&d->process_var.data[offset], &Size, &dataType, 0 ); + + if (objDict != OD_SUCCESSFUL) { + MSG_WAR(0x2919, "error accessing to the mapped var : ", subInd + 1); + MSG_WAR(0x2920, " Mapped at index : ", (*pMappingParameter) >> 16); + MSG_WAR(0x2921, " subindex : "getODentry, ((*pMappingParameter) >> 8 ) & 0xFF); + return 0xFF; + } + + offset += Size; + d->process_var.count = offset; + subInd++; + }// end Loop on mapped variables + } + return 0; +} + +/**************************************************************************/ +UNS8 sendPDOrequest( CO_Data* d, UNS32 cobId ) +{ + UNS32 * pwCobId; + UNS16 offset; + UNS16 lastIndex; + UNS8 err; + + MSG_WAR(0x3930, "sendPDOrequest ",0); + // Sending the request only if the cobid have been found on the PDO receive + // part dictionary + offset = d->firstIndex->PDO_RCV; + lastIndex = d->lastIndex->PDO_RCV; + if (offset) + while (offset <= lastIndex) { + /*get the CobId*/ + pwCobId = d->objdict[offset].pSubindex[1].pObject; + + if ( *pwCobId == cobId ) { + s_PDO pdo; + pdo.cobId = *pwCobId; + pdo.len = 0; + err = sendPDO(d, pdo, REQUEST); + return err; + } + offset++; + } + MSG_WAR(0x1931, "sendPDOrequest : COBID not found : ", cobId); + return 0xFF; +} + + + +/***********************************************************************/ +UNS8 proceedPDO(CO_Data* d, Message *m) +{ + UNS8 numPdo; + UNS8 numMap; // Number of the mapped varable + UNS8 i; + UNS8 * pMappingCount = NULL; // count of mapped objects... + // pointer to the var which is mapped to a pdo... +// void * pMappedAppObject = NULL; + // pointer fo the var which holds the mapping parameter of an mapping entry + UNS32 * pMappingParameter = NULL; + UNS8 * pTransmissionType = NULL; // pointer to the transmission type + UNS32 * pwCobId = NULL; + UNS8 Size; + UNS8 dataType; + UNS8 offset; + UNS8 status; + UNS32 objDict; + UNS16 offsetObjdict; + UNS16 lastIndex; + status = state1; + + MSG_WAR(0x3935, "proceedPDO, cobID : ", ((*m).cob_id.w & 0x7ff)); + offset = 0x00; + numPdo = 0; + numMap = 0; + if((*m).rtr == NOT_A_REQUEST ) { // The PDO received is not a request. + offsetObjdict = d->firstIndex->PDO_RCV; + lastIndex = d->lastIndex->PDO_RCV; + + /* study of all the PDO stored in the dictionary */ + if(offsetObjdict) + while (offsetObjdict <= lastIndex) { + + switch( status ) { + + case state1: /* data are stored in process_var array */ + //memcpy(&(process_var.data), &m->data, (*m).len); + // Ce memcpy devrait être portable. + for ( i = 0 ; i < m->len ; i++) + d->process_var.data[i] = m->data[i]; + d->process_var.count = (*m).len; + + status = state2; + break; + + case state2: + /* get CobId of the dictionary correspondant to the received PDO */ + pwCobId = d->objdict[offsetObjdict].pSubindex[1].pObject; + /* check the CobId coherance */ + //*pwCobId is the cobId read in the dictionary at the state 3 + if ( *pwCobId == (*m).cob_id.w ){ + // The cobId is recognized + status = state4; + MSG_WAR(0x3936, "cobId found at index ", 0x1400 + numPdo); + break; + } + else { + // cobId received does not match with those write in the dictionnary + numPdo++; + offsetObjdict++; + status = state2; + break; + } + + case state4: /* get mapped objects number */ + // The cobId of the message received has been found in the dictionnary. + offsetObjdict = d->firstIndex->PDO_RCV_MAP; + lastIndex = d->lastIndex->PDO_RCV_MAP; + pMappingCount = (d->objdict + offsetObjdict + numPdo)->pSubindex[0].pObject; + numMap = 0; + while (numMap < *pMappingCount) { + pMappingParameter = (d->objdict + offsetObjdict + numPdo)->pSubindex[numMap + 1].pObject; + if (pMappingParameter == NULL) { + MSG_ERR(0x1937, "Couldn't get mapping parameter : ", numMap + 1); + return 0xFF; + } + // Get the addresse of the mapped variable. + // detail of *pMappingParameter : + // The 16 hight bits contains the index, the medium 8 bits contains the subindex, + // and the lower 8 bits contains the size of the mapped variable. + + Size = ((UNS8)(((*pMappingParameter) & 0xFF) >> 3)); + + objDict = setODentry(d, (UNS16)((*pMappingParameter) >> 16), + (UNS8)(((*pMappingParameter) >> 8 ) & 0xFF), + (void *)&d->process_var.data[offset], &Size, 0 ); + + if(objDict != OD_SUCCESSFUL) { + MSG_ERR(0x1938, "error accessing to the mapped var : ", numMap + 1); + MSG_WAR(0x2939, " Mapped at index : ", (*pMappingParameter) >> 16); + MSG_WAR(0x2940, " subindex : ", ((*pMappingParameter) >> 8 ) & 0xFF); + return 0xFF; + } + + MSG_WAR(0x3942, "Variable updated with value received by PDO cobid : ", m->cob_id.w); + MSG_WAR(0x3943, " Mapped at index : ", (*pMappingParameter) >> 16); + MSG_WAR(0x3944, " subindex : ", ((*pMappingParameter) >> 8 ) & 0xFF); +// MSG_WAR(0x3945, " data : ",*((UNS32 *)pMappedAppObject)); + offset += Size; + numMap++; + } // end loop while on mapped variables + + offset=0x00; + numMap = 0; + return 0; + + }// end switch status + }// end while + }// end if Donnees + + + else if ((*m).rtr == REQUEST ){ + MSG_WAR(0x3946, "Receive a PDO request cobId : ", m->cob_id.w); + status = state1; + offsetObjdict = d->firstIndex->PDO_TRS; + lastIndex = d->lastIndex->PDO_TRS; + if(offsetObjdict) while( offsetObjdict <= lastIndex ){ + /* study of all PDO stored in the objects dictionary */ + + switch( status ){ + + case state1: /* check the CobId */ + /* get CobId of the dictionary which match to the received PDO */ + pwCobId = (d->objdict + offsetObjdict)->pSubindex[1].pObject; + if ( *pwCobId == (*m).cob_id.w ) { + status = state4; + break; + } + else { + numPdo++; + offsetObjdict++; + } + status = state1; + break; + + + case state4: /* check transmission type (after request?) */ + pTransmissionType = d->objdict[offsetObjdict].pSubindex[2].pObject; + if ( (*pTransmissionType == TRANS_RTR) || (*pTransmissionType == TRANS_RTR_SYNC ) || (*pTransmissionType == TRANS_EVENT) ) { + status = state5; + break; + } + else { + // The requested PDO is not to send on request. So, does nothing. + MSG_WAR(0x2947, "PDO is not to send on request : ", m->cob_id.w); + return 0xFF; + } + + case state5: /* get mapped objects number */ + offsetObjdict = d->firstIndex->PDO_TRS_MAP; + lastIndex = d->lastIndex->PDO_TRS_MAP; + pMappingCount = (d->objdict + offsetObjdict + numPdo)->pSubindex[0].pObject; + numMap = 0; + while (numMap < *pMappingCount) { + pMappingParameter = (d->objdict + offsetObjdict + numPdo)->pSubindex[numMap + 1].pObject; + // Get the mapped variable + Size = ((UNS8)(((*pMappingParameter) & 0xFF) >> 3)); + objDict = getODentry( d, (UNS16)((*pMappingParameter) >> (UNS8)16), + (UNS8)(( (*pMappingParameter) >> (UNS8)8 ) & 0xFF), + (void *)&d->process_var.data[offset], &Size, &dataType, 0 ); + if (objDict != OD_SUCCESSFUL) { + MSG_ERR(0x1948, "error accessing to the mapped var : ", numMap + 1); + MSG_WAR(0x2949, " Mapped at index : ", (*pMappingParameter) >> 16); + MSG_WAR(0x2950, " subindex : ", ((*pMappingParameter) >> 8 ) & 0xFF); + return 0xFF; + } + offset += (UNS8) (((*pMappingParameter) & 0xFF) >> 3); + d->process_var.count = offset; + numMap++; + + } // end while + PDOmGR( d, *pwCobId ); // Transmit the PDO + return 0; + + }// end switch status + }// end while + }// end if Requete + + return 0; +} + + + + +/*********************************************************************/ +/* TODO : reimplement this using CallBacks */ +/*********************************************************************/ +/* +UNS8 sendPDOevent( CO_Data* d, void * variable ) +{ // DO NOT USE MSG_ERR because the macro may send a PDO -> infinite loop if it fails. + UNS32 objDict = 0; + UNS8 ind, sub_ind; + UNS8 status; + UNS8 offset; + UNS8 * pMappingCount = NULL; + UNS32 * pMappingParameter = NULL; + void * pMappedAppObject = NULL; + UNS8 * pTransmissionType = NULL; // pointer to the transmission type + UNS32 * pwCobId = NULL; + UNS8 * pSize; + UNS8 size; + UNS8 dataType; + UNS16 offsetObjdict; + UNS16 offsetObjdictPrm; + UNS16 lastIndex; + UNS8 numMap; + ind = 0x00; + sub_ind = 1; + offset = 0x00; + pSize = &size; + status = state1; + + // look for the index and subindex where the variable is mapped + // Then, send the pdo which contains the variable. + + MSG_WAR (0x3960, "sendPDOevent", 0); + offsetObjdictPrm = d->firstIndex->PDO_TRS; + + offsetObjdict = d->firstIndex->PDO_TRS_MAP; + lastIndex = d->lastIndex->PDO_TRS_MAP; + + if (offsetObjdictPrm && offsetObjdict) + // Loop on PDO Transmit + while(offsetObjdict <= lastIndex){ + // Check the transmission mode + pTransmissionType = d->objdict[offsetObjdictPrm].pSubindex[2].pObject; + if (*pTransmissionType != TRANS_EVENT) { + ind++; + offsetObjdict++; + offsetObjdictPrm++; + continue; + } + pMappingCount = d->objdict[offsetObjdict].pSubindex[0].pObject; + numMap = 1; // mapped variable + while (numMap <= *pMappingCount) { + pMappingParameter = d->objdict[offsetObjdict].pSubindex[numMap].pObject; + // Get the variable + objDict = getODentry( d, + (UNS16)((*pMappingParameter) >> 16), + (UNS8)(( (*pMappingParameter) >> (UNS8)8 ) & (UNS32)0x000000FF), + (void * *)&pMappedAppObject, pSize, &dataType, 0 ); + if( objDict != OD_SUCCESSFUL ) { + MSG_WAR(0x2961, "Error in dict. at index : ", + (*pMappingParameter) >> (UNS8)16); + + MSG_WAR(0x2962, " subindex : ", + ((*pMappingParameter) >> (UNS8)8 ) & (UNS32)0x000000FF); + return 0xFF; + } + if (pMappedAppObject == variable) { // Variable found ! + MSG_WAR(0x3963, "Variable to send found at index : ", + (*pMappingParameter) >> 16); + MSG_WAR(0x3964, " subIndex : ", + ((*pMappingParameter) >> 8 ) & 0x000000FF); + buildPDO(d, 0x1800 + ind); + // Get the cobId + pwCobId = d->objdict[offsetObjdictPrm].pSubindex[1].pObject; + PDOmGR( d, *pwCobId ); // Send the PDO + return 0; + } + numMap++; + } // End loop on mapped variable + ind++; + offsetObjdict++; + offsetObjdictPrm++; + } // End loop while on PDO + + MSG_WAR(0x2965, "Variable not found in a PDO to send on event", 0); + return 0xFF; + +} +*/ diff -r 000000000000 -r 4472ee7c6c3e src/sdo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sdo.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,1277 @@ +/* +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 +*/ + +//#define DEBUG_WAR_CONSOLE_ON +//#define DEBUG_ERR_CONSOLE_ON + +#include "objacces.h" +#include "sdo.h" + +/***************************************************************************/ +// SDO (un)packing macros + +/** Returns the command specifier (cs, ccs, scs) from the first byte of the SDO + */ +#define getSDOcs(byte) (byte >> 5) + +/** Returns the number of bytes without data from the first byte of the SDO. Coded in 2 bits + */ +#define getSDOn2(byte) ((byte >> 2) & 3) + +/** Returns the number of bytes without data from the first byte of the SDO. Coded in 3 bits + */ +#define getSDOn3(byte) ((byte >> 1) & 7) + +/** Returns the transfer type from the first byte of the SDO + */ +#define getSDOe(byte) ((byte >> 1) & 1) + +/** Returns the size indicator from the first byte of the SDO + */ +#define getSDOs(byte) (byte & 1) + +/** Returns the indicator of end transmission from the first byte of the SDO + */ +#define getSDOc(byte) (byte & 1) + +/** Returns the toggle from the first byte of the SDO + */ +#define getSDOt(byte) ((byte >> 4) & 1) + +/** Returns the index from the bytes 1 and 2 of the SDO + */ +#define getSDOindex(byte1, byte2) ((byte2 << 8) | (byte1)) + +/** Returns the subIndex from the byte 3 of the SDO + */ +#define getSDOsubIndex(byte3) (byte3) + +/*************************************************************************** +** +*/ +void SDOTimeoutAlarm(CO_Data* d, UNS32 id) +{ + MSG_ERR(0x1A01, "SDO timeout. SDO response not received.", 0); + MSG_WAR(0x2A02, "server node : ", d->transfers[id].nodeId); + MSG_WAR(0x2A02, " index : ", d->transfers[id].index); + MSG_WAR(0x2A02, " subIndex : ", d->transfers[id].subIndex); + // Reset timer handler + d->transfers[id].timer = TIMER_NONE; + // Call the user function to inform of the problem. + (*d->SDOtimeoutError)(id); + // Sending a SDO abort + sendSDOabort(d, d->transfers[id].whoami, + d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT); + // Reset the line + resetSDOline(d, id); +} + +#define StopSDO_TIMER(id) \ +MSG_WAR(0x3A05, "StopSDO_TIMER for line : ", line);\ +d->transfers[id].timer = DelAlarm(d->transfers[id].timer); + +#define StartSDO_TIMER(id) \ +MSG_WAR(0x3A06, "StartSDO_TIMER for line : ", line);\ +d->transfers[id].timer = SetAlarm(d,id,&SDOTimeoutAlarm,MS_TO_TIMEVAL(SDO_TIMEOUT_MS),0); + +#define RestartSDO_TIMER(id) \ +MSG_WAR(0x3A07, "restartSDO_TIMER for line : ", line);\ +if(d->transfers[id].timer != TIMER_NONE) { StopSDO_TIMER(id) StartSDO_TIMER(id) } + +/***************************************************************************/ +/** Reset all sdo buffers + */ +void resetSDO (CO_Data* d) +{ + UNS8 j; + + /* transfer structure initialization */ + for (j = 0 ; j < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; j++) + resetSDOline(d, j); +} + +/***************************************************************************/ +UNS32 SDOlineToObjdict (CO_Data* d, UNS8 line) +{ + const indextable *ptrTable; + UNS8 i; + UNS8 size; + UNS32 errorCode; + size = d->transfers[line].count; + errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex, + (void *) d->transfers[line].data, &size, 1); + if (errorCode != OD_SUCCESSFUL) + return errorCode; + + return 0; + +} + +/***************************************************************************/ +UNS32 objdictToSDOline (CO_Data* d, UNS8 line) +{ + UNS8 j; +// UNS8 *data; + UNS8 size = 0; + UNS8 dataType; + UNS32 errorCode; + + MSG_WAR(0x3A05, "Reading at index : ", d->transfers[line].index); + MSG_WAR(0x3A06, "Reading at subIndex : ", d->transfers[line].subIndex); + + errorCode = getODentry(d, d->transfers[line].index, + d->transfers[line].subIndex, + (void *)d->transfers[line].data, + &size, &dataType, 0); + + if (errorCode != OD_SUCCESSFUL) + return errorCode; + + d->transfers[line].count = size; + d->transfers[line].offset = 0; + return 0; +} + +/***************************************************************************/ +UNS8 lineToSDO (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data) { + UNS8 i; + UNS8 offset; + + if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) { + MSG_ERR(0x1A10,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes); + return 0xFF; + } + if ((d->transfers[line].offset + nbBytes) > d->transfers[line].count) { + MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes); + return 0xFF; + } + offset = d->transfers[line].offset; + for (i = 0 ; i < nbBytes ; i++) + * (data + i) = d->transfers[line].data[offset + i]; + d->transfers[line].offset = d->transfers[line].offset + nbBytes; + return 0; +} + + +/***************************************************************************/ +UNS8 SDOtoLine (CO_Data* d, UNS8 line, UNS8 nbBytes, UNS8* data) +{ + UNS8 i; + UNS8 offset; + + if ((d->transfers[line].offset + nbBytes) > SDO_MAX_LENGTH_TRANSFERT) { + MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes); + return 0xFF; + } + offset = d->transfers[line].offset; + for (i = 0 ; i < nbBytes ; i++) + d->transfers[line].data[offset + i] = * (data + i); + d->transfers[line].offset = d->transfers[line].offset + nbBytes; + return 0; +} + +/***************************************************************************/ +UNS8 failedSDO (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS16 index, + UNS8 subIndex, UNS32 abortCode) +{ + UNS8 err; + UNS8 line; + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (!err) + MSG_WAR(0x3A20, "FailedSDO : line found : ", line); + if ((! err) && (whoami == SDO_SERVER)) { + resetSDOline( d, line ); + MSG_WAR(0x3A21, "FailedSDO : line released : ", line); + } + if ((! err) && (whoami == SDO_CLIENT)) + StopSDO_TIMER(line) + d->transfers[line].state = SDO_ABORTED_INTERNAL; + MSG_WAR(0x3A22, "Sending SDO abort ", 0); + err = sendSDOabort(d, whoami, index, subIndex, abortCode); + if (err) { + MSG_WAR(0x3A23, "Unable to send the SDO abort", 0); + return 0xFF; + } + return 0; +} + +/***************************************************************************/ +void resetSDOline ( CO_Data* d, UNS8 line ) +{ + UNS8 i; + + initSDOline(d, line, 0, 0, 0, SDO_RESET); + for (i = 0 ; i < SDO_MAX_LENGTH_TRANSFERT ; i++) + d->transfers[line].data[i] = 0; +} + +/***************************************************************************/ +UNS8 initSDOline (CO_Data* d, UNS8 line, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 state) +{ + if (state == SDO_DOWNLOAD_IN_PROGRESS || state == SDO_UPLOAD_IN_PROGRESS){ + StartSDO_TIMER(line) + }else{ + StopSDO_TIMER(line) + } + d->transfers[line].nodeId = nodeId; + d->transfers[line].index = index; + d->transfers[line].subIndex = subIndex; + d->transfers[line].state = state; + d->transfers[line].toggle = 0; + d->transfers[line].count = 0; + d->transfers[line].offset = 0; + d->transfers[line].dataType = 0; + return 0; +} + +/***************************************************************************/ +UNS8 getSDOfreeLine ( CO_Data* d, UNS8 whoami, UNS8 *line ) +{ + + UNS8 i; + + for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){ + if ( d->transfers[i].state == SDO_RESET ) { + *line = i; + d->transfers[i].whoami = whoami; + return 0; + } // end if + } // end for + MSG_ERR(0x1A25, "Too many SDO in progress. Aborted.", i); + return 0xFF; +} + +/***************************************************************************/ +UNS8 getSDOlineOnUse (CO_Data* d, UNS8 nodeId, UNS8 whoami, UNS8 *line) +{ + + UNS8 i; + + for (i = 0 ; i < SDO_MAX_SIMULTANEOUS_TRANSFERTS ; i++){ + if ( (d->transfers[i].state != SDO_RESET) && + (d->transfers[i].nodeId == nodeId) && + (d->transfers[i].whoami == whoami) ) { + *line = i; + return 0; + } + } + return 0xFF; +} + +/***************************************************************************/ +UNS8 closeSDOtransfer (CO_Data* d, UNS8 nodeId, UNS8 whoami) +{ + UNS8 err; + UNS8 line; + err = getSDOlineOnUse(d, nodeId, whoami, &line); + if (err) { + MSG_WAR(0x2A30, "No SDO communication to close for node : ", nodeId); + return 0xFF; + } + resetSDOline(d, line); + return 0; +} + +/***************************************************************************/ +UNS8 getSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 * nbBytes) +{ + if (d->transfers[line].count == 0) // if received initiate SDO protocol with e=0 and s=0 + * nbBytes = 0; + else + * nbBytes = d->transfers[line].count - d->transfers[line].offset; + return 0; +} + +/***************************************************************************/ +UNS8 setSDOlineRestBytes (CO_Data* d, UNS8 line, UNS8 nbBytes) +{ + if (nbBytes > SDO_MAX_LENGTH_TRANSFERT) { + MSG_ERR(0x1A35,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes); + return 0xFF; + } + d->transfers[line].count = nbBytes; + return 0; +} + + +/***************************************************************************/ +UNS8 sendSDO (CO_Data* d, UNS8 whoami, s_SDO sdo) +{ + UNS16 offset; + UNS16 lastIndex; + UNS8 found = 0; + Message m; + UNS8 i; + UNS32 * pwCobId = NULL; + UNS8 * pwNodeId = NULL; + UNS8 * pSize; + UNS8 size; + pSize = &size; + + MSG_WAR(0x3A38, "sendSDO",0); + if( !((d->nodeState == Operational) || (d->nodeState == Pre_operational ))) { + MSG_WAR(0x2A39, "unable to send the SDO (not in op or pre-op mode", d->nodeState); + return 0xFF; + } + + /*get the server->client cobid*/ + if ( whoami == SDO_SERVER ) {/*case server. Easy because today only one server SDO is authorized in CanFestival*/ + offset = d->firstIndex->SDO_SVR; + if (offset == 0) { + MSG_ERR(0x1A42, "SendSDO : No SDO server found", 0); + return 0xFF; + } + pwCobId = d->objdict[offset].pSubindex[2].pObject; + MSG_WAR(0x3A41, "I am server. cobId : ", *pwCobId); + } + else { /*case client*/ + /* Get the client->server cobid.*/ + UNS16 sdoNum = 0; + offset = d->firstIndex->SDO_CLT; + lastIndex = d->lastIndex->SDO_CLT; + if (offset == 0) { + MSG_ERR(0x1A42, "SendSDO : No SDO client index found", 0); + return 0xFF; + } + /* First, have to find at the index where is defined the communication with the server node */ + while (offset <= lastIndex){ + MSG_WAR(0x3A43,"Reading index : ", 0x1280 + sdoNum); + if (d->objdict[offset].bSubCount <= 3) { + MSG_ERR(0x1A28, "Subindex 3 not found at index ", 0x1280 + sdoNum); + return 0xFF; + } + pwNodeId = d->objdict[offset].pSubindex[3].pObject; + MSG_WAR(0x3A44, "Found nodeId server = ", *pwNodeId); + if(*pwNodeId == sdo.nodeId) { + found = 1; + break; + } + offset ++; + sdoNum ++; + } + if (! found){ + MSG_WAR (0x2A45, "No SDO client corresponds to the mesage to send to node ", sdo.nodeId); + return 0xFF; + } + /* Second, read the cobid client->server */ + pwCobId = d->objdict[offset].pSubindex[1].pObject; + } + /* message copy for sending */ + m.cob_id.w = *pwCobId; + m.rtr = NOT_A_REQUEST; + //the length of SDO must be 8 + m.len = 8; + for (i = 0 ; i < 8 ; i++) { + m.data[i] = sdo.body.data[i]; + } + return (*d->canSend)(&m); +} + +/***************************************************************************/ +UNS8 sendSDOabort (CO_Data* d, UNS8 whoami, UNS16 index, UNS8 subIndex, UNS32 abortCode) +{ + s_SDO sdo; + UNS8 ret; + MSG_WAR(0x2A50,"Sending SDO abort", abortCode); + sdo.nodeId = *d->bDeviceNodeId; + sdo.body.data[0] = 0x80; + // Index + sdo.body.data[1] = index & 0xFF; // LSB + sdo.body.data[2] = (index >> 8) & 0xFF; // MSB + // Subindex + sdo.body.data[3] = subIndex; + // Data + sdo.body.data[4] = (UNS8)(abortCode & 0xFF); + sdo.body.data[5] = (UNS8)((abortCode >> 8) & 0xFF); + sdo.body.data[6] = (UNS8)((abortCode >> 16) & 0xFF); + sdo.body.data[7] = (UNS8)((abortCode >> 24) & 0xFF); + ret = sendSDO(d, whoami, sdo); + + return ret; +} + +/***************************************************************************/ +UNS8 proceedSDO (CO_Data* d, Message *m) +{ + UNS8 err; + UNS8 line; + UNS8 nbBytes; // received or to be transmited. + UNS8 nodeId = 0; // The node from which the SDO is received + UNS8 *pNodeId = NULL; + UNS8 whoami = SDO_UNKNOWN; // SDO_SERVER or SDO_CLIENT. + UNS32 errorCode; // while reading or writing in the local object dictionary. + s_SDO sdo; // SDO to transmit + UNS16 index; + UNS8 subIndex; + UNS32 abortCode; + UNS8 i,j; + UNS32 * pCobId = NULL; + UNS8 * pSize; + UNS8 size; + UNS16 offset; + UNS16 lastIndex; + + pSize = &size; + + MSG_WAR(0x3A60, "proceedSDO ", 0); + whoami = SDO_UNKNOWN; + // Looking for the cobId in the object dictionary. + // Am-I a server ? + offset = d->firstIndex->SDO_SVR; + lastIndex = d->lastIndex->SDO_SVR; + j = 0; + if(offset) while (offset <= lastIndex) { + if (d->objdict[offset].bSubCount <= 1) { + MSG_ERR(0x1A61, "Subindex 1 not found at index ", 0x1200 + j); + return 0xFF; + } + pCobId = d->objdict[offset].pSubindex[1].pObject; + if ( *pCobId == (*m).cob_id.w ) { + whoami = SDO_SERVER; + MSG_WAR(0x3A62, "proceedSDO. I am server. index : ", 0x1200 + j); + // In case of server, the node id of the client may be unknown. So we put the index minus offset + // 0x1200 where the cobid received is defined. + nodeId = j; + break; + } + j++; + offset++; + } // end while + if (whoami == SDO_UNKNOWN) { + // Am-I client ? + offset = d->firstIndex->SDO_CLT; + lastIndex = d->lastIndex->SDO_CLT; + j = 0; + if(offset) while (offset <= lastIndex) { + if (d->objdict[offset].bSubCount <= 3) { + MSG_ERR(0x1A63, "Subindex 3 not found at index ", 0x1280 + j); + return 0xFF; + } + // a) Looking for the cobid received. + pCobId = d->objdict[offset].pSubindex[2].pObject; + if (*pCobId == (*m).cob_id.w ) { + // b) cobid found, so reading the node id of the server. + pNodeId = d->objdict[offset].pSubindex[3].pObject; + whoami = SDO_CLIENT; + nodeId = *pNodeId; + MSG_WAR(0x3A64, "proceedSDO. I am server. index : ", 0x1280 + j); + MSG_WAR(0x3A65, " Server nodeId : ", nodeId); + break; + } + j++; + offset++; + } // end while + } + if (whoami == SDO_UNKNOWN) { + return 0xFF;// This SDO was not for us ! + } + + // Test if the size of the SDO is ok + if ( (*m).len != 8) { + MSG_ERR(0x1A67, "Error size SDO. CobId : ", (*m).cob_id.w); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_GENERAL_ERROR); + return 0xFF; + } + + if (whoami == SDO_CLIENT) { + MSG_WAR(0x3A68, "I am CLIENT. Received SDO from nodeId : ", nodeId); + } + else { + MSG_WAR(0x3A69, "I am SERVER. Received SDO cobId : ", (*m).cob_id.w); + } + + // Testing the command specifier + // Allowed : cs = 0, 1, 2, 3, 4. (= all except those for block tranfert). + // cs = other : Not allowed -> abort. + switch (getSDOcs(m->data[0])) { + + case 0: + // I am SERVER + if (whoami == SDO_SERVER) { + // Receiving a download segment data. + // A SDO transfert should have been yet initiated. + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (!err) + err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS; + if (err) { + MSG_ERR(0x1A70, "SDO error : Received download segment for unstarted trans. index 0x1200 + ", + nodeId); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // Reset the wathdog + RestartSDO_TIMER(line) + MSG_WAR(0x3A71, "Received SDO download segment defined at index 0x1200 + ", nodeId); + index = d->transfers[line].index; + subIndex = d->transfers[line].subIndex; + // Toggle test. + if (d->transfers[line].toggle != getSDOt(m->data[0])) { + MSG_ERR(0x1A72, "SDO error : Toggle error : ", getSDOt(m->data[0])); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED); + return 0xFF; + } + // Nb of data to be downloaded + nbBytes = 7 - getSDOn3(m->data[0]); + // Store the data in the transfert structure. + err = SDOtoLine(d, line, nbBytes, (*m).data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + // Sending the SDO response, CS = 1 + sdo.nodeId = *d->bDeviceNodeId; // The node id of the server, (here it is the sender). + sdo.body.data[0] = (1 << 5) | (d->transfers[line].toggle << 4); + for (i = 1 ; i < 8 ; i++) + sdo.body.data[i] = 0; + MSG_WAR(0x3A73, "SDO. Send response to download request defined at index 0x1200 + ", nodeId); + sendSDO(d, whoami, sdo); + // Inverting the toggle for the next segment. + d->transfers[line].toggle = ! d->transfers[line].toggle & 1; + // If it was the last segment, + if (getSDOc(m->data[0])) { + // Transfering line data to object dictionary. + // The code does not use the "d" of initiate frame. So it is safe if e=s=0 + errorCode = SDOlineToObjdict(d, line); + if (errorCode) { + MSG_ERR(0x1A54, "SDO error : Unable to copy the data in the object dictionary", 0); + failedSDO(d, nodeId, whoami, index, subIndex, errorCode); + return 0xFF; + } + // Release of the line + resetSDOline(d, line); + MSG_WAR(0x3A74, "SDO. End of download defined at index 0x1200 + ", nodeId); + } + } // end if SERVER + else { // if CLIENT + // I am CLIENT + // It is a request for a previous upload segment. We should find a line opened for this. + err = getSDOlineOnUse( d, nodeId, whoami, &line); + if (!err) + err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS; + if (err) { + MSG_ERR(0x1A75, "SDO error : Received segment response for unknown trans. from nodeId", nodeId); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // Reset the wathdog + RestartSDO_TIMER(line) + index = d->transfers[line].index; + subIndex = d->transfers[line].subIndex; + // test of the toggle; + if (d->transfers[line].toggle != getSDOt(m->data[0])) { + MSG_ERR(0x1A76, "SDO error : Received segment response Toggle error. from nodeId", nodeId); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED); + return 0xFF; + } + // nb of data to be uploaded + nbBytes = 7 - getSDOn3(m->data[0]); + // Storing the data in the line structure. + err = SDOtoLine(d, line, nbBytes, (*m).data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + // Inverting the toggle for the next segment. + d->transfers[line].toggle = ! d->transfers[line].toggle & 1; + // If it was the last segment, + if ( getSDOc(m->data[0])) { + // Put in state finished + // The code is safe for the case e=s=0 in initiate frame. + StopSDO_TIMER(line) + d->transfers[line].state = SDO_FINISHED; + MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId); + } + else { // more segments to receive + // Sending the request for the next segment. + sdo.nodeId = nodeId; + sdo.body.data[0] = (3 << 5) | (d->transfers[line].toggle << 4); + for (i = 1 ; i < 8 ; i++) + sdo.body.data[i] = 0; + sendSDO(d, whoami, sdo); + MSG_WAR(0x3A78, "SDO send upload segment request to nodeId", nodeId); + } + } // End if CLIENT + break; + + case 1: + // I am SERVER + // Receive of an initiate download + if (whoami == SDO_SERVER) { + index = getSDOindex(m->data[1],m->data[2]); + subIndex = getSDOsubIndex(m->data[3]); + MSG_WAR(0x3A79, "Received SDO Initiate Download (to store data) defined at index 0x1200 + ", + nodeId); + MSG_WAR(0x3A80, "Writing at index : ", index); + MSG_WAR(0x3A80, "Writing at subIndex : ", subIndex); + + // Search if a SDO transfert have been yet initiated + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (! err) { + MSG_ERR(0x1A81, "SDO error : Transmission yet started.", 0); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // No line on use. Great ! + // Try to open a new line. + err = getSDOfreeLine( d, whoami, &line ); + if (err) { + MSG_ERR(0x1A82, "SDO error : No line free, too many SDO in progress. Aborted.", 0); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS); + + if (getSDOe(m->data[0])) { // If SDO expedited + // nb of data to be downloaded + nbBytes = 4 - getSDOn2(m->data[0]); + // Storing the data in the line structure. + d->transfers[line].count = nbBytes; + err = SDOtoLine(d, line, nbBytes, (*m).data + 4); + + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + + // SDO expedited -> transfert finished. Data can be stored in the dictionary. + // The line will be reseted when it is downloading in the dictionary. + MSG_WAR(0x3A83, "SDO Initiate Download is an expedited transfert. Finished.: ", nodeId); + // Transfering line data to object dictionary. + errorCode = SDOlineToObjdict(d, line); + if (errorCode) { + MSG_ERR(0x1A84, "SDO error : Unable to copy the data in the object dictionary", 0); + failedSDO(d, nodeId, whoami, index, subIndex, errorCode); + return 0xFF; + } + // Release of the line. + resetSDOline(d, line); + } + else {// So, if it is not an expedited transfert + if (getSDOs(m->data[0])) { + // TODO : if e and s = 0, not reading m->data[4] but put nbBytes = 0 + nbBytes = m->data[4]; // Transfert limited to 255 bytes. + err = setSDOlineRestBytes(d, nodeId, nbBytes); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + } + } + //Sending a SDO, cs=3 + sdo.nodeId = *d->bDeviceNodeId; // The node id of the server, (here it is the sender). + sdo.body.data[0] = 3 << 5; + sdo.body.data[1] = index & 0xFF; // LSB + sdo.body.data[2] = (index >> 8) & 0xFF; // MSB + sdo.body.data[3] = subIndex; + for (i = 4 ; i < 8 ; i++) + sdo.body.data[i] = 0; + sendSDO(d, whoami, sdo); + } // end if I am SERVER + else { + // I am CLIENT + // It is a response for a previous download segment. We should find a line opened for this. + err = getSDOlineOnUse( d, nodeId, whoami, &line); + if (!err) + err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS; + if (err) { + MSG_ERR(0x1A85, "SDO error : Received segment response for unknown trans. from nodeId", nodeId); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // Reset the wathdog + RestartSDO_TIMER(line) + index = d->transfers[line].index; + subIndex = d->transfers[line].subIndex; + // test of the toggle; + if (d->transfers[line].toggle != getSDOt(m->data[0])) { + MSG_ERR(0x1A86, "SDO error : Received segment response Toggle error. from nodeId", nodeId); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED); + return 0xFF; + } + + // End transmission or downloading next segment. We need to know if it will be the last one. + getSDOlineRestBytes(d, line, &nbBytes); + if (nbBytes == 0) { + MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId); + StopSDO_TIMER(line) + d->transfers[line].state = SDO_FINISHED; + return 0x00; + } + // At least one transfer to send. + if (nbBytes > 7) { + // several segments to download. + // code to send the next segment. (cs = 0; c = 0) + d->transfers[line].toggle = ! d->transfers[line].toggle & 1; + sdo.nodeId = nodeId; // The server node Id; + sdo.body.data[0] = (d->transfers[line].toggle << 4); + err = lineToSDO(d, line, 7, sdo.body.data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + } + else { + // Last segment. + // code to send the last segment. (cs = 0; c = 1) + d->transfers[line].toggle = ! d->transfers[line].toggle & 1; + sdo.nodeId = nodeId; // The server node Id; + sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1; + err = lineToSDO(d, line, nbBytes, sdo.body.data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + for (i = nbBytes + 1 ; i < 8 ; i++) + sdo.body.data[i] = 0; + } + MSG_WAR(0x3A88, "SDO sending download segment to nodeId", nodeId); + sendSDO(d, whoami, sdo); + } // end if I am a CLIENT + break; + + case 2: + // I am SERVER + // Receive of an initiate upload. + if (whoami == SDO_SERVER) { + index = getSDOindex(m->data[1],m->data[2]); + subIndex = getSDOsubIndex(m->data[3]); + MSG_WAR(0x3A89, "Received SDO Initiate upload (to send data) defined at index 0x1200 + ", + nodeId); + MSG_WAR(0x3A90, "Reading at index : ", index); + MSG_WAR(0x3A91, "Reading at subIndex : ", subIndex); + // Search if a SDO transfert have been yet initiated + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (! err) { + MSG_ERR(0x1A92, "SDO error : Transmission yet started at line : ", line); + MSG_WAR(0x3A93, "nodeId = ", nodeId); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // No line on use. Great ! + // Try to open a new line. + err = getSDOfreeLine( d, whoami, &line ); + if (err) { + MSG_ERR(0x1A71, "SDO error : No line free, too many SDO in progress. Aborted.", 0); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS); + // Transfer data from dictionary to the line structure. + errorCode = objdictToSDOline(d, line); + + if (errorCode) { + MSG_ERR(0x1A94, "SDO error : Unable to copy the data from object dictionary. Err code : ", + errorCode); + failedSDO(d, nodeId, whoami, index, subIndex, errorCode); + return 0xFF; + } + // Preparing the response. + getSDOlineRestBytes(d, line, &nbBytes); // Nb bytes to transfer ? + sdo.nodeId = nodeId; // The server node Id; + if (nbBytes > 4) { + // normal transfert. (segmented). + // code to send the initiate upload response. (cs = 2) + sdo.body.data[0] = (2 << 5) | 1; + sdo.body.data[1] = index & 0xFF; // LSB + sdo.body.data[2] = (index >> 8) & 0xFF; // MSB + sdo.body.data[3] = subIndex; + sdo.body.data[4] = nbBytes; // Limitation of canfestival2 : Max tranfert is 256 bytes. + // It takes too much memory to upgrate to 2^32 because the size of data is also coded + // in the object dictionary, at every index and subindex. + for (i = 5 ; i < 8 ; i++) + sdo.body.data[i] = 0; + MSG_WAR(0x3A95, "SDO. Sending normal upload initiate response defined at index 0x1200 + ", nodeId); + sendSDO(d, whoami, sdo); + } + else { + // Expedited upload. (cs = 2 ; e = 1) + sdo.body.data[0] = (2 << 5) | ((4 - nbBytes) << 2) | 3; + sdo.body.data[1] = index & 0xFF; // LSB + sdo.body.data[2] = (index >> 8) & 0xFF; // MSB + sdo.body.data[3] = subIndex; + err = lineToSDO(d, line, nbBytes, sdo.body.data + 4); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + for (i = 4 + nbBytes ; i < 8 ; i++) + sdo.body.data[i] = 0; + MSG_WAR(0x3A96, "SDO. Sending expedited upload initiate response defined at index 0x1200 + ", + nodeId); + sendSDO(d, whoami, sdo); + // Release the line. + resetSDOline(d, line); + } + } // end if I am SERVER + else { + // I am CLIENT + // It is the response for the previous initiate upload request. + // We should find a line opened for this. + err = getSDOlineOnUse( d, nodeId, whoami, &line); + if (!err) + err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS; + if (err) { + MSG_ERR(0x1A97, "SDO error : Received response for unknown upload request from nodeId", nodeId); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // Reset the wathdog + RestartSDO_TIMER(line) + index = d->transfers[line].index; + subIndex = d->transfers[line].subIndex; + + if (getSDOe(m->data[0])) { // If SDO expedited + // nb of data to be uploaded + nbBytes = 4 - getSDOn2(m->data[0]); + // Storing the data in the line structure. + err = SDOtoLine(d, line, nbBytes, (*m).data + 4); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + // SDO expedited -> transfert finished. data are available via getReadResultNetworkDict(). + MSG_WAR(0x3A98, "SDO expedited upload finished. Response received from node : ", nodeId); + StopSDO_TIMER(line) + d->transfers[line].count = nbBytes; + d->transfers[line].state = SDO_FINISHED; + return 0; + } + else { // So, if it is not an expedited transfert + // Storing the nb of data to receive. + if (getSDOs(m->data[0])) { + nbBytes = m->data[4]; // Remember the limitation to 255 bytes to transfert + err = setSDOlineRestBytes(d, line, nbBytes); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + } + // Requesting next segment. (cs = 3) + sdo.nodeId = nodeId; + sdo.body.data[0] = 3 << 5; + for (i = 1 ; i < 8 ; i++) + sdo.body.data[i] = 0; + MSG_WAR(0x3A99, "SDO. Sending upload segment request to node : ", nodeId); + sendSDO(d, whoami, sdo); + } + } // End if CLIENT + break; + + case 3: + // I am SERVER + if (whoami == SDO_SERVER) { + // Receiving a upload segment. + // A SDO transfert should have been yet initiated. + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (!err) + err = d->transfers[line].state != SDO_UPLOAD_IN_PROGRESS; + if (err) { + MSG_ERR(0x1AA0, "SDO error : Received upload segment for unstarted trans. index 0x1200 + ", + nodeId); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // Reset the wathdog + RestartSDO_TIMER(line) + MSG_WAR(0x3AA1, "Received SDO upload segment defined at index 0x1200 + ", nodeId); + index = d->transfers[line].index; + subIndex = d->transfers[line].subIndex; + // Toggle test. + if (d->transfers[line].toggle != getSDOt(m->data[0])) { + MSG_ERR(0x1AA2, "SDO error : Toggle error : ", getSDOt(m->data[0])); + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_TOGGLE_NOT_ALTERNED); + return 0xFF; + } + // Uploading next segment. We need to know if it will be the last one. + getSDOlineRestBytes(d, line, &nbBytes); + if (nbBytes > 7) { + // The segment to transfer is not the last one. + // code to send the next segment. (cs = 0; c = 0) + sdo.nodeId = nodeId; // The server node Id; + sdo.body.data[0] = (d->transfers[line].toggle << 4); + err = lineToSDO(d, line, 7, sdo.body.data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + // Inverting the toggle for the next tranfert. + d->transfers[line].toggle = ! d->transfers[line].toggle & 1; + MSG_WAR(0x3AA3, "SDO. Sending upload segment defined at index 0x1200 + ", nodeId); + sendSDO(d, whoami, sdo); + } + else { + // Last segment. + // code to send the last segment. (cs = 0; c = 1) + sdo.nodeId = nodeId; // The server node Id; + sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1; + err = lineToSDO(d, line, nbBytes, sdo.body.data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + for (i = nbBytes + 1 ; i < 8 ; i++) + sdo.body.data[i] = 0; + MSG_WAR(0x3AA4, "SDO. Sending last upload segment defined at index 0x1200 + ", nodeId); + sendSDO(d, whoami, sdo); + // Release the line + resetSDOline(d, line); + } + } // end if SERVER + else { + // I am CLIENT + // It is the response for the previous initiate download request. + // We should find a line opened for this. + err = getSDOlineOnUse( d, nodeId, whoami, &line); + if (!err) + err = d->transfers[line].state != SDO_DOWNLOAD_IN_PROGRESS; + if (err) { + MSG_ERR(0x1AA5, "SDO error : Received response for unknown download request from nodeId", nodeId); + failedSDO(d, nodeId, whoami, 0, 0, SDOABT_LOCAL_CTRL_ERROR); + return 0xFF; + } + // Reset the wathdog + RestartSDO_TIMER(line) + index = d->transfers[line].index; + subIndex = d->transfers[line].subIndex; + // End transmission or requesting next segment. + getSDOlineRestBytes(d, line, &nbBytes); + if (nbBytes == 0) { + MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId); + StopSDO_TIMER(line) + d->transfers[line].state = SDO_FINISHED; + return 0x00; + } + if (nbBytes > 7) { + // more than one request to send + // code to send the next segment. (cs = 0; c = 0) + sdo.nodeId = nodeId; // The server node Id; + sdo.body.data[0] = (d->transfers[line].toggle << 4); + err = lineToSDO(d, line, 7, sdo.body.data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + } + else { + // Last segment. + // code to send the last segment. (cs = 0; c = 1) + sdo.nodeId = nodeId; // The server node Id; + sdo.body.data[0] = (d->transfers[line].toggle << 4) | ((7 - nbBytes) << 1) | 1; + err = lineToSDO(d, line, nbBytes, sdo.body.data + 1); + if (err) { + failedSDO(d, nodeId, whoami, index, subIndex, SDOABT_GENERAL_ERROR); + return 0xFF; + } + for (i = nbBytes + 1 ; i < 8 ; i++) + sdo.body.data[i] = 0; + } + MSG_WAR(0x3AA7, "SDO sending download segment to nodeId", nodeId); + sendSDO(d, whoami, sdo); + + } // end if I am a CLIENT + break; + + case 4: + abortCode = (*m).data[3] | + (m->data[5] << 8) | + (m->data[6] << 16) | + (m->data[7] << 24); + // Received SDO abort. + // Looking for the line concerned. + if (whoami == SDO_SERVER) { + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (!err) { + resetSDOline( d, line ); + MSG_WAR(0x3AA8, "SD0. Received SDO abort. Line released. Code : ", abortCode); + } + else + MSG_WAR(0x3AA9, "SD0. Received SDO abort. No line found. Code : ", abortCode); + // Tips : The end user has no way to know that the server node has received an abort SDO. + // Its is ok, I think. + } + else { // If I am CLIENT + err = getSDOlineOnUse( d, nodeId, whoami, &line ); + if (!err) { + // The line *must* be released by the core program. + StopSDO_TIMER(line) + d->transfers[line].state = SDO_ABORTED_RCV; + MSG_WAR(0x3AB0, "SD0. Received SDO abort. Line state ABORTED. Code : ", abortCode); + } + else + MSG_WAR(0x3AB1, "SD0. Received SDO abort. No line found. Code : ", abortCode); + } + break; + default: + // Error : Unknown cs + MSG_ERR(0x1AB2, "SDO. Received unknown command specifier : ", getSDOcs(m->data[0])); + return 0xFF; + + } // End switch + return 0; +} + +/*******************************************************************)******/ +UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, + UNS8 subIndex, UNS8 count, UNS8 dataType, void *data) +{ + UNS8 err; + UNS8 SDOfound = 0; + UNS8 line; + s_SDO sdo; // SDO to transmit + UNS8 i, j; + UNS8 * pSize; + UNS8 size; + UNS16 lastIndex; + UNS16 offset; + UNS8 *pNodeIdServer; + UNS8 nodeIdServer; + pSize = &size; + + MSG_WAR(0x3AC0, "Send SDO to write in the dictionary of node : ", nodeId); + MSG_WAR(0x3AC1, " At index : ", index); + MSG_WAR(0x3AC2, " subIndex : ", subIndex); + MSG_WAR(0x3AC3, " nb bytes : ", count); + + // Verify that there is no SDO communication yet. + err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line); + if (!err) { + MSG_ERR(0x1AC4, "SDO error : Communication yet established. with node : ", nodeId); + return 0xFF; + } + // Taking the line ... + err = getSDOfreeLine( d, SDO_CLIENT, &line ); + if (err) { + MSG_ERR(0x1AC5, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId); + return (0xFF); + } + // Check which SDO to use to communicate with the node + offset = d->firstIndex->SDO_CLT; + lastIndex = d->lastIndex->SDO_CLT; + if (offset == 0) { + MSG_ERR(0x1AC6, "writeNetworkDict : No SDO client index found", 0); + return 0xFF; + } + i = 0; + while (offset <= lastIndex) { + if (d->objdict[offset].bSubCount <= 3) { + MSG_ERR(0x1AC8, "Subindex 3 not found at index ", 0x1280 + i); + return 0xFF; + } + // looking for the nodeId server + pNodeIdServer = d->objdict[offset].pSubindex[3].pObject; + nodeIdServer = *pNodeIdServer; + MSG_WAR(0x1AD2, "index : ", 0x1280 + i); + MSG_WAR(0x1AD3, "nodeIdServer : ", nodeIdServer); + + if(nodeIdServer == nodeId) { + SDOfound = 1; + break; + } + offset++; + i++; + } // end while + if (!SDOfound) { + MSG_ERR(0x1AC9, "SDO. Error. No client found to communicate with node : ", nodeId); + return 0xFF; + } + MSG_WAR(0x3AD0," SDO client defined at index : ", 0x1280 + i); + initSDOline(d, line, nodeId, index, subIndex, SDO_DOWNLOAD_IN_PROGRESS); + d->transfers[line].count = count; + d->transfers[line].dataType = dataType; + + // Copy data to transfers structure. + for (j = 0 ; j < count ; j++) { +# ifdef CANOPEN_BIG_ENDIAN + if (dataType == 0) + d->transfers[line].data[count - 1 - j] = ((char *)data)[j]; + else // String of bytes. + d->transfers[line].data[j] = ((char *)data)[j]; +# else + d->transfers[line].data[j] = ((char *)data)[j]; +# endif + } + // Send the SDO to the server. Initiate download, cs=1. + sdo.nodeId = nodeId; + if (count <= 4) { // Expedited transfert + sdo.body.data[0] = (1 << 5) | ((4 - count) << 2) | 3; + for (i = 4 ; i < 8 ; i++) + sdo.body.data[i] = d->transfers[line].data[i - 4]; + d->transfers[line].offset = count; + } + else { // Normal transfert + sdo.body.data[0] = (1 << 5) | 1; + sdo.body.data[4] = count; // nb of byte to transmit. Max = 255. (canfestival2 limitation). + for (i = 5 ; i < 8 ; i++) + sdo.body.data[i] = 0; + } + sdo.body.data[1] = index & 0xFF; // LSB + sdo.body.data[2] = (index >> 8) & 0xFF; // MSB + sdo.body.data[3] = subIndex; + + err = sendSDO(d, SDO_CLIENT, sdo); + if (err) { + MSG_ERR(0x1AD1, "SDO. Error while sending SDO to node : ", nodeId); + // release the line + resetSDOline(d, line); + return 0xFF; + } + return 0; +} + + + +/***************************************************************************/ +UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType) +{ + UNS8 err; + UNS8 SDOfound = 0; + UNS8 i; + UNS8 line; + UNS8 * pSize; + UNS8 size; + s_SDO sdo; // SDO to transmit + UNS8 *pNodeIdServer; + UNS8 nodeIdServer; + UNS16 offset; + UNS16 lastIndex; + pSize = &size; + MSG_WAR(0x3AD5, "Send SDO to read in the dictionary of node : ", nodeId); + MSG_WAR(0x3AD6, " At index : ", index); + MSG_WAR(0x3AD7, " subIndex : ", subIndex); + + + // Verify that there is no SDO communication yet. + err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line); + if (!err) { + MSG_ERR(0x1AD8, "SDO error : Communication yet established. with node : ", nodeId); + return 0xFF; + } + // Taking the line ... + err = getSDOfreeLine( d, SDO_CLIENT, &line ); + if (err) { + MSG_ERR(0x1AD9, "SDO error : No line free, too many SDO in progress. Aborted for node : ", nodeId); + return (0xFF); + } + else + MSG_WAR(0x3AE0, "Transmission on line : ", line); + + // Check which SDO to use to communicate with the node + offset = d->firstIndex->SDO_CLT; + lastIndex = d->lastIndex->SDO_CLT; + if (offset == 0) { + MSG_ERR(0x1AE1, "writeNetworkDict : No SDO client index found", 0); + return 0xFF; + } + i = 0; + while (offset <= lastIndex) { + if (d->objdict[offset].bSubCount <= 3) { + MSG_ERR(0x1AE2, "Subindex 3 not found at index ", 0x1280 + i); + return 0xFF; + } + // looking for the nodeId server + pNodeIdServer = d->objdict[offset].pSubindex[3].pObject; + nodeIdServer = *pNodeIdServer; + + if(nodeIdServer == nodeId) { + SDOfound = 1; + break; + } + offset++; + i++; + } // end while + if (!SDOfound) { + MSG_ERR(0x1AE3, "SDO. Error. No client found to communicate with node : ", nodeId); + return 0xFF; + } + MSG_WAR(0x3AE4," SDO client defined at index : ", 0x1280 + i); + initSDOline(d, line, nodeId, index, subIndex, SDO_UPLOAD_IN_PROGRESS); + getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line); + sdo.nodeId = nodeId; + // Send the SDO to the server. Initiate upload, cs=2. + d->transfers[line].dataType = dataType; + sdo.body.data[0] = (2 << 5); + sdo.body.data[1] = index & 0xFF; // LSB + sdo.body.data[2] = (index >> 8) & 0xFF; // MSB + sdo.body.data[3] = subIndex; + for (i = 4 ; i < 8 ; i++) + sdo.body.data[i] = 0; + err = sendSDO(d, SDO_CLIENT, sdo); + if (err) { + MSG_ERR(0x1AE5, "SDO. Error while sending SDO to node : ", nodeId); + // release the line + resetSDOline(d, line); + return 0xFF; + } + return 0; +} + +/***************************************************************************/ + +UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size, + UNS32 * abortCode) +{ + UNS8 i; + UNS8 err; + UNS8 line; + * size = 0; + + // Looking for the line tranfert. + err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line); + if (err) { + MSG_ERR(0x1AF0, "SDO error : No line found for communication with node : ", nodeId); + return SDO_ABORTED_INTERNAL; + } + if (d->transfers[line].state != SDO_FINISHED) + return d->transfers[line].state; + + // Transfert is finished. Put the value in the data. + * size = d->transfers[line].count; + for ( i = 0 ; i < *size ; i++) { +# ifdef CANOPEN_BIG_ENDIAN + if (d->transfers[line].dataType != visible_string) + ( (char *) data)[*size - 1 - i] = d->transfers[line].data[i]; + else // String of bytes. + ( (char *) data)[i] = d->transfers[line].data[i]; +# else + ( (char *) data)[i] = d->transfers[line].data[i]; +# endif + } + return SDO_FINISHED; +} + +/***************************************************************************/ + +UNS8 getWriteResultNetworkDict (CO_Data* d, UNS8 nodeId, UNS32 * abortCode) +{ + UNS8 line = 0; + UNS8 err; + + * abortCode = 0; + // Looking for the line tranfert. + err = getSDOlineOnUse(d, nodeId, SDO_CLIENT, &line); + if (err) { + MSG_ERR(0x1AF1, "SDO error : No line found for communication with node : ", nodeId); + return SDO_ABORTED_INTERNAL; + } + * abortCode = d->transfers[line].abortCode; + return d->transfers[line].state; +} diff -r 000000000000 -r 4472ee7c6c3e src/states.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/states.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,238 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "states.h" +#include "def.h" + +#include "nmtSlave.h" + +#ifdef LED_ENABLE +#include "led.h" +#else +#define led_set_state(a,b) +#endif + + +e_nodeState getState(CO_Data* d) +{ + return d->nodeState; +} + +void canDispatch(CO_Data* d, Message *m) +{ + switch(m->cob_id.w >> 7) + { + case SYNC: + if(d->CurrentCommunicationState.csSYNC) + proceedSYNC(d,m); + break; + //case TIME_STAMP: + case PDO1tx: + case PDO1rx: + case PDO2tx: + case PDO2rx: + case PDO3tx: + case PDO3rx: + case PDO4tx: + case PDO4rx: + if (d->CurrentCommunicationState.csPDO) + proceedPDO(d,m); + break; + case SDOtx: + case SDOrx: + if (d->CurrentCommunicationState.csSDO) + proceedSDO(d,m); + break; + case NODE_GUARD: + if (d->CurrentCommunicationState.csHeartbeat) + proceedNODE_GUARD(d,m); + break; + case NMT: + if (d->iam_a_slave) + { + proceedNMTstateChange(d,m); + } +#ifdef CANOPEN_LSS_ENABLE + default: + if (m->cob_id.w == 0x7E4 || m->cob_id.w == 0x705) + { + proceedLSS(d,m); + } +#endif + } +} + +#define StartOrStop(CommType, FuncStart, FuncStop) \ + if(newCommunicationState->CommType && !d->CurrentCommunicationState.CommType){\ + MSG_ERR(0x9999,#FuncStart, 9999);\ + d->CurrentCommunicationState.CommType = 1;\ + FuncStart;\ + }else if(!newCommunicationState->CommType && d->CurrentCommunicationState.CommType){\ + MSG_ERR(0x9999,#FuncStop, 9999);\ + d->CurrentCommunicationState.CommType = 0;\ + FuncStop;\ + } +#define None + +void switchCommunicationState(CO_Data* d, s_state_communication *newCommunicationState) +{ + StartOrStop(csBoot_Up, None, slaveSendBootUp(d)) + StartOrStop(csSDO, None, resetSDO(d)) + StartOrStop(csSYNC, startSYNC(d), stopSYNC(d)) + StartOrStop(csHeartbeat, heartbeatInit(d), heartbeatStop(d)) +// StartOrStop(Emergency,,) + StartOrStop(csPDO, None, None) +} + +UNS8 setState(CO_Data* d, e_nodeState newState) +{ + while(newState != d->nodeState){ + switch( newState ){ + case Initialisation: + { + s_state_communication newCommunicationState = { + csBoot_Up: 1, + csSDO: 0, + csEmergency: 0, + csSYNC: 0, + csHeartbeat: 0, + csPDO: 0}; + // This will force a second loop for the state switch + d->nodeState = Initialisation; + newState = Pre_operational; + switchCommunicationState(d, &newCommunicationState); + // call user app related state func. + (*d->initialisation)(); + } + break; + + case Pre_operational: + { + s_state_communication newCommunicationState = { + csBoot_Up: 0, + csSDO: 1, + csEmergency: 1, + csSYNC: 1, + csHeartbeat: 1, + csPDO: 0}; + d->nodeState = Pre_operational; + newState = Pre_operational; + switchCommunicationState(d, &newCommunicationState); + (*d->preOperational)(); + } + break; + + case Operational: + if(d->nodeState == Initialisation) return 0xFF; + { + s_state_communication newCommunicationState = { + csBoot_Up: 0, + csSDO: 1, + csEmergency: 1, + csSYNC: 1, + csHeartbeat: 1, + csPDO: 1}; + d->nodeState = Operational; + newState = Operational; + switchCommunicationState(d, &newCommunicationState); + (*d->operational)(); + } + break; + + case Stopped: + if(d->nodeState == Initialisation) return 0xFF; + { + s_state_communication newCommunicationState = { + csBoot_Up: 0, + csSDO: 0, + csEmergency: 0, + csSYNC: 0, + csHeartbeat: 1, + csPDO: 0}; + d->nodeState = Stopped; + newState = Stopped; + switchCommunicationState(d, &newCommunicationState); + (*d->stopped)(); + } + break; + + default: + return 0xFF; + }//end switch case + + led_set_state(d, newState); + } + return 0; +} + +UNS8 getNodeId(CO_Data* d) +{ + return *d->bDeviceNodeId; +} + +void setNodeId(CO_Data* d, UNS8 nodeId) +{ + UNS16 offset = d->firstIndex->SDO_SVR; + if(offset){ + //cob_id_client = 0x600 + nodeId; + *(UNS32*)d->objdict[offset].pSubindex[1].pObject = 0x600 + nodeId; + //cob_id_server = 0x580 + nodeId; + *(UNS32*)d->objdict[offset].pSubindex[2].pObject = 0x580 + nodeId; + // node Id client. As we do not know the value, we put the node Id Server + //*(UNS8*)d->objdict[offset].pSubindex[3].pObject = nodeId; + } + + // ** Initialize the server(s) SDO parameters + // Remember that only one SDO server is allowed, defined at index 0x1200 + + // ** Initialize the client(s) SDO parameters + // Nothing to initialize (no default values required by the DS 401) + // ** Initialize the receive PDO communication parameters. Only for 0x1400 to 0x1403 + { + UNS8 i = 0; + UNS16 offset = d->firstIndex->PDO_RCV; + UNS16 lastIndex = d->lastIndex->PDO_RCV; + UNS32 cobID[] = {0x200, 0x300, 0x400, 0x500}; + if( offset ) while( (offset <= lastIndex) && (i < 4)) { + if(*(UNS32*)d->objdict[offset].pSubindex[1].pObject == cobID[i] + *d->bDeviceNodeId) + *(UNS32*)d->objdict[offset].pSubindex[1].pObject = cobID[i] + nodeId; + i ++; + offset ++; + } + } + // ** Initialize the transmit PDO communication parameters. Only for 0x1800 to 0x1803 + { + UNS8 i = 0; + UNS16 offset = d->firstIndex->PDO_TRS; + UNS16 lastIndex = d->lastIndex->PDO_TRS; + UNS32 cobID[] = {0x180, 0x280, 0x380, 0x480}; + i = 0; + if( offset ) while ((offset <= lastIndex) && (i < 4)) { + if(*(UNS32*)d->objdict[offset].pSubindex[1].pObject == cobID[i] + *d->bDeviceNodeId) + *(UNS32*)d->objdict[offset].pSubindex[1].pObject = cobID[i] + nodeId; + i ++; + offset ++; + } + } + // bDeviceNodeId is defined in the object dictionary. + *d->bDeviceNodeId = nodeId; +} diff -r 000000000000 -r 4472ee7c6c3e src/sync.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sync.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,228 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "data.h" +#include "sync.h" + +void SyncAlarm(CO_Data* d, UNS32 id) +{ + sendSYNC(d, *d->COB_ID_Sync & 0x1FFFFFFF) ; +} + +// This is called when Index 0x1005 is updated. +UNS32 OnCOB_ID_SyncUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) +{ + startSYNC(d); +} + +void startSYNC(CO_Data* d) +{ + RegisterSetODentryCallBack(d, 0x1005, 0, &OnCOB_ID_SyncUpdate); + RegisterSetODentryCallBack(d, 0x1006, 0, &OnCOB_ID_SyncUpdate); + + if(d->syncTimer != TIMER_NONE){ + stopSYNC(d); + } + + if(*d->COB_ID_Sync & 0x40000000 && *d->Sync_Cycle_Period) + { + d->syncTimer = SetAlarm( + d, + 0/*No id needed*/, + &SyncAlarm, + US_TO_TIMEVAL(*d->Sync_Cycle_Period), + US_TO_TIMEVAL(*d->Sync_Cycle_Period)); + } +} + +void stopSYNC(CO_Data* d) +{ + d->syncTimer = DelAlarm(d->syncTimer); +} + +/*********************************************************************/ +UNS8 sendSYNC(CO_Data* d, UNS32 cob_id) +{ + Message m; + UNS8 resultat ; + + MSG_WAR(0x3001, "sendSYNC ", 0); + + m.cob_id.w = cob_id ; + m.rtr = NOT_A_REQUEST; + m.len = 0; + resultat = (*d->canSend)(&m) ; + proceedSYNC(d, &m) ; + return resultat ; +} + +/*****************************************************************************/ +UNS8 proceedSYNC(CO_Data* d, Message *m) +{ + + MSG_WAR(0x3002, "SYNC received. Proceed. ", 0); + + UNS8 pdoNum, // number of the actual processed pdo-nr. + prp_j; + + const UNS8 * pMappingCount = NULL; // count of mapped objects... + // pointer to the var which is mapped to a pdo +// void * pMappedAppObject = NULL; + // pointer fo the var which holds the mapping parameter of an mapping entry + UNS32 * pMappingParameter = NULL; + // pointer to the transmissiontype... + UNS8 * pTransmissionType = NULL; + UNS32 * pwCobId = NULL; + + UNS8 * pSize; + UNS8 size; + UNS8 dataType; + UNS16 index; + UNS8 subIndex; + UNS8 offset; + UNS8 status; + UNS8 sizeData; + pSize = &size; + UNS32 objDict; + status = state3; + pdoNum=0x00; + prp_j=0x00; + offset = 0x00; + UNS16 offsetObjdict; + UNS16 offsetObjdictMap; + UNS16 lastIndex; + + /* only operational state allows PDO transmission */ + if( d->nodeState != Operational ) + return 0; + + (*d->post_sync)(); + + /* So, the node is in operational state */ + /* study all PDO stored in the objects dictionary */ + + offsetObjdict = d->firstIndex->PDO_TRS; + lastIndex = d->lastIndex->PDO_TRS; + offsetObjdictMap = d->firstIndex->PDO_TRS_MAP; + + if(offsetObjdict) while( offsetObjdict <= lastIndex) { + switch( status ) { + + case state3: /* get the PDO transmission type */ + if (d->objdict[offsetObjdict].bSubCount <= 2) { + MSG_ERR(0x1004, "Subindex 2 not found at index ", 0x1800 + pdoNum); + return 0xFF; + } + pTransmissionType = d->objdict[offsetObjdict].pSubindex[2].pObject; + MSG_WAR(0x3005, "Reading PDO at index : ", 0x1800 + pdoNum); + status = state4; + break; + case state4: /* check if transmission type is after (this) SYNC */ + /* The message may not be transmited every SYNC but every n SYNC */ + if( (*pTransmissionType >= TRANS_SYNC_MIN) && (*pTransmissionType <= TRANS_SYNC_MAX) && + (++d->count_sync[pdoNum] == *pTransmissionType) ) { + d->count_sync[pdoNum] = 0; + MSG_WAR(0x3007, " PDO is on SYNCHRO. Trans type : ", *pTransmissionType); + status = state5; + break; + } + else { + MSG_WAR(0x3008, " Not on synchro or not at this SYNC. Trans type : ", + *pTransmissionType); + pdoNum++; + offsetObjdict++; + offsetObjdictMap++; + status = state11; + break; + } + case state5: /* get PDO CobId */ + pwCobId = d->objdict[offsetObjdict].pSubindex[1].pObject; + MSG_WAR(0x3009, " PDO CobId is : ", *pwCobId); + status = state7; + break; + case state7: /* get mapped objects number to transmit with this PDO */ + pMappingCount = d->objdict[offsetObjdictMap].pSubindex[0].pObject; + MSG_WAR(0x300D, " Number of objects mapped : ",*pMappingCount ); + status = state8; + case state8: /* get mapping parameters */ + pMappingParameter = d->objdict[offsetObjdictMap].pSubindex[prp_j + 1].pObject; + MSG_WAR(0x300F, " got mapping parameter : ", *pMappingParameter); + MSG_WAR(0x3050, " at index : ", 0x1A00 + pdoNum); + MSG_WAR(0x3051, " sub-index : ", prp_j + 1); + status = state9; + + case state9: /* get data to transmit */ + index = (UNS16)((*pMappingParameter) >> 16); + subIndex = (UNS8)(( (*pMappingParameter) >> (UNS8)8 ) & (UNS32)0x000000FF); + // <<3 because in *pMappingParameter the size is in bits + sizeData = (UNS8) ((*pMappingParameter & (UNS32)0x000000FF) >> 3) ; + + objDict = getODentry(d, index, subIndex, (void *)&d->process_var.data[offset], &sizeData, &dataType, 0 ); + + if( objDict != OD_SUCCESSFUL ){ + MSG_ERR(0x1013, " Couldn't find mapped variable at index-subindex-size : ", (UNS16)(*pMappingParameter)); + return 0xFF; + } + + offset += sizeData ; + d->process_var.count = offset; + prp_j++; + status = state10; + break; + + case state10: /* loop to get all the data to transmit */ + if( prp_j < *pMappingCount ){ + MSG_WAR(0x3014, " next variable mapped : ", prp_j); + status = state8; + break; + } + else { + MSG_WAR(0x3015, " End scan mapped variable", 0); + PDOmGR( d, *pwCobId ); + MSG_WAR(0x3016, " End of this pdo. Should have been sent", 0); + pdoNum++; + offsetObjdict++; + offsetObjdictMap++; + offset = 0x00; + prp_j = 0x00; + status = state11; + break; + } + + case state11: + MSG_WAR(0x3017, "next pdo index : ", pdoNum); + status = state3; + break; + + default: + MSG_ERR(0x1019,"Unknown state has been reached : %d",status); + return 0xFF; + }// end switch case + + }// end while( prp_ipost_TPDO)(); + + return 0; +} + + diff -r 000000000000 -r 4472ee7c6c3e src/timer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/timer.c Wed May 10 16:59:40 2006 +0200 @@ -0,0 +1,164 @@ +/* +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 +*/ + +//#define DEBUG_WAR_CONSOLE_ON +//#define DEBUG_ERR_CONSOLE_ON + +#include +#include "timer.h" + +// --------- The timer table --------- +s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},}; +// +TIMEVAL total_sleep_time = TIMEVAL_MAX; +TIMER_HANDLE last_timer_raw = -1; + +#define max(a,b) a>b?a:b +#define min(a,b) astate == TIMER_FREE) // and empty row + { // just store + row->callback = callback; + row->d = d; + row->id = id; + row->val = value; + row->interval = period; + row->state = TIMER_ARMED; + row_number = i; + break; + } + } + + if (row_number != TIMER_NONE) // if successfull + { + if (row_number == last_timer_raw + 1) last_timer_raw++; + + // set next wakeup alarm if new entry is sooner than others, or if it is alone + TIMEVAL real_timer_value = min(value, TIMEVAL_MAX); + TIMEVAL elapsed_time = getElapsedTime(); + + //printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); + if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) + { + total_sleep_time = elapsed_time + real_timer_value; + setTimer(real_timer_value); + } + //printf("SetAlarm() return %d\n", row_number); + return row_number; + } + return TIMER_NONE; +} + +// --------- Use this to remove an alarm --------- +TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) +{ + // Quick and dirty. system timer will continue to be trigged, but no action will be preformed. + MSG_WAR(0x3320, "DelAlarm. handle = ", handle); + if(handle != TIMER_NONE) + { + if(handle == last_timer_raw) + last_timer_raw--; + timers[handle].state = TIMER_FREE; + } + else { + } + return TIMER_NONE; +} + + +// --------- TimeDispatch is called on each timer expiration --------- +void TimeDispatch() +{ + TIMER_HANDLE i; + 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(); + + TIMEVAL real_total_sleep_time = total_sleep_time + overrun; + //printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); + + for(i=0; i <= last_timer_raw; i++) + { + s_timer_entry *row = (timers+i); + + if (row->state & TIMER_ARMED) // if row is active + { + if (row->val <= real_total_sleep_time) // to be trigged + { + //printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); + if (!row->interval) // if simply outdated + { + row->state = TIMER_TRIG; // ask for trig + } + else // or period have expired + { + // set val as interval, with overrun correction + row->val = row->interval - (overrun % row->interval); + row->state = TIMER_TRIG_PERIOD; // ask for trig, periodic + // Check if this new timer value is the soonest + next_wakeup = min(row->val,next_wakeup); + } + } + else + { + // Each armed timer value in decremented. + row->val -= real_total_sleep_time; + + // Check if this new timer value is the soonest + next_wakeup = min(row->val,next_wakeup); + } + } + } + + // Remember how much time we should sleep. + total_sleep_time = next_wakeup; + + // Set timer to soonest occurence + setTimer(next_wakeup); + + // Then trig them or not. + for(i=0; i<=last_timer_raw; i++) + { + s_timer_entry *row = (timers+i); + + if (row->state & TIMER_TRIG) + { + row->state &= ~TIMER_TRIG; // reset trig state (will be free if not periodic) + (*row->callback)(row->d, row->id); // trig ! + } + } +} +