ethercatconfig.c

Go to the documentation of this file.
00001 /*
00002  * Simple Open EtherCAT Master Library 
00003  *
00004  * File    : ethercatconfig.c
00005  * Version : 1.2.5
00006  * Date    : 09-04-2011
00007  * Copyright (C) 2005-2011 Speciaal Machinefabriek Ketels v.o.f.
00008  * Copyright (C) 2005-2011 Arthur Ketels
00009  * Copyright (C) 2008-2009 TU/e Technische Universiteit Eindhoven 
00010  *
00011  * SOEM is free software; you can redistribute it and/or modify it under
00012  * the terms of the GNU General Public License version 2 as published by the Free
00013  * Software Foundation.
00014  *
00015  * SOEM is distributed in the hope that it will be useful, but WITHOUT ANY
00016  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00017  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00018  * for more details.
00019  *
00020  * As a special exception, if other files instantiate templates or use macros
00021  * or inline functions from this file, or you compile this file and link it
00022  * with other works to produce a work based on this file, this file does not
00023  * by itself cause the resulting work to be covered by the GNU General Public
00024  * License. However the source code for this file must still be made available
00025  * in accordance with section (3) of the GNU General Public License.
00026  *
00027  * This exception does not invalidate any other reasons why a work based on
00028  * this file might be covered by the GNU General Public License.
00029  *
00030  * The EtherCAT Technology, the trade name and logo “EtherCAT” are the intellectual
00031  * property of, and protected by Beckhoff Automation GmbH. You can use SOEM for
00032  * the sole purpose of creating, using and/or selling or otherwise distributing
00033  * an EtherCAT network master provided that an EtherCAT Master License is obtained
00034  * from Beckhoff Automation GmbH.
00035  *
00036  * In case you did not receive a copy of the EtherCAT Master License along with
00037  * SOEM write to Beckhoff Automation GmbH, Eiserstraße 5, D-33415 Verl, Germany
00038  * (www.beckhoff.com).
00039  */
00040 
00041 /** \file
00042  * \brief
00043  * Configuration module for EtherCAT master.
00044  *
00045  * After successful initialisation with ec_init() or ec_init_redundant()
00046  * the slaves can be auto configured with this module.
00047  */
00048 
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <sys/time.h>
00052 #include <unistd.h>
00053 #include "ethercattype.h"
00054 #include "nicdrv.h"
00055 #include "ethercatbase.h"
00056 #include "ethercatmain.h"
00057 #include "ethercatcoe.h"
00058 #include "ethercatsoe.h"
00059 #include "ethercatconfig.h"
00060 
00061 // define if debug printf is needed
00062 //#define EC_DEBUG
00063 
00064 #ifdef EC_DEBUG
00065 #define EC_PRINT printf
00066 #else
00067 #define EC_PRINT(...) do {} while (0)
00068 #endif
00069 
00070 /** Slave configuration structure */
00071 typedef const struct
00072 {
00073   /** Manufacturer code of slave */
00074   uint32        man;
00075   /** ID of slave */
00076   uint32        id;
00077   /** Readable name */
00078   char        name[EC_MAXNAME + 1];
00079   /** Data type */
00080   uint8       Dtype;
00081   /** Input bits */
00082   uint16        Ibits;
00083   /** Output bits */
00084   uint16        Obits;
00085   /** SyncManager 2 address */
00086   uint16        SM2a;
00087   /** SyncManager 2 flags */
00088   uint32        SM2f;
00089   /** SyncManager 3 address */
00090   uint16        SM3a;
00091   /** SyncManager 3 flags */
00092   uint32        SM3f;
00093   /** FMMU 0 activation */
00094   uint8       FM0ac;
00095   /** FMMU 1 activation */
00096   uint8       FM1ac;
00097 } ec_configlist_t;
00098 
00099 #include "ethercatconfiglist.h"
00100 
00101 /** standard SM0 flags configuration for mailbox slaves */
00102 #define EC_DEFAULTMBXSM0  0x00010026
00103 /** standard SM1 flags configuration for mailbox slaves */
00104 #define EC_DEFAULTMBXSM1  0x00010022
00105 /** standard SM0 flags configuration for digital output slaves */
00106 #define EC_DEFAULTDOSM0   0x00010044
00107 
00108 /** buffer for EEPROM SM data */
00109 static ec_eepromSMt ec_SM;
00110 /** buffer for EEPROM FMMU data */
00111 static ec_eepromFMMUt ec_FMMU;
00112 
00113 /** Find slave in standard configuration list ec_configlist[]
00114  *
00115  * @param[in] man    = manufacturer
00116  * @param[in] id     = ID
00117  * @return index in ec_configlist[] when found, otherwise 0
00118  */
00119 int ec_findconfig( uint32 man, uint32 id)
00120 {
00121   int i = 0;
00122 
00123   do 
00124   {
00125     i++;
00126   } while ( (ec_configlist[i].man != EC_CONFIGEND) && 
00127         ((ec_configlist[i].man != man) || (ec_configlist[i].id != id)) );
00128   if (ec_configlist[i].man == EC_CONFIGEND)
00129     i = 0;
00130   
00131   return i;
00132 }
00133 
00134 /** Enumerate and init all slaves.
00135  *
00136  * @param[in] usetable    = TRUE when using configtable to init slaves, FALSE otherwise
00137  * @return Workcounter of slave discover datagram = number of slaves found
00138  */
00139 int ec_config_init(uint8 usetable)
00140 {
00141     uint16 w, slave, ADPh, configadr, mbx_wo, mbx_ro, mbx_l, mbx_rl, ssigen;
00142     uint16 topology, estat;
00143     int16 topoc, slavec;
00144     uint8 b,h;
00145   uint8 zbuf[64];
00146   uint8 SMc;
00147   uint32 eedat;
00148   int wkc, cindex, nSM, lp;
00149 
00150   EC_PRINT("ec_config_init %d\n",usetable);
00151     ec_slavecount = 0;
00152   /* clean ec_slave array */
00153   memset(&ec_slave, 0x00, sizeof(ec_slave));
00154   memset(&zbuf, 0x00, sizeof(zbuf));
00155   memset(&ec_group, 0x00, sizeof(ec_group));
00156   for(lp = 0; lp < EC_MAXGROUP; lp++)
00157   {
00158     ec_group[lp].logstartaddr = lp << 16; /* default start address per group entry */
00159   }
00160     w = 0x0000;
00161     wkc = ec_BRD(0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE);    /* detect number of slaves */
00162     if (wkc > 0)
00163     {
00164         ec_slavecount = wkc;
00165         b = 0x00;
00166         ec_BWR(0x0000, ECT_REG_DLPORT, sizeof(b), &b, EC_TIMEOUTRET);   /* deact loop manual */
00167         w = htoes(0x0004);
00168         ec_BWR(0x0000, ECT_REG_IRQMASK, sizeof(w), &w, EC_TIMEOUTRET);    /* set IRQ mask */
00169         ec_BWR(0x0000, ECT_REG_RXERR, 8, &zbuf, EC_TIMEOUTRET);       /* reset CRC counters */
00170         ec_BWR(0x0000, ECT_REG_FMMU0, 16 * 3, &zbuf, EC_TIMEOUTRET);    /* reset FMMU's */
00171         ec_BWR(0x0000, ECT_REG_SM0, 8 * 4, &zbuf, EC_TIMEOUTRET);     /* reset SyncM */
00172         ec_BWR(0x0000, ECT_REG_DCSYSTIME, 4, &zbuf, EC_TIMEOUTRET);     /* reset system time+ofs */
00173         w = htoes(0x1000);
00174         ec_BWR(0x0000, ECT_REG_DCSPEEDCNT, sizeof(w), &w, EC_TIMEOUTRET);   /* DC speedstart */
00175         w = htoes(0x0c00);
00176         ec_BWR(0x0000, ECT_REG_DCTIMEFILT, sizeof(w), &w, EC_TIMEOUTRET);   /* DC filt expr */
00177         b = 0x00;
00178         ec_BWR(0x0000, ECT_REG_DLALIAS, sizeof(b), &b, EC_TIMEOUTRET);    /* Ignore Alias register */
00179         b = EC_STATE_INIT | EC_STATE_ACK;
00180         ec_BWR(0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET);    /* Reset all slaves to Init */
00181     b = 2;
00182     ec_BWR(0x0000, ECT_REG_EEPCFG, sizeof(b), &b , EC_TIMEOUTRET);    /* force Eeprom from PDI */
00183     b = 0;
00184     ec_BWR(0x0000, ECT_REG_EEPCFG, sizeof(b), &b , EC_TIMEOUTRET);    /* set Eeprom to master */
00185     
00186         for (slave = 1; slave <= ec_slavecount; slave++)
00187         {
00188             ADPh = (uint16)(1 - slave);
00189             ec_slave[slave].Itype = etohs(ec_APRDw(ADPh, ECT_REG_PDICTL, EC_TIMEOUTRET)); /* read interface type of slave */
00190       /* a node offset is used to improve readibility of network frames */
00191       /* this has no impact on the number of addressable slaves (auto wrap around) */
00192             ec_APWRw(ADPh, ECT_REG_STADR, htoes(slave + EC_NODEOFFSET) , EC_TIMEOUTRET); /* set node address of slave */
00193             if (slave == 1) 
00194         b = 1; /* kill non ecat frames for first slave */
00195       else 
00196         b = 0; /* pass all frames for following slaves */
00197             ec_APWRw(ADPh, ECT_REG_DLCTL, htoes(b), EC_TIMEOUTRET); /* set non ecat frame behaviour */
00198             configadr = etohs(ec_APRDw(ADPh, ECT_REG_STADR, EC_TIMEOUTRET));
00199             ec_slave[slave].configadr = configadr;
00200       ec_FPRD(configadr, ECT_REG_ALIAS, sizeof(ec_slave[slave].aliasadr), &ec_slave[slave].aliasadr, EC_TIMEOUTRET);
00201       ec_FPRD(configadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET);
00202       estat = etohs(estat);
00203       if (estat & EC_ESTAT_R64) /* check if slave can read 8 byte chunks */
00204         ec_slave[slave].eep_8byte = 1;
00205             ec_readeeprom1(slave, ECT_SII_MANUF); /* Manuf */
00206         }
00207     for (slave = 1; slave <= ec_slavecount; slave++)
00208         {
00209             ec_slave[slave].eep_man = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP)); /* Manuf */
00210             ec_readeeprom1(slave, ECT_SII_ID); /* ID */
00211         }
00212         for (slave = 1; slave <= ec_slavecount; slave++)
00213         {
00214             ec_slave[slave].eep_id = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP)); /* ID */
00215             ec_readeeprom1(slave, ECT_SII_REV); /* revision */
00216         }
00217         for (slave = 1; slave <= ec_slavecount; slave++)
00218         {
00219             ec_slave[slave].eep_rev = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP)); /* revision */
00220             ec_readeeprom1(slave, ECT_SII_RXMBXADR); /* write mailbox address + mailboxsize */
00221         }
00222         for (slave = 1; slave <= ec_slavecount; slave++)
00223         {
00224             eedat = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP)); /* write mailbox address and mailboxsize */
00225             ec_slave[slave].mbx_wo = (uint16)LO_WORD(eedat);
00226             ec_slave[slave].mbx_l = (uint16)HI_WORD(eedat);
00227       if (ec_slave[slave].mbx_l > 0) 
00228               ec_readeeprom1(slave, ECT_SII_TXMBXADR); /* read mailbox offset */
00229         }
00230         for (slave = 1; slave <= ec_slavecount; slave++)
00231         {
00232       if (ec_slave[slave].mbx_l > 0) 
00233       {
00234               eedat = etohl(ec_readeeprom2(slave, EC_TIMEOUTEEP)); /* read mailbox offset */
00235         ec_slave[slave].mbx_ro = (uint16)LO_WORD(eedat); /* read mailbox offset */
00236               ec_slave[slave].mbx_rl = (uint16)HI_WORD(eedat); /*read mailbox length */
00237         if (ec_slave[slave].mbx_rl == 0)
00238                 ec_slave[slave].mbx_rl = ec_slave[slave].mbx_l;
00239       }
00240             configadr = ec_slave[slave].configadr;
00241             mbx_ro = ec_slave[slave].mbx_ro;
00242             mbx_wo = ec_slave[slave].mbx_wo;
00243             mbx_l = ec_slave[slave].mbx_l;
00244             mbx_rl = ec_slave[slave].mbx_rl;
00245             if ((etohs(ec_FPRDw(configadr, ECT_REG_ESCSUP, EC_TIMEOUTRET)) & 0x04) > 0)  /* Support DC? */
00246                 ec_slave[slave].hasdc = TRUE;
00247             else
00248                 ec_slave[slave].hasdc = FALSE;
00249             topology = etohs(ec_FPRDw(configadr, ECT_REG_DLSTAT, EC_TIMEOUTRET)); /* extract topology from DL status */
00250       h = 0; 
00251       b = 0;
00252             if ((topology & 0x0300) == 0x0200) /* port0 open and communication established */
00253             {
00254                 h++;
00255         b |= 0x01;
00256             }
00257             if ((topology & 0x0c00) == 0x0800) /* port1 open and communication established */
00258             {
00259                 h++;
00260         b |= 0x02;
00261             }
00262             if ((topology & 0x3000) == 0x2000) /* port2 open and communication established */
00263             {
00264                 h++;
00265         b |= 0x04;
00266             }
00267             if ((topology & 0xc000) == 0x8000) /* port3 open and communication established */
00268             {
00269                 h++;
00270         b |= 0x08;
00271             }
00272             /* ptype = Physical type*/
00273             ec_slave[slave].ptype = LO_BYTE(etohs(ec_FPRDw(configadr, ECT_REG_PORTDES, EC_TIMEOUTRET)));
00274             ec_slave[slave].topology = h;
00275       ec_slave[slave].activeports = b;
00276       /* 0=no links, not possible             */
00277             /* 1=1 link  , end of line              */
00278             /* 2=2 links , one before and one after */
00279             /* 3=3 links , split point              */
00280             /* 4=4 links , cross point              */
00281             /* search for parent */
00282             ec_slave[slave].parent = 0; /* parent is master */
00283             if (slave > 1)
00284             {
00285                 topoc = 0; 
00286                 slavec = slave - 1;
00287                 do
00288                 {
00289                 topology = ec_slave[slavec].topology;
00290                     if (topology == 1)
00291                         topoc--; /* endpoint found */
00292                     if (topology == 3)
00293                         topoc++; /* split found */
00294                     if (topology == 4)
00295                         topoc+=2; /* cross found */
00296                     if (((topoc >= 0) && (topology > 1)) ||
00297               (slavec == 1)) /* parent found */
00298                     {
00299                         ec_slave[slave].parent = slavec;
00300                         slavec = 1;
00301                     }
00302           slavec--;
00303                 }
00304                 while (slavec > 0);
00305             }
00306 
00307             w = ec_statecheck(slave, EC_STATE_INIT,  EC_TIMEOUTSTATE); //* check state change Init */
00308   
00309       /* set default mailbox configuration if slave has mailbox */
00310       if (ec_slave[slave].mbx_l>0)
00311       { 
00312         ec_slave[slave].SMtype[0] = 1;
00313         ec_slave[slave].SMtype[1] = 2;
00314         ec_slave[slave].SMtype[2] = 3;
00315         ec_slave[slave].SMtype[3] = 4;
00316         ec_slave[slave].SM[0].StartAddr = htoes(ec_slave[slave].mbx_wo);
00317         ec_slave[slave].SM[0].SMlength = htoes(ec_slave[slave].mbx_l);
00318         ec_slave[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0);
00319         ec_slave[slave].SM[1].StartAddr = htoes(ec_slave[slave].mbx_ro);
00320         ec_slave[slave].SM[1].SMlength = htoes(ec_slave[slave].mbx_rl);
00321         ec_slave[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1);
00322         ec_slave[slave].mbx_proto = ec_readeeprom (slave, ECT_SII_MBXPROTO, EC_TIMEOUTEEP);
00323       } 
00324       cindex = 0;
00325       /* use configuration table ? */
00326       if (usetable)
00327       {
00328         cindex = ec_findconfig( ec_slave[slave].eep_man, ec_slave[slave].eep_id );
00329         ec_slave[slave].configindex= cindex;
00330       }
00331       /* slave found in configuration table ? */
00332       if (cindex)
00333       {
00334         ec_slave[slave].Dtype = ec_configlist[cindex].Dtype;        
00335         strcpy( ec_slave[slave].name ,ec_configlist[cindex].name);
00336         ec_slave[slave].Ibits = ec_configlist[cindex].Ibits;
00337         ec_slave[slave].Obits = ec_configlist[cindex].Obits;
00338         if (ec_slave[slave].Obits)
00339           ec_slave[slave].FMMU0func = 1;
00340         if (ec_slave[slave].Ibits)
00341           ec_slave[slave].FMMU1func = 2;
00342         ec_slave[slave].FMMU[0].FMMUactive = ec_configlist[cindex].FM0ac;
00343         ec_slave[slave].FMMU[1].FMMUactive = ec_configlist[cindex].FM1ac;
00344         ec_slave[slave].SM[2].StartAddr = htoes(ec_configlist[cindex].SM2a);
00345         ec_slave[slave].SM[2].SMflags = htoel(ec_configlist[cindex].SM2f);
00346         /* simple (no mailbox) output slave found ? */
00347         if (ec_slave[slave].Obits && !ec_slave[slave].SM[2].StartAddr)
00348         {
00349           ec_slave[slave].SM[0].StartAddr = htoes(0x0f00);
00350           ec_slave[slave].SM[0].SMlength = htoes((ec_slave[slave].Obits + 7) / 8);
00351           ec_slave[slave].SM[0].SMflags = htoel(EC_DEFAULTDOSM0);     
00352           ec_slave[slave].FMMU[0].FMMUactive = 1;
00353           ec_slave[slave].FMMU[0].FMMUtype = 2;
00354           ec_slave[slave].SMtype[0] = 3;
00355         }
00356         /* complex output slave */
00357         else
00358         {
00359           ec_slave[slave].SM[2].SMlength = htoes((ec_slave[slave].Obits + 7) / 8);
00360           ec_slave[slave].SMtype[2] = 3;
00361         } 
00362         ec_slave[slave].SM[3].StartAddr = htoes(ec_configlist[cindex].SM3a);
00363         ec_slave[slave].SM[3].SMflags = htoel(ec_configlist[cindex].SM3f);
00364         /* simple (no mailbox) input slave found ? */
00365         if (ec_slave[slave].Ibits && !ec_slave[slave].SM[3].StartAddr)
00366         {
00367           ec_slave[slave].SM[1].StartAddr = htoes(0x1000);
00368           ec_slave[slave].SM[1].SMlength = htoes((ec_slave[slave].Ibits + 7) / 8);
00369           ec_slave[slave].SM[1].SMflags = htoel(0x00000000);      
00370           ec_slave[slave].FMMU[1].FMMUactive = 1;
00371           ec_slave[slave].FMMU[1].FMMUtype = 1;
00372           ec_slave[slave].SMtype[1] = 4;
00373         }
00374         /* complex input slave */
00375         else
00376         {
00377           ec_slave[slave].SM[3].SMlength = htoes((ec_slave[slave].Ibits + 7) / 8);
00378           ec_slave[slave].SMtype[3] = 4;
00379         } 
00380       }
00381       /* slave not in configuration table, find out via SII */
00382       else
00383       {
00384         ssigen = ec_siifind(slave, ECT_SII_GENERAL);
00385         /* SII general section */
00386         if (ssigen)
00387                 {
00388           ec_slave[slave].CoEdetails = ec_siigetbyte(slave, ssigen + 0x07);
00389           ec_slave[slave].FoEdetails = ec_siigetbyte(slave, ssigen + 0x08);
00390           ec_slave[slave].EoEdetails = ec_siigetbyte(slave, ssigen + 0x09);
00391           ec_slave[slave].SoEdetails = ec_siigetbyte(slave, ssigen + 0x0a);
00392           if((ec_siigetbyte(slave, ssigen + 0x0d) & 0x02) > 0)
00393           {
00394             ec_slave[slave].blockLRW = 1;
00395             ec_slave[0].blockLRW++;           
00396           } 
00397           ec_slave[slave].Ebuscurrent = ec_siigetbyte(slave, ssigen + 0x0e);
00398           ec_slave[slave].Ebuscurrent += ec_siigetbyte(slave, ssigen + 0x0f) << 8;
00399           ec_slave[0].Ebuscurrent += ec_slave[slave].Ebuscurrent;
00400                 }
00401         /* SII strings section */
00402         if (ec_siifind(slave, ECT_SII_STRING) > 0)
00403                     ec_siistring(ec_slave[slave].name, slave, 1);
00404         /* no name for slave found, use constructed name */
00405                 else
00406                 {
00407                     sprintf(ec_slave[slave].name, "? M:%8.8x I:%8.8x",
00408                     (unsigned int)ec_slave[slave].eep_man, (unsigned int)ec_slave[slave].eep_id);
00409                 }
00410         /* SII SM section */
00411         nSM = ec_siiSM (slave,&ec_SM);
00412         if (nSM>0)
00413         { 
00414           ec_slave[slave].SM[0].StartAddr = htoes(ec_SM.PhStart);
00415           ec_slave[slave].SM[0].SMlength = htoes(ec_SM.Plength);
00416           ec_slave[slave].SM[0].SMflags = htoel((ec_SM.Creg) + (ec_SM.Activate << 16));
00417           SMc = 1;
00418           while ((SMc < EC_MAXSM) &&  ec_siiSMnext(slave, &ec_SM, SMc))
00419           {
00420             ec_slave[slave].SM[SMc].StartAddr = htoes(ec_SM.PhStart);
00421             ec_slave[slave].SM[SMc].SMlength = htoes(ec_SM.Plength);
00422             ec_slave[slave].SM[SMc].SMflags = htoel((ec_SM.Creg) + (ec_SM.Activate << 16));
00423             SMc++;
00424           } 
00425         } 
00426         /* SII FMMU section */
00427                 if (ec_siiFMMU(slave, &ec_FMMU))
00428         {
00429           if (ec_FMMU.FMMU0 !=0xff) 
00430             ec_slave[slave].FMMU0func = ec_FMMU.FMMU0;
00431           if (ec_FMMU.FMMU1 !=0xff) 
00432             ec_slave[slave].FMMU1func = ec_FMMU.FMMU1;
00433           if (ec_FMMU.FMMU2 !=0xff) 
00434             ec_slave[slave].FMMU2func = ec_FMMU.FMMU2;
00435           if (ec_FMMU.FMMU3 !=0xff) 
00436             ec_slave[slave].FMMU3func = ec_FMMU.FMMU3;
00437         } 
00438       } 
00439 
00440       if (ec_slave[slave].mbx_l > 0)
00441       {
00442         if (ec_slave[slave].SM[0].StartAddr == 0x0000) /* should never happen */
00443         {
00444           ec_slave[slave].SM[0].StartAddr = htoes(0x1000);
00445           ec_slave[slave].SM[0].SMlength = htoes(0x0080);
00446           ec_slave[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0);
00447           ec_slave[slave].SMtype[0] = 1;          
00448         }     
00449         if (ec_slave[slave].SM[1].StartAddr == 0x0000) /* should never happen */
00450         {
00451           ec_slave[slave].SM[1].StartAddr = htoes(0x1080);
00452           ec_slave[slave].SM[1].SMlength = htoes(0x0080);
00453           ec_slave[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1);
00454           ec_slave[slave].SMtype[1] = 2;
00455         }     
00456         /* program SM0 mailbox in for slave */
00457         ec_FPWR (configadr, ECT_REG_SM0, sizeof(ec_smt), &ec_slave[slave].SM[0], EC_TIMEOUTRET);
00458         /* program SM1 mailbox out for slave */
00459         // usleep(1000); // was needed for NETX (needs internal time after SM update)
00460         ec_FPWR (configadr, ECT_REG_SM1, sizeof(ec_smt), &ec_slave[slave].SM[1], EC_TIMEOUTRET);
00461       } 
00462       ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP | EC_STATE_ACK) , EC_TIMEOUTRET); /* set preop status */
00463     }
00464   } 
00465     return wkc;
00466 }
00467 
00468 /** Map all PDOs in one group of slaves to IOmap.
00469  *
00470  * @param[out] pIOmap   = pointer to IOmap  
00471  * @param[in]  group    = group to map, 0 = all groups  
00472  * @return IOmap size
00473  */
00474 int ec_config_map_group(void *pIOmap, uint8 group)
00475 {
00476     uint16 slave, configadr;
00477   int Isize, Osize, BitCount, ByteCount, FMMUsize, FMMUdone;
00478   uint16 SMlength;
00479     uint8 BitPos, EndAddr;
00480   uint8 SMc, FMMUc;
00481   uint32 LogAddr = 0;
00482   uint32 oLogAddr = 0;
00483   uint32 diff;
00484   int nSM, rval;
00485   ec_eepromPDOt eepPDO;
00486   uint16 currentsegment = 0;
00487   uint32 segmentsize = 0;
00488 
00489   if ((ec_slavecount > 0) && (group < EC_MAXGROUP))
00490   { 
00491     EC_PRINT("ec_config_map_group IOmap:%p group:%d\n", pIOmap, group);
00492     LogAddr = ec_group[group].logstartaddr;
00493     oLogAddr = LogAddr;
00494     BitPos = 0;
00495     ec_group[group].nsegments = 0;
00496     ec_group[group].expectedWKC = 0;
00497 
00498     /* find output mapping of slave and program FMMU */
00499     for (slave = 1; slave <= ec_slavecount; slave++)
00500         {
00501             configadr = ec_slave[slave].configadr;
00502 
00503       ec_statecheck(slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */
00504 
00505       EC_PRINT(" >Slave %d, configadr %x, state %2.2x\n",
00506           slave, ec_slave[slave].configadr, ec_slave[slave].state);
00507 
00508       if (!group || (group == ec_slave[slave].group))
00509       { 
00510       
00511       /* if slave not found in configlist find IO mapping in slave self */
00512       if (!ec_slave[slave].configindex)
00513       {
00514         Isize = 0;
00515         Osize = 0;
00516         if (ec_slave[slave].mbx_proto & ECT_MBXPROT_COE) /* has CoE */
00517         {
00518           if (ec_slave[slave].CoEdetails & ECT_COEDET_SDOCA) /* has Complete Access */
00519             /* read PDO mapping via CoE and use Complete Access */
00520             rval = ec_readPDOmapCA(slave, &Osize, &Isize);
00521           else
00522             /* read PDO mapping via CoE */
00523             rval = ec_readPDOmap(slave, &Osize, &Isize);
00524           EC_PRINT("  CoE Osize:%d Isize:%d\n", Osize, Isize);
00525         }
00526         if ((!Isize && !Osize) && (ec_slave[slave].mbx_proto & ECT_MBXPROT_SOE)) /* has SoE */
00527         {
00528           /* read AT / MDT mapping via SoE */
00529           rval = ec_readIDNmap(slave, &Osize, &Isize);
00530           ec_slave[slave].SM[2].SMlength = htoes((Osize + 7) / 8);
00531           ec_slave[slave].SM[3].SMlength = htoes((Isize + 7) / 8);
00532           EC_PRINT("  SoE Osize:%d Isize:%d\n", Osize, Isize);
00533         }
00534         if (!Isize && !Osize) /* find PDO mapping by SII */
00535         {
00536           memset(&eepPDO, 0, sizeof(eepPDO));
00537           Isize = (int)ec_siiPDO (slave, &eepPDO, 0);
00538           EC_PRINT("  SII Isize:%d\n", Isize);          
00539           for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
00540           { 
00541             if (eepPDO.SMbitsize[nSM] > 0)
00542             { 
00543               ec_slave[slave].SM[nSM].SMlength =  htoes((eepPDO.SMbitsize[nSM] + 7) / 8);
00544               ec_slave[slave].SMtype[nSM] = 4;
00545               EC_PRINT("    SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]);
00546             } 
00547           } 
00548           Osize = (int)ec_siiPDO (slave, &eepPDO, 1);
00549           EC_PRINT("  SII Osize:%d\n", Osize);          
00550           for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
00551           { 
00552             if (eepPDO.SMbitsize[nSM] > 0)
00553             { 
00554               ec_slave[slave].SM[nSM].SMlength =  htoes((eepPDO.SMbitsize[nSM] + 7) / 8);
00555               ec_slave[slave].SMtype[nSM] = 3;
00556               EC_PRINT("    SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]);
00557             } 
00558           } 
00559         }
00560         ec_slave[slave].Obits = Osize;
00561         ec_slave[slave].Ibits = Isize;
00562         EC_PRINT("     ISIZE:%d %d OSIZE:%d\n", ec_slave[slave].Ibits, Isize,ec_slave[slave].Obits);
00563         
00564       }
00565 
00566       EC_PRINT("  SM programming\n");  
00567       if (!ec_slave[slave].mbx_l && ec_slave[slave].SM[0].StartAddr)
00568         {
00569         ec_FPWR (configadr, ECT_REG_SM0, sizeof(ec_smt), &ec_slave[slave].SM[0], EC_TIMEOUTRET);
00570         EC_PRINT("    SM0 Type:%d StartAddr:%4.4x Flags:%8.8x\n", 
00571             ec_slave[slave].SMtype[0], ec_slave[slave].SM[0].StartAddr, ec_slave[slave].SM[0].SMflags);   
00572         }
00573       if (!ec_slave[slave].mbx_l && ec_slave[slave].SM[1].StartAddr)
00574         {
00575         ec_FPWR (configadr, ECT_REG_SM1, sizeof(ec_smt), &ec_slave[slave].SM[1], EC_TIMEOUTRET);
00576         EC_PRINT("    SM1 Type:%d StartAddr:%4.4x Flags:%8.8x\n", 
00577             ec_slave[slave].SMtype[1], ec_slave[slave].SM[1].StartAddr, ec_slave[slave].SM[1].SMflags);   
00578         }
00579       /* program SM2 to SMx */
00580       for( nSM = 2 ; nSM < EC_MAXSM ; nSM++ )
00581       { 
00582         if (ec_slave[slave].SM[nSM].StartAddr)
00583         {
00584           /* check if SM length is zero -> clear enable flag */
00585           if( ec_slave[slave].SM[nSM].SMlength == 0) 
00586             ec_slave[slave].SM[nSM].SMflags = htoel( etohl(ec_slave[slave].SM[nSM].SMflags) & EC_SMENABLEMASK);
00587           ec_FPWR (configadr, ECT_REG_SM0 + (nSM * sizeof(ec_smt)), sizeof(ec_smt), &ec_slave[slave].SM[nSM], EC_TIMEOUTRET);
00588           EC_PRINT("    SM%d Type:%d StartAddr:%4.4x Flags:%8.8x\n", nSM,
00589               ec_slave[slave].SMtype[nSM], ec_slave[slave].SM[nSM].StartAddr, ec_slave[slave].SM[nSM].SMflags);   
00590         }
00591       }
00592       if (ec_slave[slave].Ibits > 7)
00593         ec_slave[slave].Ibytes = (ec_slave[slave].Ibits + 7) / 8;
00594       if (ec_slave[slave].Obits > 7)
00595         ec_slave[slave].Obytes = (ec_slave[slave].Obits + 7) / 8;
00596 
00597       FMMUc = ec_slave[slave].FMMUunused;
00598       SMc = 0;
00599       BitCount = 0;
00600       ByteCount = 0;
00601       EndAddr = 0;
00602       FMMUsize = 0;
00603       FMMUdone = 0;
00604       /* create output mapping */
00605       if (ec_slave[slave].Obits)
00606       {
00607         EC_PRINT("  OUTPUT MAPPING\n");
00608         /* search for SM that contribute to the output mapping */
00609         while ( (SMc < (EC_MAXSM - 1)) && (FMMUdone < ((ec_slave[slave].Obits + 7) / 8)))
00610         { 
00611           EC_PRINT("    FMMU %d\n", FMMUc);
00612           while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 3)) SMc++;
00613           EC_PRINT("      SM%d\n", SMc);
00614           ec_slave[slave].FMMU[FMMUc].PhysStart = ec_slave[slave].SM[SMc].StartAddr;
00615           SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00616           ByteCount += SMlength;
00617           BitCount += SMlength * 8;
00618           EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;
00619           while ( (BitCount < ec_slave[slave].Obits) && (SMc < (EC_MAXSM - 1)) ) /* more SM for output */
00620           {
00621             SMc++;
00622             while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 3)) SMc++;
00623             /* if addresses from more SM connect use one FMMU otherwise break up in mutiple FMMU */
00624             if ( etohs(ec_slave[slave].SM[SMc].StartAddr) > EndAddr ) break;
00625             EC_PRINT("      SM%d\n", SMc);
00626             SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00627             ByteCount += SMlength;
00628             BitCount += SMlength * 8;
00629             EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;          
00630           } 
00631 
00632           /* bit oriented slave */
00633           if (!ec_slave[slave].Obytes)
00634           { 
00635             ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00636             ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00637             BitPos += ec_slave[slave].Obits - 1;
00638             if (BitPos > 7)
00639             {
00640               LogAddr++;
00641               BitPos -= 8;
00642             } 
00643             FMMUsize = LogAddr - etohl(ec_slave[slave].FMMU[FMMUc].LogStart) + 1;
00644             ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00645             ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00646             BitPos ++;
00647             if (BitPos > 7)
00648             {
00649               LogAddr++;
00650               BitPos -= 8;
00651             } 
00652           }
00653           /* byte oriented slave */
00654           else
00655           {
00656             if (BitPos)
00657             {
00658               LogAddr++;
00659               BitPos = 0;
00660             } 
00661             ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00662             ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00663             BitPos = 7;
00664             FMMUsize = ByteCount;
00665             if ((FMMUsize + FMMUdone)> ec_slave[slave].Obytes)
00666               FMMUsize = ec_slave[slave].Obytes - FMMUdone;
00667             LogAddr += FMMUsize;
00668             ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00669             ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00670             BitPos = 0;
00671           }
00672           FMMUdone += FMMUsize;
00673           ec_slave[slave].FMMU[FMMUc].PhysStartBit = 0;
00674           ec_slave[slave].FMMU[FMMUc].FMMUtype = 2;
00675           ec_slave[slave].FMMU[FMMUc].FMMUactive = 1;
00676           /* program FMMU for output */
00677           ec_FPWR (configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut), 
00678                    &ec_slave[slave].FMMU[FMMUc], EC_TIMEOUTRET);
00679           /* add two for an output FMMU */
00680           ec_group[group].expectedWKC += 2;
00681           if (!ec_slave[slave].outputs)
00682           { 
00683             ec_slave[slave].outputs = pIOmap + etohl(ec_slave[slave].FMMU[FMMUc].LogStart);
00684             ec_slave[slave].Ostartbit = ec_slave[slave].FMMU[FMMUc].LogStartbit;
00685             EC_PRINT("    slave %d Outputs %p startbit %d\n", slave, ec_slave[slave].outputs, ec_slave[slave].Ostartbit);
00686           }
00687           FMMUc++;
00688         } 
00689         ec_slave[slave].FMMUunused = FMMUc;
00690         diff = LogAddr - oLogAddr;
00691         oLogAddr = LogAddr;
00692         if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00693         {
00694           ec_group[group].IOsegment[currentsegment] = segmentsize;
00695           if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00696           {
00697             currentsegment++;
00698             segmentsize = diff; 
00699           }
00700         }
00701         else
00702           segmentsize += diff;
00703       }
00704       } 
00705         }
00706     if (BitPos)
00707     {
00708       LogAddr++;
00709       oLogAddr = LogAddr;
00710       BitPos = 0;
00711       if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00712       {
00713         ec_group[group].IOsegment[currentsegment] = segmentsize;
00714         if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00715         {
00716           currentsegment++;
00717           segmentsize = 1;  
00718         }
00719       }
00720       else
00721         segmentsize += 1;
00722     } 
00723     ec_group[group].outputs = pIOmap;
00724     ec_group[group].Obytes = LogAddr;
00725     ec_group[group].nsegments = currentsegment + 1;
00726     ec_group[group].Isegment = currentsegment;
00727     ec_group[group].Ioffset = segmentsize;
00728     if (!group)
00729     { 
00730       ec_slave[0].outputs = pIOmap;
00731       ec_slave[0].Obytes = LogAddr; /* store output bytes in master record */
00732     } 
00733     
00734     /* do input mapping of slave and program FMMUs */
00735     for (slave = 1; slave <= ec_slavecount; slave++)
00736         {
00737             configadr = ec_slave[slave].configadr;
00738       FMMUc = ec_slave[slave].FMMUunused;
00739       if (ec_slave[slave].Obits) /* find free FMMU */
00740         while ( ec_slave[slave].FMMU[FMMUc].LogStart ) FMMUc++;
00741       SMc = 0;
00742       BitCount = 0;
00743       ByteCount = 0;
00744       EndAddr = 0;
00745       FMMUsize = 0;
00746       FMMUdone = 0;
00747       /* create input mapping */
00748       if (ec_slave[slave].Ibits)
00749       {
00750         EC_PRINT(" =Slave %d, INPUT MAPPING\n", slave);
00751         /* search for SM that contribute to the input mapping */
00752         while ( (SMc < (EC_MAXSM - 1)) && (FMMUdone < ((ec_slave[slave].Ibits + 7) / 8)))
00753         { 
00754           EC_PRINT("    FMMU %d\n", FMMUc);
00755           while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 4)) SMc++;
00756           EC_PRINT("      SM%d\n", SMc);
00757           ec_slave[slave].FMMU[FMMUc].PhysStart = ec_slave[slave].SM[SMc].StartAddr;
00758           SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00759           ByteCount += SMlength;
00760           BitCount += SMlength * 8;
00761           EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;
00762           while ( (BitCount < ec_slave[slave].Ibits) && (SMc < (EC_MAXSM - 1)) ) /* more SM for input */
00763           {
00764             SMc++;
00765             while ( (SMc < (EC_MAXSM - 1)) && (ec_slave[slave].SMtype[SMc] != 4)) SMc++;
00766             /* if addresses from more SM connect use one FMMU otherwise break up in mutiple FMMU */
00767             if ( etohs(ec_slave[slave].SM[SMc].StartAddr) > EndAddr ) break;
00768             EC_PRINT("      SM%d\n", SMc);
00769             SMlength = etohs(ec_slave[slave].SM[SMc].SMlength);
00770             ByteCount += SMlength;
00771             BitCount += SMlength * 8;
00772             EndAddr = etohs(ec_slave[slave].SM[SMc].StartAddr) + SMlength;          
00773           } 
00774 
00775           /* bit oriented slave */
00776           if (!ec_slave[slave].Ibytes)
00777           { 
00778             ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00779             ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00780             BitPos += ec_slave[slave].Ibits - 1;
00781             if (BitPos > 7)
00782             {
00783               LogAddr++;
00784               BitPos -= 8;
00785             } 
00786             FMMUsize = LogAddr - etohl(ec_slave[slave].FMMU[FMMUc].LogStart) + 1;
00787             ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00788             ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00789             BitPos ++;
00790             if (BitPos > 7)
00791             {
00792               LogAddr++;
00793               BitPos -= 8;
00794             } 
00795           }
00796           /* byte oriented slave */
00797           else
00798           {
00799             if (BitPos)
00800             {
00801               LogAddr++;
00802               BitPos = 0;
00803             } 
00804             ec_slave[slave].FMMU[FMMUc].LogStart = htoel(LogAddr);
00805             ec_slave[slave].FMMU[FMMUc].LogStartbit = BitPos;
00806             BitPos = 7;
00807             FMMUsize = ByteCount;
00808             if ((FMMUsize + FMMUdone)> ec_slave[slave].Ibytes)
00809               FMMUsize = ec_slave[slave].Ibytes - FMMUdone;
00810             LogAddr += FMMUsize;
00811             ec_slave[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
00812             ec_slave[slave].FMMU[FMMUc].LogEndbit = BitPos;
00813             BitPos = 0;
00814           }
00815           FMMUdone += FMMUsize;
00816           if (ec_slave[slave].FMMU[FMMUc].LogLength)
00817           { 
00818             ec_slave[slave].FMMU[FMMUc].PhysStartBit = 0;
00819             ec_slave[slave].FMMU[FMMUc].FMMUtype = 1;
00820             ec_slave[slave].FMMU[FMMUc].FMMUactive = 1;
00821             /* program FMMU for input */
00822             ec_FPWR (configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut), 
00823                      &ec_slave[slave].FMMU[FMMUc], EC_TIMEOUTRET);
00824             /* add one for an input FMMU */
00825             ec_group[group].expectedWKC += 1;
00826           } 
00827           if (!ec_slave[slave].inputs)
00828           { 
00829             ec_slave[slave].inputs = pIOmap + etohl(ec_slave[slave].FMMU[FMMUc].LogStart);
00830             ec_slave[slave].Istartbit = ec_slave[slave].FMMU[FMMUc].LogStartbit;
00831             EC_PRINT("    Inputs %p startbit %d\n", ec_slave[slave].inputs, ec_slave[slave].Istartbit);
00832           }
00833           FMMUc++;
00834         } 
00835         ec_slave[slave].FMMUunused = FMMUc;
00836         diff = LogAddr - oLogAddr;
00837         oLogAddr = LogAddr;
00838         if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00839         {
00840           ec_group[group].IOsegment[currentsegment] = segmentsize;
00841           if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00842           {
00843             currentsegment++;
00844             segmentsize = diff; 
00845           }
00846         }
00847         else
00848           segmentsize += diff;
00849       }
00850 
00851       ec_eeprom2pdi(slave); /* set Eeprom control to PDI */     
00852       ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , EC_TIMEOUTRET); /* set safeop status */
00853             
00854     }
00855     if (BitPos)
00856     {
00857       LogAddr++;
00858       oLogAddr = LogAddr;
00859       BitPos = 0;
00860       if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
00861       {
00862         ec_group[group].IOsegment[currentsegment] = segmentsize;
00863         if (currentsegment < (EC_MAXIOSEGMENTS - 1))
00864         {
00865           currentsegment++;
00866           segmentsize = 1;  
00867         }
00868       }
00869       else
00870         segmentsize += 1;
00871     } 
00872     ec_group[group].IOsegment[currentsegment] = segmentsize;
00873     ec_group[group].nsegments = currentsegment + 1;
00874     ec_group[group].inputs = pIOmap + ec_group[group].Obytes;
00875     ec_group[group].Ibytes = LogAddr - ec_group[group].Obytes;
00876     if (ec_slave[slave].blockLRW)
00877       ec_group[group].blockLRW++;           
00878     ec_group[group].Ebuscurrent += ec_slave[slave].Ebuscurrent;
00879     if (!group)
00880     { 
00881       ec_slave[0].inputs = pIOmap + ec_slave[0].Obytes;
00882       ec_slave[0].Ibytes = LogAddr - ec_slave[0].Obytes; /* store input bytes in master record */
00883     } 
00884 
00885     EC_PRINT("IOmapSize %d\n", LogAddr - ec_group[group].logstartaddr);   
00886     return (LogAddr - ec_group[group].logstartaddr);
00887   }
00888   return 0;
00889 } 
00890 
00891 /** Map all PDOs from slaves to IOmap.
00892  *
00893  * @param[out] pIOmap   = pointer to IOmap  
00894  * @return IOmap size
00895  */
00896 int ec_config_map(void *pIOmap)
00897 {
00898   return ec_config_map_group(pIOmap, 0);
00899 }
00900 
00901 /** Enumerate / map and init all slaves.
00902  *
00903  * @param[in] usetable    = TRUE when using configtable to init slaves, FALSE otherwise
00904  * @param[out] pIOmap   = pointer to IOmap  
00905  * @return Workcounter of slave discover datagram = number of slaves found
00906  */
00907 int ec_config(uint8 usetable, void *pIOmap)
00908 {
00909   int wkc;
00910   wkc = ec_config_init(usetable);
00911   if (wkc) 
00912     ec_config_map(pIOmap);
00913     return wkc;
00914 }
00915 
00916 /** Recover slave.
00917  *
00918  * @param[in] slave   = slave to recover
00919  * @return >0 if successful
00920  */
00921 int ec_recover_slave(uint16 slave)
00922 {
00923   int rval;
00924   uint16 ADPh, configadr;
00925 
00926   rval = 0;
00927     configadr = ec_slave[slave].configadr;
00928   /* clear possible slaves at EC_TEMPNODE */
00929   ec_FPWRw(EC_TEMPNODE, ECT_REG_STADR, htoes(0) , 0);
00930     ADPh = (uint16)(1 - slave);
00931   /* set temporary node address of slave */
00932   if(ec_APWRw(ADPh, ECT_REG_STADR, htoes(EC_TEMPNODE) , EC_TIMEOUTRET) <= 0)
00933     return 0; /* slave fails to respond */
00934   
00935     ec_slave[slave].configadr = EC_TEMPNODE; /* temporary config address */ 
00936   ec_eeprom2master(slave); /* set Eeprom control to master */     
00937 
00938   /* check if slave is the same as configured before */
00939   if ((ec_FPRDw(EC_TEMPNODE, ECT_REG_ALIAS, EC_TIMEOUTRET) == ec_slave[slave].aliasadr) &&
00940       (ec_readeeprom(slave, ECT_SII_ID, EC_TIMEOUTEEP) == ec_slave[slave].eep_id) &&
00941       (ec_readeeprom(slave, ECT_SII_MANUF, EC_TIMEOUTEEP) == ec_slave[slave].eep_man) &&
00942       (ec_readeeprom(slave, ECT_SII_REV, EC_TIMEOUTEEP) == ec_slave[slave].eep_rev))
00943   {
00944     rval = ec_FPWRw(EC_TEMPNODE, ECT_REG_STADR, htoes(configadr) , EC_TIMEOUTRET);
00945       ec_slave[slave].configadr = configadr;
00946   }
00947   else
00948   {
00949     /* slave is not the expected one, remove config address*/
00950     ec_FPWRw(EC_TEMPNODE, ECT_REG_STADR, htoes(0) , EC_TIMEOUTRET);
00951       ec_slave[slave].configadr = configadr;
00952   }
00953 
00954   return rval;
00955 }
00956 
00957 /** Reconfigure slave.
00958  *
00959  * @param[in] slave   = slave to reconfigure
00960  * @return Slave state
00961  */
00962 int ec_reconfig_slave(uint16 slave)
00963 {
00964   int state, nSM, FMMUc;
00965   uint16 configadr;
00966   
00967     configadr = ec_slave[slave].configadr;
00968   if (ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_INIT) , EC_TIMEOUTRET) <= 0)
00969     return 0;
00970   state = 0;
00971   ec_eeprom2pdi(slave); /* set Eeprom control to PDI */     
00972   /* check state change init */
00973   state = ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE);
00974   if(state == EC_STATE_INIT)
00975   {
00976     /* program all enabled SM */
00977     for( nSM = 0 ; nSM < EC_MAXSM ; nSM++ )
00978     { 
00979       if (ec_slave[slave].SM[nSM].StartAddr)
00980         ec_FPWR (configadr, ECT_REG_SM0 + (nSM * sizeof(ec_smt)), sizeof(ec_smt),
00981             &ec_slave[slave].SM[nSM], EC_TIMEOUTRET);
00982     }
00983     /* program configured FMMU */
00984     for( FMMUc = 0 ; FMMUc < ec_slave[slave].FMMUunused ; FMMUc++ )
00985     { 
00986       ec_FPWR (configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc), sizeof(ec_fmmut), 
00987           &ec_slave[slave].FMMU[FMMUc], EC_TIMEOUTRET);
00988     }
00989     ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP) , EC_TIMEOUTRET);
00990     state = ec_statecheck(slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */
00991     if( state == EC_STATE_PRE_OP)
00992     {
00993       ec_FPWRw(configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , EC_TIMEOUTRET); /* set safeop status */
00994       state = ec_statecheck(slave, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); /* check state change safe-op */
00995     }
00996   }
00997   return state;   
00998 }
Generated by  doxygen 1.6.3