AB&T / SOEM

Dependents:   EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ethercatprint.c Source File

ethercatprint.c

Go to the documentation of this file.
00001 /*
00002  * Licensed under the GNU General Public License version 2 with exceptions. See
00003  * LICENSE file in the project root for full license information
00004  */
00005 
00006 /** \file
00007  * \brief
00008  * Module to convert EtherCAT errors to readable messages.
00009  *
00010  * SDO abort messages and AL status codes are used to relay slave errors to
00011  * the user application. This module converts the binary codes to readable text.
00012  * For the defined error codes see the EtherCAT protocol documentation.
00013  */
00014 
00015 #include <stdio.h>
00016 #include "oshw.h"
00017 #include "ethercattype.h"
00018 #include "ethercatmain.h"
00019 
00020 #define EC_MAXERRORNAME 127
00021 
00022 /** SDO error list type definition */
00023 typedef struct
00024 {
00025    /** Error code returned from SDO */
00026    uint32        errorcode;
00027    /** Readable error description */
00028    char          errordescription[EC_MAXERRORNAME + 1];
00029 } ec_sdoerrorlist_t;
00030 
00031 /** AL status code list type definition */
00032 typedef struct
00033 {
00034    /** AL status code */
00035    uint16        ALstatuscode;
00036    /** Readable description */
00037    char          ALstatuscodedescription[EC_MAXERRORNAME + 1];
00038 } ec_ALstatuscodelist_t;
00039 
00040 /** SoE error list type definition */
00041 typedef struct
00042 {
00043    /** SoE error code */
00044    uint16        errorcode;
00045    /** Readable description */
00046    char          errordescription[EC_MAXERRORNAME + 1];
00047 } ec_soeerrorlist_t;
00048 
00049 /** MBX error list type definition */
00050 typedef struct
00051 {
00052    /** MBX error code */
00053    uint16              errorcode;
00054    /** Readable description */
00055    char                errordescription[EC_MAXERRORNAME + 1];
00056 } ec_mbxerrorlist_t;
00057 
00058 char estring[EC_MAXERRORNAME];
00059 
00060 /** SDO error list definition */
00061 const ec_sdoerrorlist_t ec_sdoerrorlist[] = {
00062    {0x00000000, "No error" },
00063    {0x05030000, "Toggle bit not changed" },
00064    {0x05040000, "SDO protocol timeout" },
00065    {0x05040001, "Client/Server command specifier not valid or unknown" },
00066    {0x05040005, "Out of memory" },
00067    {0x06010000, "Unsupported access to an object" },
00068    {0x06010001, "Attempt to read to a write only object" },
00069    {0x06010002, "Attempt to write to a read only object" },
00070    {0x06010003, "Subindex can not be written, SI0 must be 0 for write access" },
00071    {0x06010004, "SDO Complete access not supported for variable length objects" },
00072    {0x06010005, "Object length exceeds mailbox size" },
00073    {0x06010006, "Object mapped to RxPDO, SDO download blocked" },
00074    {0x06020000, "The object does not exist in the object directory" },
00075    {0x06040041, "The object can not be mapped into the PDO" },
00076    {0x06040042, "The number and length of the objects to be mapped would exceed the PDO length" },
00077    {0x06040043, "General parameter incompatibility reason" },
00078    {0x06040047, "General internal incompatibility in the device" },
00079    {0x06060000, "Access failed due to a hardware error" },
00080    {0x06070010, "Data type does not match, length of service parameter does not match" },
00081    {0x06070012, "Data type does not match, length of service parameter too high" },
00082    {0x06070013, "Data type does not match, length of service parameter too low" },
00083    {0x06090011, "Subindex does not exist" },
00084    {0x06090030, "Value range of parameter exceeded (only for write access)" },
00085    {0x06090031, "Value of parameter written too high" },
00086    {0x06090032, "Value of parameter written too low" },
00087    {0x06090036, "Maximum value is less than minimum value" },
00088    {0x08000000, "General error" },
00089    {0x08000020, "Data cannot be transferred or stored to the application" },
00090    {0x08000021, "Data cannot be transferred or stored to the application because of local control" },
00091    {0x08000022, "Data cannot be transferred or stored to the application because of the present device state" },
00092    {0x08000023, "Object dictionary dynamic generation fails or no object dictionary is present" },
00093    {0xffffffff, "Unknown" }
00094 };
00095 
00096 /** AL status code list definition */
00097 const ec_ALstatuscodelist_t ec_ALstatuscodelist[] = {
00098    {0x0000 , "No error" },
00099    {0x0001 , "Unspecified error" },
00100    {0x0002 , "No memory" },
00101    {0x0011 , "Invalid requested state change" },
00102    {0x0012 , "Unknown requested state" },
00103    {0x0013 , "Bootstrap not supported" },
00104    {0x0014 , "No valid firmware" },
00105    {0x0015 , "Invalid mailbox configuration" },
00106    {0x0016 , "Invalid mailbox configuration" },
00107    {0x0017 , "Invalid sync manager configuration" },
00108    {0x0018 , "No valid inputs available" },
00109    {0x0019 , "No valid outputs" },
00110    {0x001A , "Synchronization error" },
00111    {0x001B , "Sync manager watchdog" },
00112    {0x001C , "Invalid sync Manager types" },
00113    {0x001D , "Invalid output configuration" },
00114    {0x001E , "Invalid input configuration" },
00115    {0x001F , "Invalid watchdog configuration" },
00116    {0x0020 , "Slave needs cold start" },
00117    {0x0021 , "Slave needs INIT" },
00118    {0x0022 , "Slave needs PREOP" },
00119    {0x0023 , "Slave needs SAFEOP" },
00120    {0x0024 , "Invalid input mapping" },
00121    {0x0025 , "Invalid output mapping" },
00122    {0x0026 , "Inconsistent settings" },
00123    {0x0027 , "Freerun not supported" },
00124    {0x0028 , "Synchronisation not supported" },
00125    {0x0029 , "Freerun needs 3buffer mode" },
00126    {0x002A , "Background watchdog" },
00127    {0x002B , "No valid Inputs and Outputs" },
00128    {0x002C , "Fatal sync error" },
00129    {0x002D , "No sync error" }, // was "Invalid Output FMMU Configuration"
00130    {0x002E , "Invalid input FMMU configuration" },
00131    {0x0030 , "Invalid DC SYNC configuration" },
00132    {0x0031 , "Invalid DC latch configuration" },
00133    {0x0032 , "PLL error" },
00134    {0x0033 , "DC sync IO error" },
00135    {0x0034 , "DC sync timeout error" },
00136    {0x0035 , "DC invalid sync cycle time" },
00137    {0x0036 , "DC invalid sync0 cycle time" },
00138    {0x0037 , "DC invalid sync1 cycle time" },
00139    {0x0041 , "MBX_AOE" },
00140    {0x0042 , "MBX_EOE" },
00141    {0x0043 , "MBX_COE" },
00142    {0x0044 , "MBX_FOE" },
00143    {0x0045 , "MBX_SOE" },
00144    {0x004F , "MBX_VOE" },
00145    {0x0050 , "EEPROM no access" },
00146    {0x0051 , "EEPROM error" },
00147    {0x0060 , "Slave restarted locally" },
00148    {0x0061 , "Device identification value updated" },
00149    {0x00f0 , "Application controller available" },
00150    {0xffff , "Unknown" }
00151 };
00152 
00153 /** SoE error list definition */
00154 const ec_soeerrorlist_t ec_soeerrorlist[] = {
00155    {0x0000, "No error" },
00156    {0x1001, "No IDN" },
00157    {0x1009, "Invalid access to element 1" },
00158    {0x2001, "No Name" },
00159    {0x2002, "Name transmission too short" },
00160    {0x2003, "Name transmission too long" },
00161    {0x2004, "Name cannot be changed (read only)" },
00162    {0x2005, "Name is write-protected at this time" },
00163    {0x3002, "Attribute transmission too short" },
00164    {0x3003, "Attribute transmission too long" },
00165    {0x3004, "Attribute cannot be changed (read only)" },
00166    {0x3005, "Attribute is write-protected at this time" },
00167    {0x4001, "No units" },
00168    {0x4002, "Unit transmission too short" },
00169    {0x4003, "Unit transmission too long" },
00170    {0x4004, "Unit cannot be changed (read only)" },
00171    {0x4005, "Unit is write-protected at this time" },
00172    {0x5001, "No minimum input value" },
00173    {0x5002, "Minimum input value transmission too short" },
00174    {0x5003, "Minimum input value transmission too long" },
00175    {0x5004, "Minimum input value cannot be changed (read only)" },
00176    {0x5005, "Minimum input value is write-protected at this time" },
00177    {0x6001, "No maximum input value" },
00178    {0x6002, "Maximum input value transmission too short" },
00179    {0x6003, "Maximum input value transmission too long" },
00180    {0x6004, "Maximum input value cannot be changed (read only)" },
00181    {0x6005, "Maximum input value is write-protected at this time" },
00182    {0x7002, "Operation data transmission too short" },
00183    {0x7003, "Operation data transmission too long" },
00184    {0x7004, "Operation data cannot be changed (read only)" },
00185    {0x7005, "Operation data is write-protected at this time (state)" },
00186    {0x7006, "Operation data is smaller than the minimum input value" },
00187    {0x7007, "Operation data is smaller than the maximum input value" },
00188    {0x7008, "Invalid operation data:Configured IDN will not be supported" },
00189    {0x7009, "Operation data write protected by a password" },
00190    {0x700A, "Operation data is write protected, it is configured cyclically" },
00191    {0x700B, "Invalid indirect addressing: (e.g., data container, list handling)" },
00192    {0x700C, "Operation data is write protected, due to other settings" },
00193    {0x700D, "Reserved" },
00194    {0x7010, "Procedure command already active" },
00195    {0x7011, "Procedure command not interruptible" },
00196    {0x7012, "Procedure command at this time not executable (state)" },
00197    {0x7013, "Procedure command not executable (invalid or false parameters)" },
00198    {0x7014, "No data state" },
00199    {0x8001, "No default value" },
00200    {0x8002, "Default value transmission too long" },
00201    {0x8004, "Default value cannot be changed, read only" },
00202    {0x800A, "Invalid drive number" },
00203    {0x800A, "General error" },
00204    {0x800A, "No element addressed" },
00205    {0xffff, "Unknown" }
00206 };
00207 
00208 /** MBX error list definition */
00209 const ec_mbxerrorlist_t ec_mbxerrorlist[] = {
00210    {0x0000, "No error" },
00211    {0x0001, "Syntax of 6 octet Mailbox Header is wrong" },
00212    {0x0002, "The mailbox protocol is not supported" },
00213    {0x0003, "Channel Field contains wrong value"},
00214    {0x0004, "The service is no supported"},
00215    {0x0005, "Invalid mailbox header"},
00216    {0x0006, "Length of received mailbox data is too short"},
00217    {0x0007, "No more memory in slave"},
00218    {0x0008, "The length of data is inconsistent"},
00219    {0xffff, "Unknown"}
00220 };
00221 
00222 /** Look up text string that belongs to SDO error code.
00223  *
00224  * @param[in] sdoerrorcode   = SDO error code as defined in EtherCAT protocol
00225  * @return readable string
00226  */
00227 const char* ec_sdoerror2string( uint32 sdoerrorcode)
00228 {
00229    int i = 0;
00230 
00231    while ( (ec_sdoerrorlist[i].errorcode != 0xffffffffUL) &&
00232            (ec_sdoerrorlist[i].errorcode != sdoerrorcode) )
00233    {
00234       i++;
00235    }
00236 
00237    return ec_sdoerrorlist[i].errordescription;
00238 }
00239 
00240 /** Look up text string that belongs to AL status code.
00241  *
00242  * @param[in] ALstatuscode   = AL status code as defined in EtherCAT protocol
00243  * @return readable string
00244  */
00245 char* ec_ALstatuscode2string( uint16 ALstatuscode)
00246 {
00247    int i = 0;
00248 
00249    while ( (ec_ALstatuscodelist[i].ALstatuscode != 0xffff) &&
00250            (ec_ALstatuscodelist[i].ALstatuscode != ALstatuscode) )
00251    {
00252       i++;
00253    }
00254 
00255    return (char *) ec_ALstatuscodelist[i].ALstatuscodedescription;
00256 }
00257 
00258 /** Look up text string that belongs to SoE error code.
00259  *
00260  * @param[in] errorcode   = SoE error code as defined in EtherCAT protocol
00261  * @return readable string
00262  */
00263 char* ec_soeerror2string( uint16 errorcode)
00264 {
00265    int i = 0;
00266 
00267    while ( (ec_soeerrorlist[i].errorcode != 0xffff) &&
00268            (ec_soeerrorlist[i].errorcode != errorcode) )
00269    {
00270       i++;
00271    }
00272 
00273    return (char *) ec_soeerrorlist[i].errordescription;
00274 }
00275 
00276 /** Look up text string that belongs to MBX error code.
00277  *
00278  * @param[in] errorcode   = MBX error code as defined in EtherCAT protocol
00279  * @return readable string
00280  */
00281 char* ec_mbxerror2string( uint16 errorcode)
00282 {
00283    int i = 0;
00284 
00285    while ( (ec_mbxerrorlist[i].errorcode != 0xffff) &&
00286            (ec_mbxerrorlist[i].errorcode != errorcode) )
00287    {
00288       i++;
00289    }
00290 
00291    return (char *) ec_mbxerrorlist[i].errordescription;
00292 }
00293 
00294 /** Look up error in ec_errorlist and convert to text string.
00295  *
00296  * @param[in]  context        = context struct
00297  * @return readable string
00298  */
00299 char* ecx_elist2string(ecx_contextt *context)
00300 {
00301    ec_errort Ec;
00302    char timestr[20];
00303 
00304    if (ecx_poperror(context, &Ec))
00305    {
00306       sprintf(timestr, "Time:%12.3f", Ec.Time.sec + (Ec.Time.usec / 1000000.0) );
00307       switch (Ec.Etype)
00308       {
00309          case EC_ERR_TYPE_SDO_ERROR:
00310          {
00311             sprintf(estring, "%s SDO slave:%d index:%4.4x.%2.2x error:%8.8x %s\n",
00312                     timestr, Ec.Slave, Ec.Index, Ec.SubIdx, (unsigned)Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));
00313             break;
00314          }
00315          case EC_ERR_TYPE_EMERGENCY:
00316          {
00317             sprintf(estring, "%s EMERGENCY slave:%d error:%4.4x\n",
00318                     timestr, Ec.Slave, Ec.ErrorCode);
00319             break;
00320          }
00321          case EC_ERR_TYPE_PACKET_ERROR:
00322          {
00323             sprintf(estring, "%s PACKET slave:%d index:%4.4x.%2.2x error:%d\n",
00324                     timestr, Ec.Slave, Ec.Index, Ec.SubIdx, Ec.ErrorCode);
00325             break;
00326          }
00327          case EC_ERR_TYPE_SDOINFO_ERROR:
00328          {
00329             sprintf(estring, "%s SDO slave:%d index:%4.4x.%2.2x error:%8.8x %s\n",
00330                     timestr, Ec.Slave, Ec.Index, Ec.SubIdx, (unsigned)Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));
00331             break;
00332          }
00333          case EC_ERR_TYPE_SOE_ERROR:
00334          {
00335             sprintf(estring, "%s SoE slave:%d IDN:%4.4x error:%4.4x %s\n",
00336                     timestr, Ec.Slave, Ec.Index, (unsigned)Ec.AbortCode, ec_soeerror2string(Ec.ErrorCode));
00337             break;
00338          }
00339          case EC_ERR_TYPE_MBX_ERROR:
00340          {
00341             sprintf(estring, "%s MBX slave:%d error:%4.4x %s\n",
00342                     timestr, Ec.Slave, Ec.ErrorCode, ec_mbxerror2string(Ec.ErrorCode));
00343             break;
00344          }
00345          default:
00346          {
00347             sprintf(estring, "%s error:%8.8x\n",
00348                     timestr, (unsigned)Ec.AbortCode);
00349             break;
00350          }
00351       }
00352       return (char*) estring;
00353    }
00354    else
00355    {
00356       return "";
00357    }
00358 }
00359 
00360 #ifdef EC_VER1
00361 char* ec_elist2string(void)
00362 {
00363    return ecx_elist2string(&ecx_context);
00364 }
00365 #endif