Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
EasyCAT.h
00001 //******************************************************************************************** 00002 // * 00003 // AB&T Tecnologie Informatiche - Ivrea Italy * 00004 // http://www.bausano.net * 00005 // https://www.ethercat.org/en/products/791FFAA126AD43859920EA64384AD4FD.htm * 00006 // * 00007 //******************************************************************************************** 00008 // * 00009 // This software is distributed as an example, in the hope that it could be useful, * 00010 // WITHOUT ANY WARRANTY, even the implied warranty of FITNESS FOR A PARTICULAR PURPOSE * 00011 // * 00012 //******************************************************************************************** 00013 00014 00015 //----- EasyCAT library for mbed boards 170912 ---------------------------------------------- 00016 //----- Derived from the AB&T EasyCAT Arduino shield library V 1.5 -------------------------- 00017 00018 //----- Tested with the STM32 NUCLEO-F767ZI board ------------------------------------------- 00019 00020 00021 00022 00023 #ifndef EasyCAT_H 00024 #define EasyCAT_H 00025 00026 00027 00028 00029 //****** PDO configuration parameters ******************************************************** 00030 00031 // Here we can define how many I/O bytes our EasyCAT can exchange 00032 00033 // We can use STANDARD MODE or CUSTOM MODE 00034 // !!! Warning: CUSTOM MODE is recommended only for advanced users !!! 00035 00036 // In STANDARD MODE the EasyCAT exchanges a fixed number of bytes 00037 // in input and in output 00038 // The number of bytes in input are equal to the number of bytes in output 00039 // Valid values are 16, 32, 64, 128 00040 // 00041 // The configuration EEPROM on board of the EasyCAT must be 00042 // loaded with the corresponding bin file, provided by AB&T 00043 // 00044 // The EasyCAT is shipped configured for 32+32 bytes I.E. with 00045 // the "EasyCAT_32_32.bin" file loaded into the configuration EEPROM 00046 00047 00048 //-- BYTE_NUM ----------- Byte exchanged ------ Config EEPROM file 00049 00050 //#define BYTE_NUM 16 // 16 + 16 EasyCAT_16_16.bin 00051 //#define BYTE_NUM 32 // 32 + 32 EasyCAT_32_32.bin 00052 //#define BYTE_NUM 64 // 64 + 64 EasyCAT_64_64.bin 00053 //#define BYTE_NUM 128 // 128 + 128 EasyCAT_128_128.bin 00054 00055 00056 00057 // In CUSTOM MODE, recommended only for advanced users, the EasyCAT exchanges 00058 // a configurable number of bytes, between 0 and 128, in input and in output 00059 // The number of bytes in input and in output can be different 00060 // 00061 // The configuration EEPROM on board of the EasyCAT must be 00062 // loaded with a suitable bin file, provided by the user 00063 // or with the "EasyCAT_configurable.bin" file provided by AB&T 00064 00065 // Comment all the above BYTE_NUM #define for the STANDARD MODE 00066 // and define here the custom number of exchanged bytes 00067 00068 //----- CUSTOM_MODE example ------- 00069 // 00070 #define CUST_BYTE_NUM_OUT 8 // total number of bytes in output 00071 #define CUST_BYTE_NUM_IN 24 // total number of bytes in input 00072 00073 // We can also customize names and data types for the PDOs 00074 // see the example in this file (look for tag "Custom data types example") 00075 00076 //************************************************************************************* 00077 00078 00079 00080 //-- the preprocessor calculates the parameters necessary to transfer out data --- 00081 00082 // define TOT_BYTE_NUM_OUT as the total 00083 // number of byte you need to 00084 // transfer in output (between 0 and 128) 00085 // this must match your ESI XML 00086 00087 #ifdef BYTE_NUM 00088 #define TOT_BYTE_NUM_OUT BYTE_NUM // bytes in output 00089 #else 00090 #define TOT_BYTE_NUM_OUT CUST_BYTE_NUM_OUT // any number between 0 and 128 00091 #endif 00092 00093 00094 #if ((TOT_BYTE_NUM_OUT & 0x03) != 0x00) // number of bytes in output 00095 #define TOT_BYTE_NUM_ROUND_OUT ((TOT_BYTE_NUM_OUT | 0x03) + 1) 00096 #else // rounded to 4 (long) 00097 #define TOT_BYTE_NUM_ROUND_OUT TOT_BYTE_NUM_OUT // 00098 #endif // 00099 00100 #if TOT_BYTE_NUM_OUT > 64 // if we have more then 64 bytes 00101 // we have to split the transfer in two 00102 00103 #define SEC_BYTE_NUM_OUT (TOT_BYTE_NUM_OUT - 64) // number of bytes of the second transfer 00104 00105 #if ((SEC_BYTE_NUM_OUT & 0x03) != 0x00) // number of bytes of the second transfer 00106 #define SEC_BYTE_NUM_ROUND_OUT ((SEC_BYTE_NUM_OUT | 0x03) + 1) 00107 #else // rounded to 4 (long) 00108 #define SEC_BYTE_NUM_ROUND_OUT SEC_BYTE_NUM_OUT// 00109 #endif // 00110 00111 #define SEC_LONG_NUM_OUT SEC_BYTE_NUM_ROUND_OUT/4// number of long of the second transfer 00112 00113 #define FST_BYTE_NUM_OUT 64 // number of bytes of the first transfer 00114 #define FST_BYTE_NUM_ROUND_OUT 64 // number of bytes of the first transfer 00115 // rounded to 4 (long) 00116 #define FST_LONG_NUM_OUT 16 // number of long of the second transfer 00117 00118 00119 #else // if we have 64 bytes max we tranfert 00120 // them in just one round 00121 00122 #define FST_BYTE_NUM_OUT TOT_BYTE_NUM_OUT // number of bytes of the first and only transfer 00123 00124 #if ((FST_BYTE_NUM_OUT & 0x03) != 0x00) // number of bytes of the first and only transfer 00125 #define FST_BYTE_NUM_ROUND_OUT ((FST_BYTE_NUM_OUT | 0x03) + 1) 00126 #else // rounded to 4 (long) 00127 #define FST_BYTE_NUM_ROUND_OUT FST_BYTE_NUM_OUT 00128 #endif 00129 00130 #define FST_LONG_NUM_OUT FST_BYTE_NUM_ROUND_OUT/4// number of long of the first and only transfer 00131 00132 #define SEC_BYTE_NUM_OUT 0 // we don't use the second round 00133 #define SEC_BYTE_NUM_ROUND_OUT 0 // 00134 #define SEC_LONG_NUM_OUT 0 // 00135 00136 #endif 00137 00138 00139 //-- the preprocessor calculates the parameters necessary to transfer in data --- 00140 00141 // define TOT_BYTE_NUM_IN the total 00142 // number of byte you need to 00143 // transfer in input (between 0 and 128) 00144 00145 #ifdef BYTE_NUM 00146 #define TOT_BYTE_NUM_IN BYTE_NUM // bytes in input 00147 #else 00148 #define TOT_BYTE_NUM_IN CUST_BYTE_NUM_IN // any number between 0 and 128 00149 #endif 00150 00151 00152 #if ((TOT_BYTE_NUM_IN & 0x03) != 0x00) // number of bytes in output 00153 #define TOT_BYTE_NUM_ROUND_IN ((TOT_BYTE_NUM_IN | 0x03) + 1) 00154 #else // rounded to 4 (long) 00155 #define TOT_BYTE_NUM_ROUND_IN TOT_BYTE_NUM_IN // 00156 #endif // 00157 00158 #if TOT_BYTE_NUM_IN > 64 // if we have more then 64 bytes 00159 // we have to split the transfer in two 00160 00161 #define SEC_BYTE_NUM_IN (TOT_BYTE_NUM_IN - 64) // number of bytes of the second transfer 00162 00163 #if ((SEC_BYTE_NUM_IN & 0x03) != 0x00) // number of bytes of the second transfer 00164 #define SEC_BYTE_NUM_ROUND_IN ((SEC_BYTE_NUM_IN | 0x03) + 1) 00165 #else // rounded to 4 (long) 00166 #define SEC_BYTE_NUM_ROUND_IN SEC_BYTE_NUM_IN // 00167 #endif // 00168 00169 #define SEC_LONG_NUM_IN SEC_BYTE_NUM_ROUND_IN/4 // number of long of the second transfer 00170 00171 #define FST_BYTE_NUM_IN 64 // number of bytes of the first transfer 00172 #define FST_BYTE_NUM_ROUND_IN 64 // number of bytes of the first transfer 00173 // rounded to 4 (long) 00174 #define FST_LONG_NUM_IN 16 // number of long of the second transfer 00175 00176 00177 #else // if we have 64 bytes max we tranfert 00178 // them in just one round 00179 00180 #define FST_BYTE_NUM_IN TOT_BYTE_NUM_IN // number of bytes of the first and only transfer 00181 00182 #if ((FST_BYTE_NUM_IN & 0x03) != 0x00) // number of bytes of the first and only transfer 00183 #define FST_BYTE_NUM_ROUND_IN ((FST_BYTE_NUM_IN | 0x03) + 1) 00184 #else // rounded to 4 (long) 00185 #define FST_BYTE_NUM_ROUND_IN FST_BYTE_NUM_IN 00186 #endif 00187 00188 #define FST_LONG_NUM_IN FST_BYTE_NUM_ROUND_IN/4 // number of long of the first and only transfer 00189 00190 #define SEC_BYTE_NUM_IN 0 // we don't use the second round 00191 #define SEC_BYTE_NUM_ROUND_IN 0 // 00192 #define SEC_LONG_NUM_IN 0 // 00193 00194 #endif 00195 00196 00197 //--------------------------------------------------------------------------------- 00198 00199 //----------------- sanity check ------------------------------------------------------- 00200 00201 00202 #ifdef BYTE_NUM // STANDARD MODE and CUSTOM MODE 00203 // cannot be defined at the same time 00204 #ifdef CUST_BYTE_NUM_OUT 00205 #error "BYTE_NUM and CUST_BYTE_NUM_OUT cannot be defined at the same time !!!!" 00206 #error "define them correctly in file EasyCAT.h" 00207 #endif 00208 00209 #ifdef CUST_BYTE_NUM_IN 00210 #error "BYTE_NUM and CUST_BYTE_NUM_IN cannot be defined at the same time !!!!" 00211 #error "define them correctly in file EasyCAT.h" 00212 #endif 00213 #endif 00214 00215 #ifdef BYTE_NUM //--- for BYTE_NUM we accept only 16 32 64 128 -- 00216 00217 #if ((BYTE_NUM !=16) && (BYTE_NUM !=32) && (BYTE_NUM !=64) && (BYTE_NUM !=128)) 00218 #error "BYTE_NUM must be 16, 32, 64 or 128 !!! define it correctly in file EasyCAT.h" 00219 #endif 00220 00221 #else 00222 //--- CUST_BYTE_NUM_OUT and CUST_BYTE_NUM_IN -------- 00223 // must be max 128 00224 #if (CUST_BYTE_NUM_OUT > 128) 00225 #error "CUST_BYTE_NUM_OUT must be max 128 !!! define it correctly in file EasyCAT.h" 00226 #endif 00227 00228 #if (CUST_BYTE_NUM_IN > 128) 00229 #error "CUST_BYTE_NUM_IN must be max 128 !!! define it correctly in file EasyCAT.h" 00230 #endif 00231 00232 #endif 00233 00234 00235 //************************************************************************************************* 00236 00237 00238 00239 00240 //---- LAN9252 registers -------------------------------------------------------------------------- 00241 00242 //---- access to EtherCAT registers ------------------- 00243 00244 #define ECAT_CSR_DATA 0x0300 // EtherCAT CSR Interface Data Register 00245 #define ECAT_CSR_CMD 0x0304 // EtherCAT CSR Interface Command Register 00246 00247 00248 //---- access to EtherCAT process RAM ----------------- 00249 00250 #define ECAT_PRAM_RD_ADDR_LEN 0x0308 // EtherCAT Process RAM Read Address and Length Register 00251 #define ECAT_PRAM_RD_CMD 0x030C // EtherCAT Process RAM Read Command Register 00252 #define ECAT_PRAM_WR_ADDR_LEN 0x0310 // EtherCAT Process RAM Write Address and Length Register 00253 #define ECAT_PRAM_WR_CMD 0x0314 // EtherCAT Process RAM Write Command Register 00254 00255 #define ECAT_PRAM_RD_DATA 0x0000 // EtherCAT Process RAM Read Data FIFO 00256 #define ECAT_PRAM_WR_DATA 0x0020 // EtherCAT Process RAM Write Data FIFO 00257 00258 //---- EtherCAT registers ----------------------------- 00259 00260 #define AL_STATUS 0x0130 // AL status 00261 #define WDOG_STATUS 0x0440 // watch dog status 00262 #define AL_EVENT_MASK 0x0204 // AL event interrupt mask 00263 00264 //---- LAN9252 registers ------------------------------ 00265 00266 #define HW_CFG 0x0074 // hardware configuration register 00267 #define BYTE_TEST 0x0064 // byte order test register 00268 #define RESET_CTL 0x01F8 // reset register 00269 #define ID_REV 0x0050 // chip ID and revision 00270 #define IRQ_CFG 0x0054 // interrupt configuration 00271 #define INT_EN 0x005C // interrupt enable 00272 00273 00274 //---- LAN9252 flags ------------------------------------------------------------------------------ 00275 00276 #define ECAT_CSR_BUSY 0x80 00277 00278 #define PRAM_ABORT 0x40000000 00279 00280 #define PRAM_BUSY 0x80 00281 00282 #define PRAM_AVAIL 0x01 00283 00284 #define READY 0x08 00285 00286 #define DIGITAL_RST 0x00000001 00287 00288 00289 //---- EtherCAT flags ----------------------------------------------------------------------------- 00290 00291 // EtherCAT state machine 00292 00293 #define ESM_INIT 0x01 // init 00294 #define ESM_PREOP 0x02 // pre-operational 00295 #define ESM_BOOT 0x03 // bootstrap 00296 #define ESM_SAFEOP 0x04 // safe-operational 00297 #define ESM_OP 0x08 // operational 00298 00299 00300 //--- ESC commands -------------------------------------------------------------------------------- 00301 00302 #define ESC_WRITE 0x80 00303 #define ESC_READ 0xC0 00304 00305 00306 //---- SPI ---------------------------------------------------------------------------------------- 00307 00308 #define COMM_SPI_READ 0x03 00309 #define COMM_SPI_WRITE 0x02 00310 00311 #define DUMMY_BYTE 0xFF 00312 00313 00314 00315 //---- typedef ------------------------------------------------------------------------------------ 00316 00317 typedef union 00318 { 00319 unsigned short Word; 00320 unsigned char Byte[2]; 00321 } UWORD; 00322 00323 typedef union 00324 { 00325 unsigned long Long; 00326 unsigned short Word[2]; 00327 unsigned char Byte[4]; 00328 } ULONG; 00329 00330 00331 typedef union //-- output buffer ----------------- 00332 { // 00333 uint8_t Byte [TOT_BYTE_NUM_ROUND_OUT]; // 00334 00335 #if CUST_BYTE_NUM_OUT > 0 //----- Custom data types example ----- 00336 // 00337 struct // Here we can define our custom 00338 { float Running_Time_T ; // data types and names for the outputs 00339 // 00340 // The total number of bytes declared 00341 uint8_t State_Step_T ; // in this structure must be equal 00342 uint8_t Status_Driver_T ; // to the value assigned to CUST_BYTE_NUM_OUT 00343 uint8_t END_T ; 00344 uint8_t EtherCAT ; // In this case 1+ 4+4+4+ 4+4+4+ 4+4+4+ 4+4+4 = 49 00345 }Cust; // 00346 00347 #endif // 00348 00349 } PROCBUFFER_OUT; // 00350 00351 00352 typedef union //-- input buffer ------------------ 00353 { // 00354 uint8_t Byte [TOT_BYTE_NUM_ROUND_IN]; // 00355 00356 #if CUST_BYTE_NUM_IN > 0 //----- Custom data types example ------ 00357 // 00358 struct // Here we can define our custom 00359 { float Standing_Time_T ; 00360 float Step_Time_T ; 00361 float Wait_COM_Tr_Time_T ; 00362 float COM_Tr_Threshold_T ; 00363 00364 // data types and names for the inputs 00365 int8_t Enable; 00366 int8_t EnableLateral; 00367 int8_t QuickStop; 00368 int8_t ClearFault; 00369 00370 00371 00372 int8_t Stand; 00373 int8_t Start; 00374 int8_t Stepping; 00375 int8_t EndStep; 00376 00377 00378 00379 00380 00381 }Cust; // 00382 // 00383 #endif // 00384 00385 } PROCBUFFER_IN; // 00386 00387 00388 typedef enum 00389 { 00390 ASYNC, 00391 DC_SYNC, 00392 SM_SYNC 00393 }SyncMode; 00394 00395 00396 00397 //------------------------------------------------------------------------------------------------- 00398 00399 class EasyCAT 00400 { 00401 public: 00402 EasyCAT(); // default constructor 00403 EasyCAT(PinName SCS); 00404 EasyCAT(SyncMode Sync); 00405 EasyCAT(PinName SCS, SyncMode Sync); 00406 00407 00408 unsigned char MainTask(); // EtherCAT main task 00409 // must be called cyclically by the application 00410 00411 bool Init(); // EasyCAT board initialization 00412 00413 PROCBUFFER_OUT BufferOut; // output process data buffer 00414 PROCBUFFER_IN BufferIn; // input process data buffer 00415 00416 00417 private: 00418 void SPIWriteRegisterDirect (unsigned short Address, unsigned long DataOut); 00419 unsigned long SPIReadRegisterDirect (unsigned short Address, unsigned char Len); 00420 00421 void SPIWriteRegisterIndirect (unsigned long DataOut, unsigned short Address, unsigned char Len); 00422 unsigned long SPIReadRegisterIndirect (unsigned short Address, unsigned char Len); 00423 00424 void SPIReadProcRamFifo(); 00425 void SPIWriteProcRamFifo(); 00426 00427 PinName SCS_; 00428 SyncMode Sync_; 00429 }; 00430 00431 #endif
Generated on Wed Jul 20 2022 19:41:42 by
