Ahmed HADDAD / EasyCAT_lib

Dependents:   MOTION_LCD

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EasyCAT.h Source File

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