00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef __ethercat_slave_memory_h__
00034 #define __ethercat_slave_memory_h__
00035
00036 #include "ros_ethercat_eml/ethercat_defs.h"
00037 #include "ros_ethercat_eml/ethercat_log.h"
00038 #include "ros_ethercat_eml/ethercat_datastruct.h"
00039 #include <stdio.h>
00040 #include <cassert>
00041
00042
00043 static const size_t EC_DLInformationSize = 0xa;
00044
00045
00046
00047
00048
00049 static const uint32_t EC_ProductCodeAddressInSII = 0x0000000a;
00050 static const uint32_t EC_RevisionAddressInSII = 0x0000000c;
00051 static const uint32_t EC_SerialAddressInSII = 0x0000000e;
00052
00053 enum ECAT_Slave_Registers
00054 {
00055 Type = 0,
00056 Revision,
00057 Build,
00058 Num_FMMUs,
00059 Num_Sync_Managers,
00060 RAM_Size,
00061 ECAT_Station_Address,
00062 DLL_Control,
00063 DLL_Status,
00064 AL_Control,
00065 AL_Status,
00066 PDI_Control,
00067 PDI_Conf_reg,
00068 AL_Event,
00069 RX_Error_Counter_Channel_A,
00070 RX_Error_Counter_Channel_B,
00071 Watchdog_Divider,
00072 Watchdog_Time_PDI,
00073 Watchdog_Time_Channel_0,
00074 Watchdog_Time_Channel_1,
00075 Watchdog_Time_Channel_2,
00076 Watchdog_Time_Channel_3,
00077 Watchdog_Time_Channel_4,
00078 Watchdog_Time_Channel_5,
00079 Watchdog_Time_Channel_6,
00080 Watchdog_Time_Channel_7,
00081 Watchdog_Time_Channel_8,
00082 Watchdog_Time_Channel_9,
00083 Watchdog_Time_Channel_10,
00084 Watchdog_Time_Channel_11,
00085 Watchdog_Time_Channel_12,
00086 Watchdog_Time_Channel_13,
00087 Watchdog_Time_Channel_14,
00088 Watchdog_Time_Channel_15,
00089 Watchdog_Channel_status,
00090 SII_Size,
00091 SII_ControlStatus,
00092 SII_Address,
00093 SII_Data,
00094 FMMU_0,
00095 FMMU_1,
00096 FMMU_2,
00097 FMMU_3,
00098 FMMU_4,
00099 FMMU_5,
00100 FMMU_6,
00101 FMMU_7,
00102 FMMU_8,
00103 FMMU_9,
00104 FMMU_10,
00105 FMMU_11,
00106 FMMU_12,
00107 FMMU_13,
00108 FMMU_14,
00109 FMMU_15,
00110 Sync_Manager_0,
00111 Sync_Manager_1,
00112 Sync_Manager_2,
00113 Sync_Manager_3,
00114 Sync_Manager_4,
00115 Sync_Manager_5,
00116 Sync_Manager_6,
00117 Sync_Manager_7,
00118 Sync_Manager_8,
00119 Sync_Manager_9,
00120 Sync_Manager_10,
00121 Sync_Manager_11,
00122 Sync_Manager_12,
00123 Sync_Manager_13,
00124 Sync_Manager_14,
00125 Sync_Manager_15,
00126 NumRegisters,
00127 };
00128
00129 enum ECAT_Register_Access
00130 {
00131 EC_R = 0,
00132 EC_W = 1,
00133 EC_RW = 2
00134 };
00135
00137
00138 struct ECAT_Slave_Register_Data
00139 {
00141 const char * name;
00143 const uint16_t ado;
00145 const ECAT_Register_Access ECAT_access;
00147 const ECAT_Register_Access uC_access;
00149 const uint8_t size;
00150 };
00151
00152 static const ECAT_Slave_Register_Data EC_Slave_RD[NumRegisters] = {
00153 {"Type", 0x0000, EC_R, EC_R, 0x01},
00154 {"Revision", 0x0001, EC_R, EC_R, 0x01},
00155 {"Build", 0x0002, EC_R, EC_R, 0x02},
00156 {"Number of FMMUs", 0x0004, EC_R, EC_R, 0x01},
00157 {"Number of Sync Managers", 0x0005, EC_R, EC_R, 0x01},
00158 {"RAM Size", 0x0006, EC_R, EC_R, 0x01},
00159 {"EtherCAT Station Address", 0x0010, EC_RW, EC_R, 0x02},
00160 {"DLL Control Register", 0x0100, EC_RW, EC_R, 0x02},
00161 {"DLL Status Register", 0x0110, EC_R, EC_R, 0x02},
00162 {"AL Control Register", 0x0120, EC_RW, EC_R, 0x02},
00163 {"AL Status Register", 0x0130, EC_R, EC_RW, 0x02},
00164 {"PDI Control Register", 0x0140, EC_R, EC_R, 0x02},
00165 {"PDI Config Register", 0x0150, EC_R, EC_R, 0x05},
00166 {"AL Event Register", 0x0220, EC_R, EC_R, 0x04},
00167 {"RX Error Counter Channel A", 0x0300, EC_RW, EC_R, 0x02},
00168 {"RX Error Counter Channel B", 0x0302, EC_RW, EC_R, 0x02},
00169 {"Watchdog divider", 0x0400, EC_RW, EC_R, 0x02},
00170 {"Watchdog Time PDI", 0x0410, EC_RW, EC_R, 0x02},
00171 {"Watchdog Time Channel 0", 0x0420, EC_RW, EC_R, 0x02},
00172 {"Watchdog Time Channel 1", 0x0422, EC_RW, EC_R, 0x02},
00173 {"Watchdog Time Channel 2", 0x0424, EC_RW, EC_R, 0x02},
00174 {"Watchdog Time Channel 3", 0x0426, EC_RW, EC_R, 0x02},
00175 {"Watchdog Time Channel 4", 0x0428, EC_RW, EC_R, 0x02},
00176 {"Watchdog Time Channel 5", 0x042a, EC_RW, EC_R, 0x02},
00177 {"Watchdog Time Channel 6", 0x042c, EC_RW, EC_R, 0x02},
00178 {"Watchdog Time Channel 7", 0x042e, EC_RW, EC_R, 0x02},
00179 {"Watchdog Time Channel 8", 0x0430, EC_RW, EC_R, 0x02},
00180 {"Watchdog Time Channel 9", 0x0432, EC_RW, EC_R, 0x02},
00181 {"Watchdog Time Channel 10", 0x0434, EC_RW, EC_R, 0x02},
00182 {"Watchdog Time Channel 11", 0x0436, EC_RW, EC_R, 0x02},
00183 {"Watchdog Time Channel 12", 0x0438, EC_RW, EC_R, 0x02},
00184 {"Watchdog Time Channel 13", 0x043a, EC_RW, EC_R, 0x02},
00185 {"Watchdog Time Channel 14", 0x043c, EC_RW, EC_R, 0x02},
00186 {"Watchdog Time Channel 15", 0x043e, EC_RW, EC_R, 0x02},
00187 {"Watchdog Channel status", 0x0450, EC_R, EC_R, 0x02},
00188 {"SII Eeprom Size", 0x0500, EC_R, EC_R, 0x02},
00189 {"SII Control/Status", 0x0502, EC_RW, EC_R, 0x02},
00190 {"SII Address", 0x0504, EC_RW, EC_R, 0x04},
00191 {"SII Data", 0x0508, EC_RW, EC_R, 0x04},
00192 {"FMMU0", 0x0600, EC_RW, EC_R, 0x10},
00193 {"FMMU1", 0x0610, EC_RW, EC_R, 0x10},
00194 {"FMMU2", 0x0620, EC_RW, EC_R, 0x10},
00195 {"FMMU3", 0x0630, EC_RW, EC_R, 0x10},
00196 {"FMMU4", 0x0640, EC_RW, EC_R, 0x10},
00197 {"FMMU5", 0x0650, EC_RW, EC_R, 0x10},
00198 {"FMMU6", 0x0660, EC_RW, EC_R, 0x10},
00199 {"FMMU7", 0x0670, EC_RW, EC_R, 0x10},
00200 {"FMMU8", 0x0680, EC_RW, EC_R, 0x10},
00201 {"FMMU9", 0x0690, EC_RW, EC_R, 0x10},
00202 {"FMMU10", 0x06A0, EC_RW, EC_R, 0x10},
00203 {"FMMU11", 0x06B0, EC_RW, EC_R, 0x10},
00204 {"FMMU12", 0x06C0, EC_RW, EC_R, 0x10},
00205 {"FMMU13", 0x06D0, EC_RW, EC_R, 0x10},
00206 {"FMMU14", 0x06E0, EC_RW, EC_R, 0x10},
00207 {"FMMU15", 0x06F0, EC_RW, EC_R, 0x10},
00208 {"Sync Manager 0", 0x0800, EC_RW, EC_R, 0x08},
00209 {"Sync Manager 1", 0x0808, EC_RW, EC_R, 0x08},
00210 {"Sync Manager 2", 0x0810, EC_RW, EC_R, 0x08},
00211 {"Sync Manager 3", 0x0818, EC_RW, EC_R, 0x08},
00212 {"Sync Manager 4", 0x0820, EC_RW, EC_R, 0x08},
00213 {"Sync Manager 5", 0x0828, EC_RW, EC_R, 0x08},
00214 {"Sync Manager 6", 0x0830, EC_RW, EC_R, 0x08},
00215 {"Sync Manager 7", 0x0838, EC_RW, EC_R, 0x08},
00216 {"Sync Manager 8", 0x0840, EC_RW, EC_R, 0x08},
00217 {"Sync Manager 9", 0x0848, EC_RW, EC_R, 0x08},
00218 {"Sync Manager 10", 0x0850, EC_RW, EC_R, 0x08},
00219 {"Sync Manager 11", 0x0858, EC_RW, EC_R, 0x08},
00220 {"Sync Manager 12", 0x0860, EC_RW, EC_R, 0x08},
00221 {"Sync Manager 13", 0x0868, EC_RW, EC_R, 0x08},
00222 {"Sync Manager 14", 0x0870, EC_RW, EC_R, 0x08},
00223 {"Sync Manager 15", 0x0878, EC_RW, EC_R, 0x08}
00224 };
00225 static inline int FMMUx(int channel)
00226 {
00227 switch (channel)
00228 {
00229 case 0:
00230 return FMMU_0;
00231 break;
00232 case 1:
00233 return FMMU_1;
00234 break;
00235 case 2:
00236 return FMMU_2;
00237 break;
00238 case 3:
00239 return FMMU_3;
00240 break;
00241 case 4:
00242 return FMMU_4;
00243 break;
00244 case 5:
00245 return FMMU_5;
00246 break;
00247 case 6:
00248 return FMMU_6;
00249 break;
00250 case 7:
00251 return FMMU_7;
00252 break;
00253 case 8:
00254 return FMMU_8;
00255 break;
00256 case 9:
00257 return FMMU_9;
00258 break;
00259 case 10:
00260 return FMMU_10;
00261 break;
00262 case 11:
00263 return FMMU_11;
00264 break;
00265 case 12:
00266 return FMMU_12;
00267 break;
00268 case 13:
00269 return FMMU_13;
00270 break;
00271 case 14:
00272 return FMMU_14;
00273 break;
00274 case 15:
00275 return FMMU_15;
00276 break;
00277 default:
00278 ec_log(EC_LOG_ERROR, "FMMUx: No such channel %d\n", channel);
00279 return -1;
00280 }
00281 }
00282 static inline int Sync_Managerx(int channel)
00283 {
00284 switch (channel)
00285 {
00286 case 0:
00287 return Sync_Manager_0;
00288 break;
00289 case 1:
00290 return Sync_Manager_1;
00291 break;
00292 case 2:
00293 return Sync_Manager_2;
00294 break;
00295 case 3:
00296 return Sync_Manager_3;
00297 break;
00298 case 4:
00299 return Sync_Manager_4;
00300 break;
00301 case 5:
00302 return Sync_Manager_5;
00303 break;
00304 case 6:
00305 return Sync_Manager_6;
00306 break;
00307 case 7:
00308 return Sync_Manager_7;
00309 break;
00310 case 8:
00311 return Sync_Manager_8;
00312 break;
00313 case 9:
00314 return Sync_Manager_9;
00315 break;
00316 case 10:
00317 return Sync_Manager_10;
00318 break;
00319 case 11:
00320 return Sync_Manager_11;
00321 break;
00322 case 12:
00323 return Sync_Manager_12;
00324 break;
00325 case 13:
00326 return Sync_Manager_13;
00327 break;
00328 case 14:
00329 return Sync_Manager_14;
00330 break;
00331 case 15:
00332 return Sync_Manager_15;
00333 break;
00334 default:
00335 ec_log(EC_LOG_ERROR, "Sync_Managerx: No such channel %d\n", channel);
00336 return -1;
00337 }
00338 }
00339 static inline int Watchdog_Time_Channelx(int channel)
00340 {
00341 switch (channel)
00342 {
00343 case 0:
00344 return Watchdog_Time_Channel_0;
00345 break;
00346 case 1:
00347 return Watchdog_Time_Channel_1;
00348 break;
00349 case 2:
00350 return Watchdog_Time_Channel_2;
00351 break;
00352 case 3:
00353 return Watchdog_Time_Channel_3;
00354 break;
00355 case 4:
00356 return Watchdog_Time_Channel_4;
00357 break;
00358 case 5:
00359 return Watchdog_Time_Channel_5;
00360 break;
00361 case 6:
00362 return Watchdog_Time_Channel_6;
00363 break;
00364 case 7:
00365 return Watchdog_Time_Channel_7;
00366 break;
00367 case 8:
00368 return Watchdog_Time_Channel_8;
00369 break;
00370 case 9:
00371 return Watchdog_Time_Channel_9;
00372 break;
00373 case 10:
00374 return Watchdog_Time_Channel_10;
00375 break;
00376 case 11:
00377 return Watchdog_Time_Channel_11;
00378 break;
00379 case 12:
00380 return Watchdog_Time_Channel_12;
00381 break;
00382 case 13:
00383 return Watchdog_Time_Channel_13;
00384 break;
00385 case 14:
00386 return Watchdog_Time_Channel_14;
00387 break;
00388 case 15:
00389 return Watchdog_Time_Channel_15;
00390 break;
00391 default:
00392 ec_log(EC_LOG_ERROR, "Watchdog_Time_Channelx: No such channel %d\n", channel);
00393 return -1;
00394 }
00395 }
00396
00398
00399 class EC_DLInformation : public EC_DataStruct
00400 {
00401 public:
00402 EC_DLInformation(uint8_t type,
00403 uint8_t revision,
00404 uint16_t build,
00405 uint8_t no_of_supp_fmmu_channels,
00406 uint8_t no_of_supp_syncman_channels,
00407 uint8_t ram_size,
00408 bool fmmu_bit_operation_not_supp);
00409 EC_DLInformation(const unsigned char * a_buffer);
00410
00411 virtual unsigned char * dump(unsigned char * a_buffer) const;
00412
00413 uint8_t Type;
00414 uint8_t Revision;
00415 uint16_t Build;
00416 uint8_t NoOfSuppFmmuChannels;
00417 uint8_t NoOfSuppSyncManChannels;
00418 uint8_t RamSize;
00419
00420 bool FmmuBitOperationNotSupp;
00421
00422
00423 };
00424
00426
00427 class EC_FixedStationAddress : public EC_DataStruct
00428 {
00429 public:
00430 EC_FixedStationAddress(uint16_t fixed_station_address = 0x0000) :
00431 EC_DataStruct(EC_Slave_RD[ECAT_Station_Address].size), FixedStationAddress(
00432 fixed_station_address){ }
00433 EC_FixedStationAddress(const unsigned char * data) :
00434 EC_DataStruct(EC_Slave_RD[ECAT_Station_Address].size)
00435 {
00436 nw2host(data, FixedStationAddress);
00437 }
00438 virtual unsigned char * dump(unsigned char * a_buffer) const
00439 {
00440 return host2nw(a_buffer, FixedStationAddress);
00441 }
00442 void operator=(const EC_FixedStationAddress & ad)
00443 {
00444 this->FixedStationAddress = ad.FixedStationAddress;
00445 }
00446 bool operator==(const EC_FixedStationAddress & ad) const
00447 {
00448 return (this->FixedStationAddress == ad.FixedStationAddress);
00449 }
00450 operator uint16_t() const
00451 {
00452 return FixedStationAddress;
00453 }
00454 private:
00456 uint16_t FixedStationAddress;
00457 };
00458
00459
00460
00461 enum EC_State
00462 {
00463 EC_INIT_STATE = 0x01,
00464 EC_PREOP_STATE = 0x02,
00465 EC_BOOTSTRAP_STATE = 0x03,
00466 EC_SAFEOP_STATE = 0x04,
00467 EC_OP_STATE = 0x08
00468 };
00469
00471
00472 class EC_ALControl : public EC_DataStruct
00473 {
00474 public:
00476
00482 EC_ALControl(EC_State state = EC_INIT_STATE,
00483 bool ack = false);
00485 EC_ALControl(const unsigned char * a_buffer);
00486
00487 virtual unsigned char * dump(unsigned char * a_buffer) const;
00488
00489 EC_State State;
00490 bool Acknowledge;
00491
00492 };
00493
00495
00496 class EC_ALStatus : public EC_DataStruct
00497 {
00498 public:
00500
00505 EC_ALStatus(EC_State state = EC_INIT_STATE,
00506 bool change = false);
00508 EC_ALStatus(const unsigned char * a_buffer);
00509
00510 virtual unsigned char * dump(unsigned char * a_buffer) const;
00511
00512 EC_State State;
00513 bool Change;
00514
00515 };
00516
00518
00519 class EC_SIIControlStatus : public EC_DataStruct
00520 {
00521 public:
00523 EC_SIIControlStatus(bool eeprom_write_access = false,
00524 bool eeprom_address_algorithm = false,
00525 bool read_op = false,
00526 bool write_op = false,
00527 bool reload_op = false,
00528 bool write_error = false,
00529 bool busy = false);
00531 EC_SIIControlStatus(const unsigned char * a_buffer);
00532
00533 virtual unsigned char * dump(unsigned char * a_buffer) const;
00534
00536 bool EepromWriteAccess;
00537
00538 bool EepromAddressAlgorithm;
00540 bool ReadOp;
00542 bool WriteOp;
00544 bool ReloadOp;
00546 bool WriteError;
00548 bool Busy;
00549
00550 bool AcknowledgeError;
00551 };
00552
00554
00555 class EC_BitPos
00556 {
00557 public:
00559
00561 EC_BitPos(uint8_t a_int = 0)
00562 {
00563
00564 assert(a_int < 8);
00565 m_bitpos = a_int;
00566 }
00568 operator uint8_t() const
00569 {
00570 return m_bitpos;
00571 }
00572 private:
00573 uint8_t m_bitpos;
00574 };
00575
00577
00578 class EC_FMMU : public EC_DataStruct
00579 {
00580 public:
00582 EC_FMMU(uint32_t logical_start_address = 0x00000000,
00583 uint16_t length = 0x0000,
00584 EC_BitPos logical_start_bit = 0x00,
00585 EC_BitPos logical_end_bit = 0x00,
00586 uint16_t physical_start_address = 0x0000,
00587 EC_BitPos physical_start_bit = 0x00,
00588 bool read_enable = false,
00589 bool write_enable = false,
00590 bool channel_enable = false);
00592 EC_FMMU(const unsigned char * a_buffer);
00593
00594 virtual unsigned char * dump(unsigned char * a_buffer) const;
00595
00596 uint32_t LogicalStartAddress;
00597 uint16_t Length;
00598 EC_BitPos LogicalStartBit;
00599
00600 EC_BitPos LogicalEndBit;
00601
00602 uint16_t PhysicalStartAddress;
00603 EC_BitPos PhysicalStartBit;
00604
00605 bool ReadEnable;
00606 bool WriteEnable;
00607
00608 bool ChannelEnable;
00609
00610
00611
00612 };
00613
00614
00615
00616 enum ECBufferType
00617 {
00618 EC_BUFFERED = 0x00,
00619 EC_QUEUED = 0x02,
00620 };
00621
00623
00626 class EC_BufferType
00627 {
00628 public:
00630
00632 EC_BufferType(ECBufferType bt = EC_BUFFERED)
00633 {
00634 m_buffertype = (uint8_t) bt;
00635 }
00636
00638 operator uint8_t() const
00639 {
00640 return m_buffertype;
00641 }
00642 private:
00643 uint8_t m_buffertype;
00644 };
00645
00646 enum ECDirection
00647 {
00648 EC_READ_FROM_MASTER = 0x00,
00649 EC_WRITTEN_FROM_MASTER = 0x01,
00650 };
00651
00653
00656 class EC_Direction
00657 {
00658 public:
00660
00665 EC_Direction(ECDirection dir = EC_READ_FROM_MASTER)
00666 {
00667 m_direction = (uint8_t) dir;
00668 }
00670 operator uint8_t() const
00671 {
00672 return m_direction;
00673 }
00674 private:
00675 uint8_t m_direction;
00676 };
00677
00678 enum ECBufferedState
00679 {
00680 EC_FIRST_BUFFER = 0x00,
00681 EC_SECOND_BUFFER = 0x01,
00682 EC_THIRD_BUFFER = 0x02,
00683 EC_LOCKED_BUFFER = 0x03,
00684 };
00685
00687
00690 class EC_BufferedState
00691 {
00692 public:
00694
00701 EC_BufferedState(ECBufferedState state = EC_FIRST_BUFFER)
00702 {
00703 m_buffered_state = (uint8_t) state;
00704 }
00706 operator uint8_t() const
00707 {
00708 return m_buffered_state;
00709 }
00710 private:
00711 uint8_t m_buffered_state;
00712 };
00713
00714 static const bool EC_QUEUED_STATE_READ = false;
00715 static const bool EC_QUEUED_STATE_WRITTEN = true;
00716
00718
00719 class EC_SyncMan : public EC_DataStruct
00720 {
00721 public:
00723 EC_SyncMan(uint16_t physical_start_address = 0x0000,
00724 uint16_t length = 0x0000,
00725 EC_BufferType buffer_type = EC_BUFFERED,
00726 EC_Direction direction = EC_READ_FROM_MASTER,
00727 bool AL_event_enable = false,
00728 bool watchdog_enable = false,
00729 bool write_event = false,
00730 bool read_event = false,
00731 bool watchdog_trigger = false,
00732 bool queued_state = EC_QUEUED_STATE_READ,
00733 EC_BufferedState buffered_state = EC_FIRST_BUFFER,
00734 bool ChannelEnable = false);
00736 EC_SyncMan(const unsigned char * a_buffer);
00737
00738 virtual unsigned char * dump(unsigned char * a_buffer) const;
00739
00740 uint16_t PhysicalStartAddress;
00741 uint16_t Length;
00742 EC_BufferType BufferType;
00743 EC_Direction Direction;
00744 bool ALEventEnable;
00745 bool ECATEventEnable;
00746 bool WatchdogEnable;
00747 bool WriteEvent;
00748 bool ReadEvent;
00749 bool WatchdogTrigger;
00750 bool QueuedState;
00751 EC_BufferedState BufferedState;
00752 bool ChannelEnable;
00753 };
00754
00755 #endif // __ethercat_slave_memory_h__