ethercatprint.c

Go to the documentation of this file.
00001 /*
00002  * Simple Open EtherCAT Master Library 
00003  *
00004  * File    : ethercatprint.c
00005  * Version : 1.2.5
00006  * Date    : 09-04-2011
00007  * Copyright (C) 2005-2011 Speciaal Machinefabriek Ketels v.o.f.
00008  * Copyright (C) 2005-2011 Arthur Ketels
00009  * Copyright (C) 2008-2009 TU/e Technische Universiteit Eindhoven 
00010  *
00011  * SOEM is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the Free
00013  * Software Foundation.
00014  *
00015  * SOEM is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00017  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00018  * for more details.
00019  *
00020  * As a special exception, if other files instantiate templates or use macros
00021  * or inline functions from this file, or you compile this file and link it
00022  * with other works to produce a work based on this file, this file does not
00023  * by itself cause the resulting work to be covered by the GNU General Public
00024  * License. However the source code for this file must still be made available
00025  * in accordance with section (3) of the GNU General Public License.
00026  *
00027  * This exception does not invalidate any other reasons why a work based on
00028  * this file might be covered by the GNU General Public License.
00029  *
00030  * The EtherCAT Technology, the trade name and logo “EtherCAT” are the intellectual
00031  * property of, and protected by Beckhoff Automation GmbH. You can use SOEM for
00032  * the sole purpose of creating, using and/or selling or otherwise distributing
00033  * an EtherCAT network master provided that an EtherCAT Master License is obtained
00034  * from Beckhoff Automation GmbH.
00035  *
00036  * In case you did not receive a copy of the EtherCAT Master License along with
00037  * SOEM write to Beckhoff Automation GmbH, Eiserstraße 5, D-33415 Verl, Germany
00038  * (www.beckhoff.com).
00039  */
00040 
00041 /** \file
00042  * \brief
00043  * Module to convert EtherCAT errors to readable messages.
00044  *
00045  * SDO abort messages and AL status codes are used to relay slave errors to
00046  * the user application. This module converts the binary codes to readble text.
00047  * For the defined error codes see the EtherCAT protocol documentation.
00048  */
00049 
00050 #include <stdio.h>
00051 #include "ethercattype.h"
00052 #include "ethercatmain.h"
00053 
00054 #define EC_MAXERRORNAME 127
00055 
00056 /** SDO error list type definition */
00057 typedef const struct
00058 {
00059   /** Error code returned from SDO */
00060   uint32        errorcode;
00061   /** Readable error description */
00062   char        errordescription[EC_MAXERRORNAME + 1];
00063 } ec_sdoerrorlist_t;
00064 
00065 /** AL status code list type definition */
00066 typedef const struct
00067 {
00068   /** AL status code */
00069   uint16        ALstatuscode;
00070   /** Readable description */
00071   char        ALstatuscodedescription[EC_MAXERRORNAME + 1];
00072 } ec_ALstatuscodelist_t;
00073 
00074 /** SoE error list type definition */
00075 typedef const struct
00076 {
00077   /** SoE error code */
00078   uint16        errorcode;
00079   /** Readable description */
00080   char        errordescription[EC_MAXERRORNAME + 1];
00081 } ec_soeerrorlist_t;
00082 
00083 char estring[EC_MAXERRORNAME];
00084 
00085 /** SDO error list definition */
00086 const ec_sdoerrorlist_t ec_sdoerrorlist[] = {
00087   {0x00000000, "No error" },
00088   {0x05030000, "Toggle bit not changed" },
00089   {0x05040000, "SDO protocol timeout" },
00090   {0x05040001, "Client/Server command specifier not valid or unknown" },
00091   {0x05040005, "Out of memory" },
00092   {0x06010000, "Unsupported access to an object" },
00093   {0x06010001, "Attempt to read to a write only object" },
00094   {0x06010002, "Attempt to write to a read only object" },
00095   {0x06020000, "The object does not exist in the object directory" },
00096   {0x06040041, "The object can not be mapped into the PDO" },
00097   {0x06040042, "The number and length of the objects to be mapped would exceed the PDO length" },
00098   {0x06040043, "General parameter incompatibility reason" },
00099   {0x06040047, "General internal incompatibility in the device" },
00100   {0x06060000, "Access failed due to a hardware error" },
00101   {0x06070010, "Data type does not match, length of service parameter does not match" },
00102   {0x06070012, "Data type does not match, length of service parameter too high" },
00103   {0x06070013, "Data type does not match, length of service parameter too low" },
00104   {0x06090011, "Subindex does not exist" },
00105   {0x06090030, "Value range of parameter exceeded (only for write access)" },
00106   {0x06090031, "Value of parameter written too high" },
00107   {0x06090032, "Value of parameter written too low" },
00108   {0x06090036, "Maximum value is less than minimum value" },
00109   {0x08000000, "General error" },
00110   {0x08000020, "Data cannot be transferred or stored to the application" },
00111   {0x08000021, "Data cannot be transferred or stored to the application because of local control" },
00112   {0x08000022, "Data cannot be transferred or stored to the application because of the present device state" },
00113   {0x08000023, "Object dictionary dynamic generation fails or no object dictionary is present" },
00114   {0xffffffff, "Unknown" }
00115 };
00116 
00117 /** AL status code list definition */
00118 const ec_ALstatuscodelist_t ec_ALstatuscodelist[] = {
00119   {0x0000 , "No error" },
00120   {0x0001 , "Unspecified error" },
00121   {0x0011 , "Invalid requested state change" },
00122   {0x0012 , "Unknown requested state" },
00123   {0x0013 , "Bootstrap not supported" },
00124   {0x0014 , "No valid firmware" },
00125   {0x0015 , "Invalid mailbox configuration" },
00126   {0x0016 , "Invalid mailbox configuration" },
00127   {0x0017 , "Invalid sync manager configuration" },
00128   {0x0018 , "No valid inputs available" },
00129   {0x0019 , "No valid outputs" },
00130   {0x001A , "Synchronization error" },
00131   {0x001B , "Sync manager watchdog" },
00132   {0x001C , "Invalid Sync Manager Types" },
00133   {0x001D , "Invalid Output Configuration" },
00134   {0x001E , "Invalid Input Configuration" },
00135   {0x001F , "Invalid Watchdog Configuration" },
00136   {0x0020 , "Slave needs cold start" },
00137   {0x0021 , "Slave needs INIT" },
00138   {0x0022 , "Slave needs PREOP" },
00139   {0x0023 , "Slave needs SAFEOP" },
00140   {0x002D , "Invalid Output FMMU Configuration" },
00141   {0x002E , "Invalid Input FMMU Configuration" },
00142   {0x0030 , "Invalid DC SYNCH Configuration" },
00143   {0x0031 , "Invalid DC Latch Configuration" },
00144   {0x0032 , "PLL Error" },
00145   {0x0033 , "Invalid DC IO Error" },
00146   {0x0034 , "Invalid DC Timeout Error" },
00147   {0x0042 , "MBX_EOE" },
00148   {0x0043 , "MBX_COE" },
00149   {0x0044 , "MBX_FOE" },
00150   {0x0045 , "MBX_SOE" },
00151   {0x004F , "MBX_VOE" },
00152   {0xffff , "Unknown" }
00153 };
00154 
00155 /** SoE error list definition */
00156 const ec_soeerrorlist_t ec_soeerrorlist[] = {
00157   {0x0000, "No error" },
00158   {0x1001, "No IDN" },
00159   {0x1009, "Invalid access to element 1" },
00160   {0x2001, "No Name" },
00161   {0x2002, "Name transmission too short" },
00162   {0x2003, "Name transmission too long" },
00163   {0x2004, "Name cannot be changed (read only)" },
00164   {0x2005, "Name is write-protected at this time" },
00165   {0x3002, "Attribute transmission too short" },
00166   {0x3003, "Attribute transmission too long" },
00167   {0x3004, "Attribute cannot be changed (read only)" },
00168   {0x3005, "Attribute is write-protected at this time" },
00169   {0x4001, "No units" },
00170   {0x4002, "Unit transmission too short" },
00171   {0x4003, "Unit transmission too long" },
00172   {0x4004, "Unit cannot be changed (read only)" },
00173   {0x4005, "Unit is write-protected at this time" },
00174   {0x5001, "No minimum input value" },
00175   {0x5002, "Minimum input value transmission too short" },
00176   {0x5003, "Minimum input value transmission too long" },
00177   {0x5004, "Minimum input value cannot be changed (read only)" },
00178   {0x5005, "Minimum input value is write-protected at this time" },
00179   {0x6001, "No maximum input value" },
00180   {0x6002, "Maximum input value transmission too short" },
00181   {0x6003, "Maximum input value transmission too long" },
00182   {0x6004, "Maximum input value cannot be changed (read only)" },
00183   {0x6005, "Maximum input value is write-protected at this time" },
00184   {0x7002, "Operation data transmission too short" },
00185   {0x7003, "Operation data transmission too long" },
00186   {0x7004, "Operation data cannot be changed (read only)" },
00187   {0x7005, "Operation data is write-protected at this time (state)" },
00188   {0x7006, "Operation data is smaller than the minimum input value" },
00189   {0x7007, "Operation data is smaller than the maximum input value" },
00190   {0x7008, "Invalid operation data:Configured IDN will not be supported" },
00191   {0x7009, "Operation data write protected by a password" },
00192   {0x700A, "Operation data is write protected, it is configured cyclically" },
00193   {0x700B, "Invalid indirect addressing: (e.g., data container, list handling)" },
00194   {0x700C, "Operation data is write protected, due to other settings" },
00195   {0x700D, "Reserved" },
00196   {0x7010, "Procedure command already active" },
00197   {0x7011, "Procedure command not interruptible" },
00198   {0x7012, "Procedure command at this time not executable (state)" },
00199   {0x7013, "Procedure command not executable (invalid or false parameters)" },
00200   {0x7014, "No data state" },
00201   {0x8001, "No default value" },
00202   {0x8002, "Default value transmission too long" },
00203   {0x8004, "Default value cannot be changed, read only" },
00204   {0x800A, "Invalid drive number" },
00205   {0x800A, "General error" },
00206   {0x800A, "No element addressed" },
00207   {0xffff, "Unknown" }
00208 };
00209   
00210 /** Look up text string that belongs to SDO error code.
00211  *
00212  * @param[in] sdoerrorcode    = SDO error code as defined in EtherCAT protocol
00213  * @return readable string
00214  */
00215 char* ec_sdoerror2string( uint32 sdoerrorcode)
00216 {
00217   int i = 0;
00218 
00219   do 
00220   {
00221     i++;
00222   } 
00223   while ( (ec_sdoerrorlist[i].errorcode != 0xfffffffful) && 
00224       (ec_sdoerrorlist[i].errorcode != sdoerrorcode) );
00225   
00226   return (char*) ec_sdoerrorlist[i].errordescription;
00227 }
00228 
00229 /** Look up text string that belongs to AL status code.
00230  *
00231  * @param[in] ALstatuscode    = AL status code as defined in EtherCAT protocol
00232  * @return readable string
00233  */
00234 char* ec_ALstatuscode2string( uint16 ALstatuscode)
00235 {
00236   int i = 0;
00237 
00238   do 
00239   {
00240     i++;
00241   } 
00242   while ( (ec_ALstatuscodelist[i].ALstatuscode != 0xffff) && 
00243       (ec_ALstatuscodelist[i].ALstatuscode != ALstatuscode) );
00244   
00245   return (char *) ec_ALstatuscodelist[i].ALstatuscodedescription;
00246 }
00247 
00248 /** Look up text string that belongs to SoE error code.
00249  *
00250  * @param[in] errorcode   = AL status code as defined in EtherCAT protocol
00251  * @return readable string
00252  */
00253 char* ec_soeerror2string( uint16 errorcode)
00254 {
00255   int i = 0;
00256 
00257   do 
00258   {
00259     i++;
00260   } 
00261   while ( (ec_soeerrorlist[i].errorcode != 0xffff) && 
00262       (ec_soeerrorlist[i].errorcode != errorcode) );
00263   
00264   return (char *) ec_soeerrorlist[i].errordescription;
00265 }
00266 
00267 /** Look up error in ec_errorlist and convert to text string.
00268  *
00269  * @return readable string
00270  */
00271 char* ec_elist2string(void)
00272 {
00273   ec_errort Ec;
00274   char timestr[20];
00275   
00276   if (ec_poperror(&Ec))
00277   {
00278     sprintf(timestr, "Time:%12.3f", Ec.Time.tv_sec + (Ec.Time.tv_usec / 1000000.0) );
00279     switch (Ec.Etype)
00280     {
00281       case EC_ERR_TYPE_SDO_ERROR:
00282         sprintf(estring, "%s SDO slave:%d index:%4.4x.%2.2x error:%8.8x %s\n", 
00283           timestr, Ec.Slave, Ec.Index, Ec.SubIdx, Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));        
00284         break;
00285       case EC_ERR_TYPE_EMERGENCY:
00286         sprintf(estring, "%s EMERGENCY slave:%d error:%4.4x\n", 
00287           timestr, Ec.Slave, Ec.ErrorCode);       
00288         break;
00289       case EC_ERR_TYPE_PACKET_ERROR:
00290         sprintf(estring, "%s PACKET slave:%d index:%4.4x.%2.2x error:%d\n", 
00291           timestr, Ec.Slave, Ec.Index, Ec.SubIdx, Ec.ErrorCode);        
00292         break;
00293       case EC_ERR_TYPE_SDOINFO_ERROR:
00294         sprintf(estring, "%s SDO slave:%d index:%4.4x.%2.2x error:%8.8x %s\n", 
00295           timestr, Ec.Slave, Ec.Index, Ec.SubIdx, Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));        
00296         break;
00297       case EC_ERR_TYPE_SOE_ERROR:
00298         sprintf(estring, "%s SoE slave:%d IDN:%4.4x error:%4.4x %s\n", 
00299           timestr, Ec.Slave, Ec.Index, Ec.AbortCode, ec_soeerror2string(Ec.ErrorCode));       
00300         break;
00301       default:
00302         sprintf(estring, "%s error:%8.8x\n", 
00303           timestr, Ec.AbortCode);       
00304     }
00305     return (char*) estring;
00306   }
00307   else return "";
00308 }
Generated by  doxygen 1.6.3