forked from OpenEtherCATsociety/SOEM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ethercatprint.c
365 lines (338 loc) · 12.9 KB
/
ethercatprint.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Module to convert EtherCAT errors to readable messages.
*
* SDO abort messages and AL status codes are used to relay slave errors to
* the user application. This module converts the binary codes to readble text.
* For the defined error codes see the EtherCAT protocol documentation.
*/
#include <stdio.h>
#include "oshw.h"
#include "ethercattype.h"
#include "ethercatmain.h"
#define EC_MAXERRORNAME 127
/** SDO error list type definition */
typedef struct
{
/** Error code returned from SDO */
uint32 errorcode;
/** Readable error description */
char errordescription[EC_MAXERRORNAME + 1];
} ec_sdoerrorlist_t;
/** AL status code list type definition */
typedef struct
{
/** AL status code */
uint16 ALstatuscode;
/** Readable description */
char ALstatuscodedescription[EC_MAXERRORNAME + 1];
} ec_ALstatuscodelist_t;
/** SoE error list type definition */
typedef struct
{
/** SoE error code */
uint16 errorcode;
/** Readable description */
char errordescription[EC_MAXERRORNAME + 1];
} ec_soeerrorlist_t;
/** MBX error list type definition */
typedef struct
{
/** MBX error code */
uint16 errorcode;
/** Readable description */
char errordescription[EC_MAXERRORNAME + 1];
} ec_mbxerrorlist_t;
char estring[EC_MAXERRORNAME];
/** SDO error list definition */
const ec_sdoerrorlist_t ec_sdoerrorlist[] = {
{0x00000000, "No error" },
{0x05030000, "Toggle bit not changed" },
{0x05040000, "SDO protocol timeout" },
{0x05040001, "Client/Server command specifier not valid or unknown" },
{0x05040005, "Out of memory" },
{0x06010000, "Unsupported access to an object" },
{0x06010001, "Attempt to read to a write only object" },
{0x06010002, "Attempt to write to a read only object" },
{0x06010003, "Subindex can not be written, SI0 must be 0 for write access" },
{0x06010004, "SDO Complete access not supported for variable length objects" },
{0x06010005, "Object length exceeds mailbox size" },
{0x06010006, "Object mapped to RxPDO, SDO download blocked" },
{0x06020000, "The object does not exist in the object directory" },
{0x06040041, "The object can not be mapped into the PDO" },
{0x06040042, "The number and length of the objects to be mapped would exceed the PDO length" },
{0x06040043, "General parameter incompatibility reason" },
{0x06040047, "General internal incompatibility in the device" },
{0x06060000, "Access failed due to a hardware error" },
{0x06070010, "Data type does not match, length of service parameter does not match" },
{0x06070012, "Data type does not match, length of service parameter too high" },
{0x06070013, "Data type does not match, length of service parameter too low" },
{0x06090011, "Subindex does not exist" },
{0x06090030, "Value range of parameter exceeded (only for write access)" },
{0x06090031, "Value of parameter written too high" },
{0x06090032, "Value of parameter written too low" },
{0x06090036, "Maximum value is less than minimum value" },
{0x08000000, "General error" },
{0x08000020, "Data cannot be transferred or stored to the application" },
{0x08000021, "Data cannot be transferred or stored to the application because of local control" },
{0x08000022, "Data cannot be transferred or stored to the application because of the present device state" },
{0x08000023, "Object dictionary dynamic generation fails or no object dictionary is present" },
{0xffffffff, "Unknown" }
};
/** AL status code list definition */
const ec_ALstatuscodelist_t ec_ALstatuscodelist[] = {
{0x0000 , "No error" },
{0x0001 , "Unspecified error" },
{0x0002 , "No memory" },
{0x0011 , "Invalid requested state change" },
{0x0012 , "Unknown requested state" },
{0x0013 , "Bootstrap not supported" },
{0x0014 , "No valid firmware" },
{0x0015 , "Invalid mailbox configuration" },
{0x0016 , "Invalid mailbox configuration" },
{0x0017 , "Invalid sync manager configuration" },
{0x0018 , "No valid inputs available" },
{0x0019 , "No valid outputs" },
{0x001A , "Synchronization error" },
{0x001B , "Sync manager watchdog" },
{0x001C , "Invalid sync Manager types" },
{0x001D , "Invalid output configuration" },
{0x001E , "Invalid input configuration" },
{0x001F , "Invalid watchdog configuration" },
{0x0020 , "Slave needs cold start" },
{0x0021 , "Slave needs INIT" },
{0x0022 , "Slave needs PREOP" },
{0x0023 , "Slave needs SAFEOP" },
{0x0024 , "Invalid input mapping" },
{0x0025 , "Invalid output mapping" },
{0x0026 , "Inconsistent settings" },
{0x0027 , "Freerun not supported" },
{0x0028 , "Synchronisation not supported" },
{0x0029 , "Freerun needs 3buffer mode" },
{0x002A , "Background watchdog" },
{0x002B , "No valid Inputs and Outputs" },
{0x002C , "Fatal sync error" },
{0x002D , "No sync error" }, // was "Invalid Output FMMU Configuration"
{0x002E , "Invalid input FMMU configuration" },
{0x0030 , "Invalid DC SYNC configuration" },
{0x0031 , "Invalid DC latch configuration" },
{0x0032 , "PLL error" },
{0x0033 , "DC sync IO error" },
{0x0034 , "DC sync timeout error" },
{0x0035 , "DC invalid sync cycle time" },
{0x0036 , "DC invalid sync0 cycle time" },
{0x0037 , "DC invalid sync1 cycle time" },
{0x0041 , "MBX_AOE" },
{0x0042 , "MBX_EOE" },
{0x0043 , "MBX_COE" },
{0x0044 , "MBX_FOE" },
{0x0045 , "MBX_SOE" },
{0x004F , "MBX_VOE" },
{0x0050 , "EEPROM no access" },
{0x0051 , "EEPROM error" },
{0x0060 , "Slave restarted locally" },
{0x0061 , "Device identification value updated" },
{0x00f0 , "Application controller available" },
{0xffff , "Unknown" }
};
/** SoE error list definition */
const ec_soeerrorlist_t ec_soeerrorlist[] = {
{0x0000, "No error" },
{0x1001, "No IDN" },
{0x1009, "Invalid access to element 1" },
{0x2001, "No Name" },
{0x2002, "Name transmission too short" },
{0x2003, "Name transmission too long" },
{0x2004, "Name cannot be changed (read only)" },
{0x2005, "Name is write-protected at this time" },
{0x3002, "Attribute transmission too short" },
{0x3003, "Attribute transmission too long" },
{0x3004, "Attribute cannot be changed (read only)" },
{0x3005, "Attribute is write-protected at this time" },
{0x4001, "No units" },
{0x4002, "Unit transmission too short" },
{0x4003, "Unit transmission too long" },
{0x4004, "Unit cannot be changed (read only)" },
{0x4005, "Unit is write-protected at this time" },
{0x5001, "No minimum input value" },
{0x5002, "Minimum input value transmission too short" },
{0x5003, "Minimum input value transmission too long" },
{0x5004, "Minimum input value cannot be changed (read only)" },
{0x5005, "Minimum input value is write-protected at this time" },
{0x6001, "No maximum input value" },
{0x6002, "Maximum input value transmission too short" },
{0x6003, "Maximum input value transmission too long" },
{0x6004, "Maximum input value cannot be changed (read only)" },
{0x6005, "Maximum input value is write-protected at this time" },
{0x7002, "Operation data transmission too short" },
{0x7003, "Operation data transmission too long" },
{0x7004, "Operation data cannot be changed (read only)" },
{0x7005, "Operation data is write-protected at this time (state)" },
{0x7006, "Operation data is smaller than the minimum input value" },
{0x7007, "Operation data is smaller than the maximum input value" },
{0x7008, "Invalid operation data:Configured IDN will not be supported" },
{0x7009, "Operation data write protected by a password" },
{0x700A, "Operation data is write protected, it is configured cyclically" },
{0x700B, "Invalid indirect addressing: (e.g., data container, list handling)" },
{0x700C, "Operation data is write protected, due to other settings" },
{0x700D, "Reserved" },
{0x7010, "Procedure command already active" },
{0x7011, "Procedure command not interruptible" },
{0x7012, "Procedure command at this time not executable (state)" },
{0x7013, "Procedure command not executable (invalid or false parameters)" },
{0x7014, "No data state" },
{0x8001, "No default value" },
{0x8002, "Default value transmission too long" },
{0x8004, "Default value cannot be changed, read only" },
{0x800A, "Invalid drive number" },
{0x800A, "General error" },
{0x800A, "No element addressed" },
{0xffff, "Unknown" }
};
/** MBX error list definition */
const ec_mbxerrorlist_t ec_mbxerrorlist[] = {
{0x0000, "No error" },
{0x0001, "Syntax of 6 octet Mailbox Header is wrong" },
{0x0002, "The mailbox protocol is not supported" },
{0x0003, "Channel Field contains wrong value"},
{0x0004, "The service is no supported"},
{0x0005, "Invalid mailbox header"},
{0x0006, "Length of received mailbox data is too short"},
{0x0007, "No more memory in slave"},
{0x0008, "The lenght of data is inconsistent"},
{0xffff, "Unknown"}
};
/** Look up text string that belongs to SDO error code.
*
* @param[in] sdoerrorcode = SDO error code as defined in EtherCAT protocol
* @return readable string
*/
const char* ec_sdoerror2string( uint32 sdoerrorcode)
{
int i = 0;
while ( (ec_sdoerrorlist[i].errorcode != 0xffffffffUL) &&
(ec_sdoerrorlist[i].errorcode != sdoerrorcode) )
{
i++;
}
return ec_sdoerrorlist[i].errordescription;
}
/** Look up text string that belongs to AL status code.
*
* @param[in] ALstatuscode = AL status code as defined in EtherCAT protocol
* @return readable string
*/
char* ec_ALstatuscode2string( uint16 ALstatuscode)
{
int i = 0;
while ( (ec_ALstatuscodelist[i].ALstatuscode != 0xffff) &&
(ec_ALstatuscodelist[i].ALstatuscode != ALstatuscode) )
{
i++;
}
return (char *) ec_ALstatuscodelist[i].ALstatuscodedescription;
}
/** Look up text string that belongs to SoE error code.
*
* @param[in] errorcode = SoE error code as defined in EtherCAT protocol
* @return readable string
*/
char* ec_soeerror2string( uint16 errorcode)
{
int i = 0;
while ( (ec_soeerrorlist[i].errorcode != 0xffff) &&
(ec_soeerrorlist[i].errorcode != errorcode) )
{
i++;
}
return (char *) ec_soeerrorlist[i].errordescription;
}
/** Look up text string that belongs to MBX error code.
*
* @param[in] errorcode = MBX error code as defined in EtherCAT protocol
* @return readable string
*/
char* ec_mbxerror2string( uint16 errorcode)
{
int i = 0;
while ( (ec_mbxerrorlist[i].errorcode != 0xffff) &&
(ec_mbxerrorlist[i].errorcode != errorcode) )
{
i++;
}
return (char *) ec_mbxerrorlist[i].errordescription;
}
/** Look up error in ec_errorlist and convert to text string.
*
* @param[in] context = context struct
* @return readable string
*/
char* ecx_elist2string(ecx_contextt *context)
{
ec_errort Ec;
char timestr[20];
if (ecx_poperror(context, &Ec))
{
sprintf(timestr, "Time:%12.3f", Ec.Time.sec + (Ec.Time.usec / 1000000.0) );
switch (Ec.Etype)
{
case EC_ERR_TYPE_SDO_ERROR:
{
sprintf(estring, "%s SDO slave:%d index:%4.4x.%2.2x error:%8.8x %s\n",
timestr, Ec.Slave, Ec.Index, Ec.SubIdx, (unsigned)Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));
break;
}
case EC_ERR_TYPE_EMERGENCY:
{
sprintf(estring, "%s EMERGENCY slave:%d error:%4.4x\n",
timestr, Ec.Slave, Ec.ErrorCode);
break;
}
case EC_ERR_TYPE_PACKET_ERROR:
{
sprintf(estring, "%s PACKET slave:%d index:%4.4x.%2.2x error:%d\n",
timestr, Ec.Slave, Ec.Index, Ec.SubIdx, Ec.ErrorCode);
break;
}
case EC_ERR_TYPE_SDOINFO_ERROR:
{
sprintf(estring, "%s SDO slave:%d index:%4.4x.%2.2x error:%8.8x %s\n",
timestr, Ec.Slave, Ec.Index, Ec.SubIdx, (unsigned)Ec.AbortCode, ec_sdoerror2string(Ec.AbortCode));
break;
}
case EC_ERR_TYPE_SOE_ERROR:
{
sprintf(estring, "%s SoE slave:%d IDN:%4.4x error:%4.4x %s\n",
timestr, Ec.Slave, Ec.Index, (unsigned)Ec.AbortCode, ec_soeerror2string(Ec.ErrorCode));
break;
}
case EC_ERR_TYPE_MBX_ERROR:
{
sprintf(estring, "%s MBX slave:%d error:%4.4x %s\n",
timestr, Ec.Slave, Ec.ErrorCode, ec_mbxerror2string(Ec.ErrorCode));
break;
}
default:
{
sprintf(estring, "%s error:%8.8x\n",
timestr, (unsigned)Ec.AbortCode);
break;
}
}
return (char*) estring;
}
else
{
return "";
}
}
#ifdef EC_VER1
char* ec_elist2string(void)
{
return ecx_elist2string(&ecx_context);
}
#endif