SOEM EtherCAT Master library for STM Nucleo F767ZI

Dependents:   EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB

  • It has been developed for the EasyCAT LAB , a complete educational and experimental EtherCAT® system, composed of one master and two slaves .

Warning

/media/uploads/EasyCAT/easycat_lab.jpg

Committer:
EasyCAT
Date:
Tue Jun 11 10:29:09 2019 +0000
Revision:
0:543d6784d4cc
SOEM EtherCAT Master Library for STM Nucleo F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EasyCAT 0:543d6784d4cc 1 /*
EasyCAT 0:543d6784d4cc 2 * Licensed under the GNU General Public License version 2 with exceptions. See
EasyCAT 0:543d6784d4cc 3 * LICENSE file in the project root for full license information
EasyCAT 0:543d6784d4cc 4 */
EasyCAT 0:543d6784d4cc 5
EasyCAT 0:543d6784d4cc 6 /** \file
EasyCAT 0:543d6784d4cc 7 * \brief
EasyCAT 0:543d6784d4cc 8 * Configuration module for EtherCAT master.
EasyCAT 0:543d6784d4cc 9 *
EasyCAT 0:543d6784d4cc 10 * After successful initialisation with ec_init() or ec_init_redundant()
EasyCAT 0:543d6784d4cc 11 * the slaves can be auto configured with this module.
EasyCAT 0:543d6784d4cc 12 */
EasyCAT 0:543d6784d4cc 13
EasyCAT 0:543d6784d4cc 14 #include <stdio.h>
EasyCAT 0:543d6784d4cc 15 #include <string.h>
EasyCAT 0:543d6784d4cc 16 #include "osal.h"
EasyCAT 0:543d6784d4cc 17 #include "oshw.h"
EasyCAT 0:543d6784d4cc 18 #include "ethercattype.h"
EasyCAT 0:543d6784d4cc 19 #include "ethercatbase.h"
EasyCAT 0:543d6784d4cc 20 #include "ethercatmain.h"
EasyCAT 0:543d6784d4cc 21 #include "ethercatcoe.h"
EasyCAT 0:543d6784d4cc 22 #include "ethercatsoe.h"
EasyCAT 0:543d6784d4cc 23 #include "ethercatconfig.h"
EasyCAT 0:543d6784d4cc 24
EasyCAT 0:543d6784d4cc 25
EasyCAT 0:543d6784d4cc 26 typedef struct
EasyCAT 0:543d6784d4cc 27 {
EasyCAT 0:543d6784d4cc 28 int thread_n;
EasyCAT 0:543d6784d4cc 29 int running;
EasyCAT 0:543d6784d4cc 30 ecx_contextt *context;
EasyCAT 0:543d6784d4cc 31 uint16 slave;
EasyCAT 0:543d6784d4cc 32 } ecx_mapt_t;
EasyCAT 0:543d6784d4cc 33
EasyCAT 0:543d6784d4cc 34 ecx_mapt_t ecx_mapt[EC_MAX_MAPT];
EasyCAT 0:543d6784d4cc 35 #if EC_MAX_MAPT > 1
EasyCAT 0:543d6784d4cc 36 OSAL_THREAD_HANDLE ecx_threadh[EC_MAX_MAPT];
EasyCAT 0:543d6784d4cc 37 #endif
EasyCAT 0:543d6784d4cc 38
EasyCAT 0:543d6784d4cc 39 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 40 /** Slave configuration structure */
EasyCAT 0:543d6784d4cc 41 typedef const struct
EasyCAT 0:543d6784d4cc 42 {
EasyCAT 0:543d6784d4cc 43 /** Manufacturer code of slave */
EasyCAT 0:543d6784d4cc 44 uint32 man;
EasyCAT 0:543d6784d4cc 45 /** ID of slave */
EasyCAT 0:543d6784d4cc 46 uint32 id;
EasyCAT 0:543d6784d4cc 47 /** Readable name */
EasyCAT 0:543d6784d4cc 48 char name[EC_MAXNAME + 1];
EasyCAT 0:543d6784d4cc 49 /** Data type */
EasyCAT 0:543d6784d4cc 50 uint8 Dtype;
EasyCAT 0:543d6784d4cc 51 /** Input bits */
EasyCAT 0:543d6784d4cc 52 uint16 Ibits;
EasyCAT 0:543d6784d4cc 53 /** Output bits */
EasyCAT 0:543d6784d4cc 54 uint16 Obits;
EasyCAT 0:543d6784d4cc 55 /** SyncManager 2 address */
EasyCAT 0:543d6784d4cc 56 uint16 SM2a;
EasyCAT 0:543d6784d4cc 57 /** SyncManager 2 flags */
EasyCAT 0:543d6784d4cc 58 uint32 SM2f;
EasyCAT 0:543d6784d4cc 59 /** SyncManager 3 address */
EasyCAT 0:543d6784d4cc 60 uint16 SM3a;
EasyCAT 0:543d6784d4cc 61 /** SyncManager 3 flags */
EasyCAT 0:543d6784d4cc 62 uint32 SM3f;
EasyCAT 0:543d6784d4cc 63 /** FMMU 0 activation */
EasyCAT 0:543d6784d4cc 64 uint8 FM0ac;
EasyCAT 0:543d6784d4cc 65 /** FMMU 1 activation */
EasyCAT 0:543d6784d4cc 66 uint8 FM1ac;
EasyCAT 0:543d6784d4cc 67 } ec_configlist_t;
EasyCAT 0:543d6784d4cc 68
EasyCAT 0:543d6784d4cc 69 #include "ethercatconfiglist.h"
EasyCAT 0:543d6784d4cc 70 #endif
EasyCAT 0:543d6784d4cc 71
EasyCAT 0:543d6784d4cc 72 /** standard SM0 flags configuration for mailbox slaves */
EasyCAT 0:543d6784d4cc 73 #define EC_DEFAULTMBXSM0 0x00010026
EasyCAT 0:543d6784d4cc 74 /** standard SM1 flags configuration for mailbox slaves */
EasyCAT 0:543d6784d4cc 75 #define EC_DEFAULTMBXSM1 0x00010022
EasyCAT 0:543d6784d4cc 76 /** standard SM0 flags configuration for digital output slaves */
EasyCAT 0:543d6784d4cc 77 #define EC_DEFAULTDOSM0 0x00010044
EasyCAT 0:543d6784d4cc 78
EasyCAT 0:543d6784d4cc 79 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 80 /** Find slave in standard configuration list ec_configlist[]
EasyCAT 0:543d6784d4cc 81 *
EasyCAT 0:543d6784d4cc 82 * @param[in] man = manufacturer
EasyCAT 0:543d6784d4cc 83 * @param[in] id = ID
EasyCAT 0:543d6784d4cc 84 * @return index in ec_configlist[] when found, otherwise 0
EasyCAT 0:543d6784d4cc 85 */
EasyCAT 0:543d6784d4cc 86 int ec_findconfig( uint32 man, uint32 id)
EasyCAT 0:543d6784d4cc 87 {
EasyCAT 0:543d6784d4cc 88 int i = 0;
EasyCAT 0:543d6784d4cc 89
EasyCAT 0:543d6784d4cc 90 do
EasyCAT 0:543d6784d4cc 91 {
EasyCAT 0:543d6784d4cc 92 i++;
EasyCAT 0:543d6784d4cc 93 } while ( (ec_configlist[i].man != EC_CONFIGEND) &&
EasyCAT 0:543d6784d4cc 94 ((ec_configlist[i].man != man) || (ec_configlist[i].id != id)) );
EasyCAT 0:543d6784d4cc 95 if (ec_configlist[i].man == EC_CONFIGEND)
EasyCAT 0:543d6784d4cc 96 {
EasyCAT 0:543d6784d4cc 97 i = 0;
EasyCAT 0:543d6784d4cc 98 }
EasyCAT 0:543d6784d4cc 99 return i;
EasyCAT 0:543d6784d4cc 100 }
EasyCAT 0:543d6784d4cc 101 #endif
EasyCAT 0:543d6784d4cc 102
EasyCAT 0:543d6784d4cc 103 void ecx_init_context(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 104 {
EasyCAT 0:543d6784d4cc 105 int lp;
EasyCAT 0:543d6784d4cc 106 *(context->slavecount) = 0;
EasyCAT 0:543d6784d4cc 107 /* clean ec_slave array */
EasyCAT 0:543d6784d4cc 108 memset(context->slavelist, 0x00, sizeof(ec_slavet) * context->maxslave);
EasyCAT 0:543d6784d4cc 109 memset(context->grouplist, 0x00, sizeof(ec_groupt) * context->maxgroup);
EasyCAT 0:543d6784d4cc 110 /* clear slave eeprom cache, does not actually read any eeprom */
EasyCAT 0:543d6784d4cc 111 ecx_siigetbyte(context, 0, EC_MAXEEPBUF);
EasyCAT 0:543d6784d4cc 112 for(lp = 0; lp < context->maxgroup; lp++)
EasyCAT 0:543d6784d4cc 113 {
EasyCAT 0:543d6784d4cc 114 /* default start address per group entry */
EasyCAT 0:543d6784d4cc 115 context->grouplist[lp].logstartaddr = lp << EC_LOGGROUPOFFSET;
EasyCAT 0:543d6784d4cc 116 }
EasyCAT 0:543d6784d4cc 117 }
EasyCAT 0:543d6784d4cc 118
EasyCAT 0:543d6784d4cc 119 int ecx_detect_slaves(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 120 {
EasyCAT 0:543d6784d4cc 121 uint8 b;
EasyCAT 0:543d6784d4cc 122 uint16 w;
EasyCAT 0:543d6784d4cc 123 int wkc;
EasyCAT 0:543d6784d4cc 124
EasyCAT 0:543d6784d4cc 125 /* make special pre-init register writes to enable MAC[1] local administered bit *
EasyCAT 0:543d6784d4cc 126 * setting for old netX100 slaves */
EasyCAT 0:543d6784d4cc 127 b = 0x00;
EasyCAT 0:543d6784d4cc 128 ecx_BWR(context->port, 0x0000, ECT_REG_DLALIAS, sizeof(b), &b, EC_TIMEOUTRET3); /* Ignore Alias register */
EasyCAT 0:543d6784d4cc 129 b = EC_STATE_INIT | EC_STATE_ACK;
EasyCAT 0:543d6784d4cc 130 ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET3); /* Reset all slaves to Init */
EasyCAT 0:543d6784d4cc 131 /* netX100 should now be happy */
EasyCAT 0:543d6784d4cc 132 ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL, sizeof(b), &b, EC_TIMEOUTRET3); /* Reset all slaves to Init */
EasyCAT 0:543d6784d4cc 133 wkc = ecx_BRD(context->port, 0x0000, ECT_REG_TYPE, sizeof(w), &w, EC_TIMEOUTSAFE); /* detect number of slaves */
EasyCAT 0:543d6784d4cc 134 if (wkc > 0)
EasyCAT 0:543d6784d4cc 135 {
EasyCAT 0:543d6784d4cc 136 /* this is strictly "less than" since the master is "slave 0" */
EasyCAT 0:543d6784d4cc 137 if (wkc < EC_MAXSLAVE)
EasyCAT 0:543d6784d4cc 138 {
EasyCAT 0:543d6784d4cc 139 *(context->slavecount) = wkc;
EasyCAT 0:543d6784d4cc 140 }
EasyCAT 0:543d6784d4cc 141 else
EasyCAT 0:543d6784d4cc 142 {
EasyCAT 0:543d6784d4cc 143 EC_PRINT("Error: too many slaves on network: num_slaves=%d, EC_MAXSLAVE=%d\n",
EasyCAT 0:543d6784d4cc 144 wkc, EC_MAXSLAVE);
EasyCAT 0:543d6784d4cc 145 return -2;
EasyCAT 0:543d6784d4cc 146 }
EasyCAT 0:543d6784d4cc 147 }
EasyCAT 0:543d6784d4cc 148 return wkc;
EasyCAT 0:543d6784d4cc 149 }
EasyCAT 0:543d6784d4cc 150
EasyCAT 0:543d6784d4cc 151 static void ecx_set_slaves_to_default(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 152 {
EasyCAT 0:543d6784d4cc 153 uint8 b;
EasyCAT 0:543d6784d4cc 154 uint16 w;
EasyCAT 0:543d6784d4cc 155 uint8 zbuf[64];
EasyCAT 0:543d6784d4cc 156 memset(&zbuf, 0x00, sizeof(zbuf));
EasyCAT 0:543d6784d4cc 157 b = 0x00;
EasyCAT 0:543d6784d4cc 158 ecx_BWR(context->port, 0x0000, ECT_REG_DLPORT , sizeof(b) , &b, EC_TIMEOUTRET3); /* deact loop manual */
EasyCAT 0:543d6784d4cc 159 w = htoes(0x0004);
EasyCAT 0:543d6784d4cc 160 ecx_BWR(context->port, 0x0000, ECT_REG_IRQMASK , sizeof(w) , &w, EC_TIMEOUTRET3); /* set IRQ mask */
EasyCAT 0:543d6784d4cc 161 ecx_BWR(context->port, 0x0000, ECT_REG_RXERR , 8 , &zbuf, EC_TIMEOUTRET3); /* reset CRC counters */
EasyCAT 0:543d6784d4cc 162 ecx_BWR(context->port, 0x0000, ECT_REG_FMMU0 , 16 * 3 , &zbuf, EC_TIMEOUTRET3); /* reset FMMU's */
EasyCAT 0:543d6784d4cc 163 ecx_BWR(context->port, 0x0000, ECT_REG_SM0 , 8 * 4 , &zbuf, EC_TIMEOUTRET3); /* reset SyncM */
EasyCAT 0:543d6784d4cc 164 b = 0x00;
EasyCAT 0:543d6784d4cc 165 ecx_BWR(context->port, 0x0000, ECT_REG_DCSYNCACT , sizeof(b) , &b, EC_TIMEOUTRET3); /* reset activation register */
EasyCAT 0:543d6784d4cc 166 ecx_BWR(context->port, 0x0000, ECT_REG_DCSYSTIME , 4 , &zbuf, EC_TIMEOUTRET3); /* reset system time+ofs */
EasyCAT 0:543d6784d4cc 167 w = htoes(0x1000);
EasyCAT 0:543d6784d4cc 168 ecx_BWR(context->port, 0x0000, ECT_REG_DCSPEEDCNT , sizeof(w) , &w, EC_TIMEOUTRET3); /* DC speedstart */
EasyCAT 0:543d6784d4cc 169 w = htoes(0x0c00);
EasyCAT 0:543d6784d4cc 170 ecx_BWR(context->port, 0x0000, ECT_REG_DCTIMEFILT , sizeof(w) , &w, EC_TIMEOUTRET3); /* DC filt expr */
EasyCAT 0:543d6784d4cc 171 b = 0x00;
EasyCAT 0:543d6784d4cc 172 ecx_BWR(context->port, 0x0000, ECT_REG_DLALIAS , sizeof(b) , &b, EC_TIMEOUTRET3); /* Ignore Alias register */
EasyCAT 0:543d6784d4cc 173 b = EC_STATE_INIT | EC_STATE_ACK;
EasyCAT 0:543d6784d4cc 174 ecx_BWR(context->port, 0x0000, ECT_REG_ALCTL , sizeof(b) , &b, EC_TIMEOUTRET3); /* Reset all slaves to Init */
EasyCAT 0:543d6784d4cc 175 b = 2;
EasyCAT 0:543d6784d4cc 176 ecx_BWR(context->port, 0x0000, ECT_REG_EEPCFG , sizeof(b) , &b, EC_TIMEOUTRET3); /* force Eeprom from PDI */
EasyCAT 0:543d6784d4cc 177 b = 0;
EasyCAT 0:543d6784d4cc 178 ecx_BWR(context->port, 0x0000, ECT_REG_EEPCFG , sizeof(b) , &b, EC_TIMEOUTRET3); /* set Eeprom to master */
EasyCAT 0:543d6784d4cc 179 }
EasyCAT 0:543d6784d4cc 180
EasyCAT 0:543d6784d4cc 181 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 182 static int ecx_config_from_table(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 183 {
EasyCAT 0:543d6784d4cc 184 int cindex;
EasyCAT 0:543d6784d4cc 185 ec_slavet *csl;
EasyCAT 0:543d6784d4cc 186
EasyCAT 0:543d6784d4cc 187 csl = &(context->slavelist[slave]);
EasyCAT 0:543d6784d4cc 188 cindex = ec_findconfig( csl->eep_man, csl->eep_id );
EasyCAT 0:543d6784d4cc 189 csl->configindex= cindex;
EasyCAT 0:543d6784d4cc 190 /* slave found in configuration table ? */
EasyCAT 0:543d6784d4cc 191 if (cindex)
EasyCAT 0:543d6784d4cc 192 {
EasyCAT 0:543d6784d4cc 193 csl->Dtype = ec_configlist[cindex].Dtype;
EasyCAT 0:543d6784d4cc 194 strcpy(csl->name ,ec_configlist[cindex].name);
EasyCAT 0:543d6784d4cc 195 csl->Ibits = ec_configlist[cindex].Ibits;
EasyCAT 0:543d6784d4cc 196 csl->Obits = ec_configlist[cindex].Obits;
EasyCAT 0:543d6784d4cc 197 if (csl->Obits)
EasyCAT 0:543d6784d4cc 198 {
EasyCAT 0:543d6784d4cc 199 csl->FMMU0func = 1;
EasyCAT 0:543d6784d4cc 200 }
EasyCAT 0:543d6784d4cc 201 if (csl->Ibits)
EasyCAT 0:543d6784d4cc 202 {
EasyCAT 0:543d6784d4cc 203 csl->FMMU1func = 2;
EasyCAT 0:543d6784d4cc 204 }
EasyCAT 0:543d6784d4cc 205 csl->FMMU[0].FMMUactive = ec_configlist[cindex].FM0ac;
EasyCAT 0:543d6784d4cc 206 csl->FMMU[1].FMMUactive = ec_configlist[cindex].FM1ac;
EasyCAT 0:543d6784d4cc 207 csl->SM[2].StartAddr = htoes(ec_configlist[cindex].SM2a);
EasyCAT 0:543d6784d4cc 208 csl->SM[2].SMflags = htoel(ec_configlist[cindex].SM2f);
EasyCAT 0:543d6784d4cc 209 /* simple (no mailbox) output slave found ? */
EasyCAT 0:543d6784d4cc 210 if (csl->Obits && !csl->SM[2].StartAddr)
EasyCAT 0:543d6784d4cc 211 {
EasyCAT 0:543d6784d4cc 212 csl->SM[0].StartAddr = htoes(0x0f00);
EasyCAT 0:543d6784d4cc 213 csl->SM[0].SMlength = htoes((csl->Obits + 7) / 8);
EasyCAT 0:543d6784d4cc 214 csl->SM[0].SMflags = htoel(EC_DEFAULTDOSM0);
EasyCAT 0:543d6784d4cc 215 csl->FMMU[0].FMMUactive = 1;
EasyCAT 0:543d6784d4cc 216 csl->FMMU[0].FMMUtype = 2;
EasyCAT 0:543d6784d4cc 217 csl->SMtype[0] = 3;
EasyCAT 0:543d6784d4cc 218 }
EasyCAT 0:543d6784d4cc 219 /* complex output slave */
EasyCAT 0:543d6784d4cc 220 else
EasyCAT 0:543d6784d4cc 221 {
EasyCAT 0:543d6784d4cc 222 csl->SM[2].SMlength = htoes((csl->Obits + 7) / 8);
EasyCAT 0:543d6784d4cc 223 csl->SMtype[2] = 3;
EasyCAT 0:543d6784d4cc 224 }
EasyCAT 0:543d6784d4cc 225 csl->SM[3].StartAddr = htoes(ec_configlist[cindex].SM3a);
EasyCAT 0:543d6784d4cc 226 csl->SM[3].SMflags = htoel(ec_configlist[cindex].SM3f);
EasyCAT 0:543d6784d4cc 227 /* simple (no mailbox) input slave found ? */
EasyCAT 0:543d6784d4cc 228 if (csl->Ibits && !csl->SM[3].StartAddr)
EasyCAT 0:543d6784d4cc 229 {
EasyCAT 0:543d6784d4cc 230 csl->SM[1].StartAddr = htoes(0x1000);
EasyCAT 0:543d6784d4cc 231 csl->SM[1].SMlength = htoes((csl->Ibits + 7) / 8);
EasyCAT 0:543d6784d4cc 232 csl->SM[1].SMflags = htoel(0x00000000);
EasyCAT 0:543d6784d4cc 233 csl->FMMU[1].FMMUactive = 1;
EasyCAT 0:543d6784d4cc 234 csl->FMMU[1].FMMUtype = 1;
EasyCAT 0:543d6784d4cc 235 csl->SMtype[1] = 4;
EasyCAT 0:543d6784d4cc 236 }
EasyCAT 0:543d6784d4cc 237 /* complex input slave */
EasyCAT 0:543d6784d4cc 238 else
EasyCAT 0:543d6784d4cc 239 {
EasyCAT 0:543d6784d4cc 240 csl->SM[3].SMlength = htoes((csl->Ibits + 7) / 8);
EasyCAT 0:543d6784d4cc 241 csl->SMtype[3] = 4;
EasyCAT 0:543d6784d4cc 242 }
EasyCAT 0:543d6784d4cc 243 }
EasyCAT 0:543d6784d4cc 244 return cindex;
EasyCAT 0:543d6784d4cc 245 }
EasyCAT 0:543d6784d4cc 246 #else
EasyCAT 0:543d6784d4cc 247 static int ecx_config_from_table(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 248 {
EasyCAT 0:543d6784d4cc 249 (void)context;
EasyCAT 0:543d6784d4cc 250 (void)slave;
EasyCAT 0:543d6784d4cc 251 return 0;
EasyCAT 0:543d6784d4cc 252 }
EasyCAT 0:543d6784d4cc 253 #endif
EasyCAT 0:543d6784d4cc 254
EasyCAT 0:543d6784d4cc 255 /* If slave has SII and same slave ID done before, use previous data.
EasyCAT 0:543d6784d4cc 256 * This is safe because SII is constant for same slave ID.
EasyCAT 0:543d6784d4cc 257 */
EasyCAT 0:543d6784d4cc 258 static int ecx_lookup_prev_sii(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 259 {
EasyCAT 0:543d6784d4cc 260 int i, nSM;
EasyCAT 0:543d6784d4cc 261 if ((slave > 1) && (*(context->slavecount) > 0))
EasyCAT 0:543d6784d4cc 262 {
EasyCAT 0:543d6784d4cc 263 i = 1;
EasyCAT 0:543d6784d4cc 264 while(((context->slavelist[i].eep_man != context->slavelist[slave].eep_man) ||
EasyCAT 0:543d6784d4cc 265 (context->slavelist[i].eep_id != context->slavelist[slave].eep_id ) ||
EasyCAT 0:543d6784d4cc 266 (context->slavelist[i].eep_rev != context->slavelist[slave].eep_rev)) &&
EasyCAT 0:543d6784d4cc 267 (i < slave))
EasyCAT 0:543d6784d4cc 268 {
EasyCAT 0:543d6784d4cc 269 i++;
EasyCAT 0:543d6784d4cc 270 }
EasyCAT 0:543d6784d4cc 271 if(i < slave)
EasyCAT 0:543d6784d4cc 272 {
EasyCAT 0:543d6784d4cc 273 context->slavelist[slave].CoEdetails = context->slavelist[i].CoEdetails;
EasyCAT 0:543d6784d4cc 274 context->slavelist[slave].FoEdetails = context->slavelist[i].FoEdetails;
EasyCAT 0:543d6784d4cc 275 context->slavelist[slave].EoEdetails = context->slavelist[i].EoEdetails;
EasyCAT 0:543d6784d4cc 276 context->slavelist[slave].SoEdetails = context->slavelist[i].SoEdetails;
EasyCAT 0:543d6784d4cc 277 if(context->slavelist[i].blockLRW > 0)
EasyCAT 0:543d6784d4cc 278 {
EasyCAT 0:543d6784d4cc 279 context->slavelist[slave].blockLRW = 1;
EasyCAT 0:543d6784d4cc 280 context->slavelist[0].blockLRW++;
EasyCAT 0:543d6784d4cc 281 }
EasyCAT 0:543d6784d4cc 282 context->slavelist[slave].Ebuscurrent = context->slavelist[i].Ebuscurrent;
EasyCAT 0:543d6784d4cc 283 context->slavelist[0].Ebuscurrent += context->slavelist[slave].Ebuscurrent;
EasyCAT 0:543d6784d4cc 284 memcpy(context->slavelist[slave].name, context->slavelist[i].name, EC_MAXNAME + 1);
EasyCAT 0:543d6784d4cc 285 for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
EasyCAT 0:543d6784d4cc 286 {
EasyCAT 0:543d6784d4cc 287 context->slavelist[slave].SM[nSM].StartAddr = context->slavelist[i].SM[nSM].StartAddr;
EasyCAT 0:543d6784d4cc 288 context->slavelist[slave].SM[nSM].SMlength = context->slavelist[i].SM[nSM].SMlength;
EasyCAT 0:543d6784d4cc 289 context->slavelist[slave].SM[nSM].SMflags = context->slavelist[i].SM[nSM].SMflags;
EasyCAT 0:543d6784d4cc 290 }
EasyCAT 0:543d6784d4cc 291 context->slavelist[slave].FMMU0func = context->slavelist[i].FMMU0func;
EasyCAT 0:543d6784d4cc 292 context->slavelist[slave].FMMU1func = context->slavelist[i].FMMU1func;
EasyCAT 0:543d6784d4cc 293 context->slavelist[slave].FMMU2func = context->slavelist[i].FMMU2func;
EasyCAT 0:543d6784d4cc 294 context->slavelist[slave].FMMU3func = context->slavelist[i].FMMU3func;
EasyCAT 0:543d6784d4cc 295 EC_PRINT("Copy SII slave %d from %d.\n", slave, i);
EasyCAT 0:543d6784d4cc 296 return 1;
EasyCAT 0:543d6784d4cc 297 }
EasyCAT 0:543d6784d4cc 298 }
EasyCAT 0:543d6784d4cc 299 return 0;
EasyCAT 0:543d6784d4cc 300 }
EasyCAT 0:543d6784d4cc 301
EasyCAT 0:543d6784d4cc 302 /** Enumerate and init all slaves.
EasyCAT 0:543d6784d4cc 303 *
EasyCAT 0:543d6784d4cc 304 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 305 * @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
EasyCAT 0:543d6784d4cc 306 * @return Workcounter of slave discover datagram = number of slaves found
EasyCAT 0:543d6784d4cc 307 */
EasyCAT 0:543d6784d4cc 308 int ecx_config_init(ecx_contextt *context, uint8 usetable)
EasyCAT 0:543d6784d4cc 309 {
EasyCAT 0:543d6784d4cc 310 uint16 slave, ADPh, configadr, ssigen;
EasyCAT 0:543d6784d4cc 311 uint16 topology, estat;
EasyCAT 0:543d6784d4cc 312 int16 topoc, slavec, aliasadr;
EasyCAT 0:543d6784d4cc 313 uint8 b,h;
EasyCAT 0:543d6784d4cc 314 uint8 SMc;
EasyCAT 0:543d6784d4cc 315 uint32 eedat;
EasyCAT 0:543d6784d4cc 316 int wkc, cindex, nSM;
EasyCAT 0:543d6784d4cc 317 uint16 val16;
EasyCAT 0:543d6784d4cc 318
EasyCAT 0:543d6784d4cc 319 EC_PRINT("ec_config_init %d\n",usetable);
EasyCAT 0:543d6784d4cc 320 ecx_init_context(context);
EasyCAT 0:543d6784d4cc 321 wkc = ecx_detect_slaves(context);
EasyCAT 0:543d6784d4cc 322 if (wkc > 0)
EasyCAT 0:543d6784d4cc 323 {
EasyCAT 0:543d6784d4cc 324 ecx_set_slaves_to_default(context);
EasyCAT 0:543d6784d4cc 325 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 326 {
EasyCAT 0:543d6784d4cc 327 ADPh = (uint16)(1 - slave);
EasyCAT 0:543d6784d4cc 328 val16 = ecx_APRDw(context->port, ADPh, ECT_REG_PDICTL, EC_TIMEOUTRET3); /* read interface type of slave */
EasyCAT 0:543d6784d4cc 329 context->slavelist[slave].Itype = etohs(val16);
EasyCAT 0:543d6784d4cc 330 /* a node offset is used to improve readability of network frames */
EasyCAT 0:543d6784d4cc 331 /* this has no impact on the number of addressable slaves (auto wrap around) */
EasyCAT 0:543d6784d4cc 332 ecx_APWRw(context->port, ADPh, ECT_REG_STADR, htoes(slave + EC_NODEOFFSET) , EC_TIMEOUTRET3); /* set node address of slave */
EasyCAT 0:543d6784d4cc 333 if (slave == 1)
EasyCAT 0:543d6784d4cc 334 {
EasyCAT 0:543d6784d4cc 335 b = 1; /* kill non ecat frames for first slave */
EasyCAT 0:543d6784d4cc 336 }
EasyCAT 0:543d6784d4cc 337 else
EasyCAT 0:543d6784d4cc 338 {
EasyCAT 0:543d6784d4cc 339 b = 0; /* pass all frames for following slaves */
EasyCAT 0:543d6784d4cc 340 }
EasyCAT 0:543d6784d4cc 341 ecx_APWRw(context->port, ADPh, ECT_REG_DLCTL, htoes(b), EC_TIMEOUTRET3); /* set non ecat frame behaviour */
EasyCAT 0:543d6784d4cc 342 configadr = ecx_APRDw(context->port, ADPh, ECT_REG_STADR, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 343 configadr = etohs(configadr);
EasyCAT 0:543d6784d4cc 344 context->slavelist[slave].configadr = configadr;
EasyCAT 0:543d6784d4cc 345 ecx_FPRD(context->port, configadr, ECT_REG_ALIAS, sizeof(aliasadr), &aliasadr, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 346 context->slavelist[slave].aliasadr = etohs(aliasadr);
EasyCAT 0:543d6784d4cc 347 ecx_FPRD(context->port, configadr, ECT_REG_EEPSTAT, sizeof(estat), &estat, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 348 estat = etohs(estat);
EasyCAT 0:543d6784d4cc 349 if (estat & EC_ESTAT_R64) /* check if slave can read 8 byte chunks */
EasyCAT 0:543d6784d4cc 350 {
EasyCAT 0:543d6784d4cc 351 context->slavelist[slave].eep_8byte = 1;
EasyCAT 0:543d6784d4cc 352 }
EasyCAT 0:543d6784d4cc 353 ecx_readeeprom1(context, slave, ECT_SII_MANUF); /* Manuf */
EasyCAT 0:543d6784d4cc 354 }
EasyCAT 0:543d6784d4cc 355 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 356 {
EasyCAT 0:543d6784d4cc 357 eedat = ecx_readeeprom2(context, slave, EC_TIMEOUTEEP); /* Manuf */
EasyCAT 0:543d6784d4cc 358 context->slavelist[slave].eep_man = etohl(eedat);
EasyCAT 0:543d6784d4cc 359 ecx_readeeprom1(context, slave, ECT_SII_ID); /* ID */
EasyCAT 0:543d6784d4cc 360 }
EasyCAT 0:543d6784d4cc 361 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 362 {
EasyCAT 0:543d6784d4cc 363 eedat = ecx_readeeprom2(context, slave, EC_TIMEOUTEEP); /* ID */
EasyCAT 0:543d6784d4cc 364 context->slavelist[slave].eep_id = etohl(eedat);
EasyCAT 0:543d6784d4cc 365 ecx_readeeprom1(context, slave, ECT_SII_REV); /* revision */
EasyCAT 0:543d6784d4cc 366 }
EasyCAT 0:543d6784d4cc 367 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 368 {
EasyCAT 0:543d6784d4cc 369 eedat = ecx_readeeprom2(context, slave, EC_TIMEOUTEEP); /* revision */
EasyCAT 0:543d6784d4cc 370 context->slavelist[slave].eep_rev = etohl(eedat);
EasyCAT 0:543d6784d4cc 371 ecx_readeeprom1(context, slave, ECT_SII_RXMBXADR); /* write mailbox address + mailboxsize */
EasyCAT 0:543d6784d4cc 372 }
EasyCAT 0:543d6784d4cc 373 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 374 {
EasyCAT 0:543d6784d4cc 375 eedat = ecx_readeeprom2(context, slave, EC_TIMEOUTEEP); /* write mailbox address and mailboxsize */
EasyCAT 0:543d6784d4cc 376 context->slavelist[slave].mbx_wo = (uint16)LO_WORD(etohl(eedat));
EasyCAT 0:543d6784d4cc 377 context->slavelist[slave].mbx_l = (uint16)HI_WORD(etohl(eedat));
EasyCAT 0:543d6784d4cc 378 if (context->slavelist[slave].mbx_l > 0)
EasyCAT 0:543d6784d4cc 379 {
EasyCAT 0:543d6784d4cc 380 ecx_readeeprom1(context, slave, ECT_SII_TXMBXADR); /* read mailbox offset */
EasyCAT 0:543d6784d4cc 381 }
EasyCAT 0:543d6784d4cc 382 }
EasyCAT 0:543d6784d4cc 383 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 384 {
EasyCAT 0:543d6784d4cc 385 if (context->slavelist[slave].mbx_l > 0)
EasyCAT 0:543d6784d4cc 386 {
EasyCAT 0:543d6784d4cc 387 eedat = ecx_readeeprom2(context, slave, EC_TIMEOUTEEP); /* read mailbox offset */
EasyCAT 0:543d6784d4cc 388 context->slavelist[slave].mbx_ro = (uint16)LO_WORD(etohl(eedat)); /* read mailbox offset */
EasyCAT 0:543d6784d4cc 389 context->slavelist[slave].mbx_rl = (uint16)HI_WORD(etohl(eedat)); /*read mailbox length */
EasyCAT 0:543d6784d4cc 390 if (context->slavelist[slave].mbx_rl == 0)
EasyCAT 0:543d6784d4cc 391 {
EasyCAT 0:543d6784d4cc 392 context->slavelist[slave].mbx_rl = context->slavelist[slave].mbx_l;
EasyCAT 0:543d6784d4cc 393 }
EasyCAT 0:543d6784d4cc 394 ecx_readeeprom1(context, slave, ECT_SII_MBXPROTO);
EasyCAT 0:543d6784d4cc 395 }
EasyCAT 0:543d6784d4cc 396 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 397 val16 = ecx_FPRDw(context->port, configadr, ECT_REG_ESCSUP, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 398 if ((etohs(val16) & 0x04) > 0) /* Support DC? */
EasyCAT 0:543d6784d4cc 399 {
EasyCAT 0:543d6784d4cc 400 context->slavelist[slave].hasdc = TRUE;
EasyCAT 0:543d6784d4cc 401 }
EasyCAT 0:543d6784d4cc 402 else
EasyCAT 0:543d6784d4cc 403 {
EasyCAT 0:543d6784d4cc 404 context->slavelist[slave].hasdc = FALSE;
EasyCAT 0:543d6784d4cc 405 }
EasyCAT 0:543d6784d4cc 406 topology = ecx_FPRDw(context->port, configadr, ECT_REG_DLSTAT, EC_TIMEOUTRET3); /* extract topology from DL status */
EasyCAT 0:543d6784d4cc 407 topology = etohs(topology);
EasyCAT 0:543d6784d4cc 408 h = 0;
EasyCAT 0:543d6784d4cc 409 b = 0;
EasyCAT 0:543d6784d4cc 410 if ((topology & 0x0300) == 0x0200) /* port0 open and communication established */
EasyCAT 0:543d6784d4cc 411 {
EasyCAT 0:543d6784d4cc 412 h++;
EasyCAT 0:543d6784d4cc 413 b |= 0x01;
EasyCAT 0:543d6784d4cc 414 }
EasyCAT 0:543d6784d4cc 415 if ((topology & 0x0c00) == 0x0800) /* port1 open and communication established */
EasyCAT 0:543d6784d4cc 416 {
EasyCAT 0:543d6784d4cc 417 h++;
EasyCAT 0:543d6784d4cc 418 b |= 0x02;
EasyCAT 0:543d6784d4cc 419 }
EasyCAT 0:543d6784d4cc 420 if ((topology & 0x3000) == 0x2000) /* port2 open and communication established */
EasyCAT 0:543d6784d4cc 421 {
EasyCAT 0:543d6784d4cc 422 h++;
EasyCAT 0:543d6784d4cc 423 b |= 0x04;
EasyCAT 0:543d6784d4cc 424 }
EasyCAT 0:543d6784d4cc 425 if ((topology & 0xc000) == 0x8000) /* port3 open and communication established */
EasyCAT 0:543d6784d4cc 426 {
EasyCAT 0:543d6784d4cc 427 h++;
EasyCAT 0:543d6784d4cc 428 b |= 0x08;
EasyCAT 0:543d6784d4cc 429 }
EasyCAT 0:543d6784d4cc 430 /* ptype = Physical type*/
EasyCAT 0:543d6784d4cc 431 val16 = ecx_FPRDw(context->port, configadr, ECT_REG_PORTDES, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 432 context->slavelist[slave].ptype = LO_BYTE(etohs(val16));
EasyCAT 0:543d6784d4cc 433 context->slavelist[slave].topology = h;
EasyCAT 0:543d6784d4cc 434 context->slavelist[slave].activeports = b;
EasyCAT 0:543d6784d4cc 435 /* 0=no links, not possible */
EasyCAT 0:543d6784d4cc 436 /* 1=1 link , end of line */
EasyCAT 0:543d6784d4cc 437 /* 2=2 links , one before and one after */
EasyCAT 0:543d6784d4cc 438 /* 3=3 links , split point */
EasyCAT 0:543d6784d4cc 439 /* 4=4 links , cross point */
EasyCAT 0:543d6784d4cc 440 /* search for parent */
EasyCAT 0:543d6784d4cc 441 context->slavelist[slave].parent = 0; /* parent is master */
EasyCAT 0:543d6784d4cc 442 if (slave > 1)
EasyCAT 0:543d6784d4cc 443 {
EasyCAT 0:543d6784d4cc 444 topoc = 0;
EasyCAT 0:543d6784d4cc 445 slavec = slave - 1;
EasyCAT 0:543d6784d4cc 446 do
EasyCAT 0:543d6784d4cc 447 {
EasyCAT 0:543d6784d4cc 448 topology = context->slavelist[slavec].topology;
EasyCAT 0:543d6784d4cc 449 if (topology == 1)
EasyCAT 0:543d6784d4cc 450 {
EasyCAT 0:543d6784d4cc 451 topoc--; /* endpoint found */
EasyCAT 0:543d6784d4cc 452 }
EasyCAT 0:543d6784d4cc 453 if (topology == 3)
EasyCAT 0:543d6784d4cc 454 {
EasyCAT 0:543d6784d4cc 455 topoc++; /* split found */
EasyCAT 0:543d6784d4cc 456 }
EasyCAT 0:543d6784d4cc 457 if (topology == 4)
EasyCAT 0:543d6784d4cc 458 {
EasyCAT 0:543d6784d4cc 459 topoc += 2; /* cross found */
EasyCAT 0:543d6784d4cc 460 }
EasyCAT 0:543d6784d4cc 461 if (((topoc >= 0) && (topology > 1)) ||
EasyCAT 0:543d6784d4cc 462 (slavec == 1)) /* parent found */
EasyCAT 0:543d6784d4cc 463 {
EasyCAT 0:543d6784d4cc 464 context->slavelist[slave].parent = slavec;
EasyCAT 0:543d6784d4cc 465 slavec = 1;
EasyCAT 0:543d6784d4cc 466 }
EasyCAT 0:543d6784d4cc 467 slavec--;
EasyCAT 0:543d6784d4cc 468 }
EasyCAT 0:543d6784d4cc 469 while (slavec > 0);
EasyCAT 0:543d6784d4cc 470 }
EasyCAT 0:543d6784d4cc 471 (void)ecx_statecheck(context, slave, EC_STATE_INIT, EC_TIMEOUTSTATE); //* check state change Init */
EasyCAT 0:543d6784d4cc 472
EasyCAT 0:543d6784d4cc 473 /* set default mailbox configuration if slave has mailbox */
EasyCAT 0:543d6784d4cc 474 if (context->slavelist[slave].mbx_l>0)
EasyCAT 0:543d6784d4cc 475 {
EasyCAT 0:543d6784d4cc 476 context->slavelist[slave].SMtype[0] = 1;
EasyCAT 0:543d6784d4cc 477 context->slavelist[slave].SMtype[1] = 2;
EasyCAT 0:543d6784d4cc 478 context->slavelist[slave].SMtype[2] = 3;
EasyCAT 0:543d6784d4cc 479 context->slavelist[slave].SMtype[3] = 4;
EasyCAT 0:543d6784d4cc 480 context->slavelist[slave].SM[0].StartAddr = htoes(context->slavelist[slave].mbx_wo);
EasyCAT 0:543d6784d4cc 481 context->slavelist[slave].SM[0].SMlength = htoes(context->slavelist[slave].mbx_l);
EasyCAT 0:543d6784d4cc 482 context->slavelist[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0);
EasyCAT 0:543d6784d4cc 483 context->slavelist[slave].SM[1].StartAddr = htoes(context->slavelist[slave].mbx_ro);
EasyCAT 0:543d6784d4cc 484 context->slavelist[slave].SM[1].SMlength = htoes(context->slavelist[slave].mbx_rl);
EasyCAT 0:543d6784d4cc 485 context->slavelist[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1);
EasyCAT 0:543d6784d4cc 486 eedat = ecx_readeeprom2(context, slave, EC_TIMEOUTEEP);
EasyCAT 0:543d6784d4cc 487 context->slavelist[slave].mbx_proto = etohl(eedat);
EasyCAT 0:543d6784d4cc 488 }
EasyCAT 0:543d6784d4cc 489 cindex = 0;
EasyCAT 0:543d6784d4cc 490 /* use configuration table ? */
EasyCAT 0:543d6784d4cc 491 if (usetable == 1)
EasyCAT 0:543d6784d4cc 492 {
EasyCAT 0:543d6784d4cc 493 cindex = ecx_config_from_table(context, slave);
EasyCAT 0:543d6784d4cc 494 }
EasyCAT 0:543d6784d4cc 495 /* slave not in configuration table, find out via SII */
EasyCAT 0:543d6784d4cc 496 if (!cindex && !ecx_lookup_prev_sii(context, slave))
EasyCAT 0:543d6784d4cc 497 {
EasyCAT 0:543d6784d4cc 498 ssigen = ecx_siifind(context, slave, ECT_SII_GENERAL);
EasyCAT 0:543d6784d4cc 499 /* SII general section */
EasyCAT 0:543d6784d4cc 500 if (ssigen)
EasyCAT 0:543d6784d4cc 501 {
EasyCAT 0:543d6784d4cc 502 context->slavelist[slave].CoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x07);
EasyCAT 0:543d6784d4cc 503 context->slavelist[slave].FoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x08);
EasyCAT 0:543d6784d4cc 504 context->slavelist[slave].EoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x09);
EasyCAT 0:543d6784d4cc 505 context->slavelist[slave].SoEdetails = ecx_siigetbyte(context, slave, ssigen + 0x0a);
EasyCAT 0:543d6784d4cc 506 if((ecx_siigetbyte(context, slave, ssigen + 0x0d) & 0x02) > 0)
EasyCAT 0:543d6784d4cc 507 {
EasyCAT 0:543d6784d4cc 508 context->slavelist[slave].blockLRW = 1;
EasyCAT 0:543d6784d4cc 509 context->slavelist[0].blockLRW++;
EasyCAT 0:543d6784d4cc 510 }
EasyCAT 0:543d6784d4cc 511 context->slavelist[slave].Ebuscurrent = ecx_siigetbyte(context, slave, ssigen + 0x0e);
EasyCAT 0:543d6784d4cc 512 context->slavelist[slave].Ebuscurrent += ecx_siigetbyte(context, slave, ssigen + 0x0f) << 8;
EasyCAT 0:543d6784d4cc 513 context->slavelist[0].Ebuscurrent += context->slavelist[slave].Ebuscurrent;
EasyCAT 0:543d6784d4cc 514 }
EasyCAT 0:543d6784d4cc 515 /* SII strings section */
EasyCAT 0:543d6784d4cc 516 if (ecx_siifind(context, slave, ECT_SII_STRING) > 0)
EasyCAT 0:543d6784d4cc 517 {
EasyCAT 0:543d6784d4cc 518 ecx_siistring(context, context->slavelist[slave].name, slave, 1);
EasyCAT 0:543d6784d4cc 519 }
EasyCAT 0:543d6784d4cc 520 /* no name for slave found, use constructed name */
EasyCAT 0:543d6784d4cc 521 else
EasyCAT 0:543d6784d4cc 522 {
EasyCAT 0:543d6784d4cc 523 sprintf(context->slavelist[slave].name, "? M:%8.8x I:%8.8x",
EasyCAT 0:543d6784d4cc 524 (unsigned int)context->slavelist[slave].eep_man,
EasyCAT 0:543d6784d4cc 525 (unsigned int)context->slavelist[slave].eep_id);
EasyCAT 0:543d6784d4cc 526 }
EasyCAT 0:543d6784d4cc 527 /* SII SM section */
EasyCAT 0:543d6784d4cc 528 nSM = ecx_siiSM(context, slave, context->eepSM);
EasyCAT 0:543d6784d4cc 529 if (nSM>0)
EasyCAT 0:543d6784d4cc 530 {
EasyCAT 0:543d6784d4cc 531 context->slavelist[slave].SM[0].StartAddr = htoes(context->eepSM->PhStart);
EasyCAT 0:543d6784d4cc 532 context->slavelist[slave].SM[0].SMlength = htoes(context->eepSM->Plength);
EasyCAT 0:543d6784d4cc 533 context->slavelist[slave].SM[0].SMflags =
EasyCAT 0:543d6784d4cc 534 htoel((context->eepSM->Creg) + (context->eepSM->Activate << 16));
EasyCAT 0:543d6784d4cc 535 SMc = 1;
EasyCAT 0:543d6784d4cc 536 while ((SMc < EC_MAXSM) && ecx_siiSMnext(context, slave, context->eepSM, SMc))
EasyCAT 0:543d6784d4cc 537 {
EasyCAT 0:543d6784d4cc 538 context->slavelist[slave].SM[SMc].StartAddr = htoes(context->eepSM->PhStart);
EasyCAT 0:543d6784d4cc 539 context->slavelist[slave].SM[SMc].SMlength = htoes(context->eepSM->Plength);
EasyCAT 0:543d6784d4cc 540 context->slavelist[slave].SM[SMc].SMflags =
EasyCAT 0:543d6784d4cc 541 htoel((context->eepSM->Creg) + (context->eepSM->Activate << 16));
EasyCAT 0:543d6784d4cc 542 SMc++;
EasyCAT 0:543d6784d4cc 543 }
EasyCAT 0:543d6784d4cc 544 }
EasyCAT 0:543d6784d4cc 545 /* SII FMMU section */
EasyCAT 0:543d6784d4cc 546 if (ecx_siiFMMU(context, slave, context->eepFMMU))
EasyCAT 0:543d6784d4cc 547 {
EasyCAT 0:543d6784d4cc 548 if (context->eepFMMU->FMMU0 !=0xff)
EasyCAT 0:543d6784d4cc 549 {
EasyCAT 0:543d6784d4cc 550 context->slavelist[slave].FMMU0func = context->eepFMMU->FMMU0;
EasyCAT 0:543d6784d4cc 551 }
EasyCAT 0:543d6784d4cc 552 if (context->eepFMMU->FMMU1 !=0xff)
EasyCAT 0:543d6784d4cc 553 {
EasyCAT 0:543d6784d4cc 554 context->slavelist[slave].FMMU1func = context->eepFMMU->FMMU1;
EasyCAT 0:543d6784d4cc 555 }
EasyCAT 0:543d6784d4cc 556 if (context->eepFMMU->FMMU2 !=0xff)
EasyCAT 0:543d6784d4cc 557 {
EasyCAT 0:543d6784d4cc 558 context->slavelist[slave].FMMU2func = context->eepFMMU->FMMU2;
EasyCAT 0:543d6784d4cc 559 }
EasyCAT 0:543d6784d4cc 560 if (context->eepFMMU->FMMU3 !=0xff)
EasyCAT 0:543d6784d4cc 561 {
EasyCAT 0:543d6784d4cc 562 context->slavelist[slave].FMMU3func = context->eepFMMU->FMMU3;
EasyCAT 0:543d6784d4cc 563 }
EasyCAT 0:543d6784d4cc 564 }
EasyCAT 0:543d6784d4cc 565 }
EasyCAT 0:543d6784d4cc 566
EasyCAT 0:543d6784d4cc 567 if (context->slavelist[slave].mbx_l > 0)
EasyCAT 0:543d6784d4cc 568 {
EasyCAT 0:543d6784d4cc 569 if (context->slavelist[slave].SM[0].StartAddr == 0x0000) /* should never happen */
EasyCAT 0:543d6784d4cc 570 {
EasyCAT 0:543d6784d4cc 571 EC_PRINT("Slave %d has no proper mailbox in configuration, try default.\n", slave);
EasyCAT 0:543d6784d4cc 572 context->slavelist[slave].SM[0].StartAddr = htoes(0x1000);
EasyCAT 0:543d6784d4cc 573 context->slavelist[slave].SM[0].SMlength = htoes(0x0080);
EasyCAT 0:543d6784d4cc 574 context->slavelist[slave].SM[0].SMflags = htoel(EC_DEFAULTMBXSM0);
EasyCAT 0:543d6784d4cc 575 context->slavelist[slave].SMtype[0] = 1;
EasyCAT 0:543d6784d4cc 576 }
EasyCAT 0:543d6784d4cc 577 if (context->slavelist[slave].SM[1].StartAddr == 0x0000) /* should never happen */
EasyCAT 0:543d6784d4cc 578 {
EasyCAT 0:543d6784d4cc 579 EC_PRINT("Slave %d has no proper mailbox out configuration, try default.\n", slave);
EasyCAT 0:543d6784d4cc 580 context->slavelist[slave].SM[1].StartAddr = htoes(0x1080);
EasyCAT 0:543d6784d4cc 581 context->slavelist[slave].SM[1].SMlength = htoes(0x0080);
EasyCAT 0:543d6784d4cc 582 context->slavelist[slave].SM[1].SMflags = htoel(EC_DEFAULTMBXSM1);
EasyCAT 0:543d6784d4cc 583 context->slavelist[slave].SMtype[1] = 2;
EasyCAT 0:543d6784d4cc 584 }
EasyCAT 0:543d6784d4cc 585 /* program SM0 mailbox in and SM1 mailbox out for slave */
EasyCAT 0:543d6784d4cc 586 /* writing both SM in one datagram will solve timing issue in old NETX */
EasyCAT 0:543d6784d4cc 587 ecx_FPWR(context->port, configadr, ECT_REG_SM0, sizeof(ec_smt) * 2,
EasyCAT 0:543d6784d4cc 588 &(context->slavelist[slave].SM[0]), EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 589 }
EasyCAT 0:543d6784d4cc 590 /* some slaves need eeprom available to PDI in init->preop transition */
EasyCAT 0:543d6784d4cc 591 ecx_eeprom2pdi(context, slave);
EasyCAT 0:543d6784d4cc 592 /* request pre_op for slave */
EasyCAT 0:543d6784d4cc 593 ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP | EC_STATE_ACK) , EC_TIMEOUTRET3); /* set preop status */
EasyCAT 0:543d6784d4cc 594 }
EasyCAT 0:543d6784d4cc 595 }
EasyCAT 0:543d6784d4cc 596 return wkc;
EasyCAT 0:543d6784d4cc 597 }
EasyCAT 0:543d6784d4cc 598
EasyCAT 0:543d6784d4cc 599 /* If slave has SII mapping and same slave ID done before, use previous mapping.
EasyCAT 0:543d6784d4cc 600 * This is safe because SII mapping is constant for same slave ID.
EasyCAT 0:543d6784d4cc 601 */
EasyCAT 0:543d6784d4cc 602 static int ecx_lookup_mapping(ecx_contextt *context, uint16 slave, int *Osize, int *Isize)
EasyCAT 0:543d6784d4cc 603 {
EasyCAT 0:543d6784d4cc 604 int i, nSM;
EasyCAT 0:543d6784d4cc 605 if ((slave > 1) && (*(context->slavecount) > 0))
EasyCAT 0:543d6784d4cc 606 {
EasyCAT 0:543d6784d4cc 607 i = 1;
EasyCAT 0:543d6784d4cc 608 while(((context->slavelist[i].eep_man != context->slavelist[slave].eep_man) ||
EasyCAT 0:543d6784d4cc 609 (context->slavelist[i].eep_id != context->slavelist[slave].eep_id ) ||
EasyCAT 0:543d6784d4cc 610 (context->slavelist[i].eep_rev != context->slavelist[slave].eep_rev)) &&
EasyCAT 0:543d6784d4cc 611 (i < slave))
EasyCAT 0:543d6784d4cc 612 {
EasyCAT 0:543d6784d4cc 613 i++;
EasyCAT 0:543d6784d4cc 614 }
EasyCAT 0:543d6784d4cc 615 if(i < slave)
EasyCAT 0:543d6784d4cc 616 {
EasyCAT 0:543d6784d4cc 617 for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
EasyCAT 0:543d6784d4cc 618 {
EasyCAT 0:543d6784d4cc 619 context->slavelist[slave].SM[nSM].SMlength = context->slavelist[i].SM[nSM].SMlength;
EasyCAT 0:543d6784d4cc 620 context->slavelist[slave].SMtype[nSM] = context->slavelist[i].SMtype[nSM];
EasyCAT 0:543d6784d4cc 621 }
EasyCAT 0:543d6784d4cc 622 *Osize = context->slavelist[i].Obits;
EasyCAT 0:543d6784d4cc 623 *Isize = context->slavelist[i].Ibits;
EasyCAT 0:543d6784d4cc 624 context->slavelist[slave].Obits = *Osize;
EasyCAT 0:543d6784d4cc 625 context->slavelist[slave].Ibits = *Isize;
EasyCAT 0:543d6784d4cc 626 EC_PRINT("Copy mapping slave %d from %d.\n", slave, i);
EasyCAT 0:543d6784d4cc 627 return 1;
EasyCAT 0:543d6784d4cc 628 }
EasyCAT 0:543d6784d4cc 629 }
EasyCAT 0:543d6784d4cc 630 return 0;
EasyCAT 0:543d6784d4cc 631 }
EasyCAT 0:543d6784d4cc 632
EasyCAT 0:543d6784d4cc 633 static int ecx_map_coe_soe(ecx_contextt *context, uint16 slave, int thread_n)
EasyCAT 0:543d6784d4cc 634 {
EasyCAT 0:543d6784d4cc 635 int Isize, Osize;
EasyCAT 0:543d6784d4cc 636 int rval;
EasyCAT 0:543d6784d4cc 637
EasyCAT 0:543d6784d4cc 638 ecx_statecheck(context, slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */
EasyCAT 0:543d6784d4cc 639
EasyCAT 0:543d6784d4cc 640 EC_PRINT(" >Slave %d, configadr %x, state %2.2x\n",
EasyCAT 0:543d6784d4cc 641 slave, context->slavelist[slave].configadr, context->slavelist[slave].state);
EasyCAT 0:543d6784d4cc 642
EasyCAT 0:543d6784d4cc 643 /* execute special slave configuration hook Pre-Op to Safe-OP */
EasyCAT 0:543d6784d4cc 644 if(context->slavelist[slave].PO2SOconfig) /* only if registered */
EasyCAT 0:543d6784d4cc 645 {
EasyCAT 0:543d6784d4cc 646 context->slavelist[slave].PO2SOconfig(slave);
EasyCAT 0:543d6784d4cc 647 }
EasyCAT 0:543d6784d4cc 648 /* if slave not found in configlist find IO mapping in slave self */
EasyCAT 0:543d6784d4cc 649 if (!context->slavelist[slave].configindex)
EasyCAT 0:543d6784d4cc 650 {
EasyCAT 0:543d6784d4cc 651 Isize = 0;
EasyCAT 0:543d6784d4cc 652 Osize = 0;
EasyCAT 0:543d6784d4cc 653 if (context->slavelist[slave].mbx_proto & ECT_MBXPROT_COE) /* has CoE */
EasyCAT 0:543d6784d4cc 654 {
EasyCAT 0:543d6784d4cc 655 rval = 0;
EasyCAT 0:543d6784d4cc 656 if (context->slavelist[slave].CoEdetails & ECT_COEDET_SDOCA) /* has Complete Access */
EasyCAT 0:543d6784d4cc 657 {
EasyCAT 0:543d6784d4cc 658 /* read PDO mapping via CoE and use Complete Access */
EasyCAT 0:543d6784d4cc 659 rval = ecx_readPDOmapCA(context, slave, thread_n, &Osize, &Isize);
EasyCAT 0:543d6784d4cc 660 }
EasyCAT 0:543d6784d4cc 661 if (!rval) /* CA not available or not succeeded */
EasyCAT 0:543d6784d4cc 662 {
EasyCAT 0:543d6784d4cc 663 /* read PDO mapping via CoE */
EasyCAT 0:543d6784d4cc 664 rval = ecx_readPDOmap(context, slave, &Osize, &Isize);
EasyCAT 0:543d6784d4cc 665 }
EasyCAT 0:543d6784d4cc 666 EC_PRINT(" CoE Osize:%d Isize:%d\n", Osize, Isize);
EasyCAT 0:543d6784d4cc 667 }
EasyCAT 0:543d6784d4cc 668 if ((!Isize && !Osize) && (context->slavelist[slave].mbx_proto & ECT_MBXPROT_SOE)) /* has SoE */
EasyCAT 0:543d6784d4cc 669 {
EasyCAT 0:543d6784d4cc 670 /* read AT / MDT mapping via SoE */
EasyCAT 0:543d6784d4cc 671 rval = ecx_readIDNmap(context, slave, &Osize, &Isize);
EasyCAT 0:543d6784d4cc 672 context->slavelist[slave].SM[2].SMlength = htoes((Osize + 7) / 8);
EasyCAT 0:543d6784d4cc 673 context->slavelist[slave].SM[3].SMlength = htoes((Isize + 7) / 8);
EasyCAT 0:543d6784d4cc 674 EC_PRINT(" SoE Osize:%d Isize:%d\n", Osize, Isize);
EasyCAT 0:543d6784d4cc 675 }
EasyCAT 0:543d6784d4cc 676 context->slavelist[slave].Obits = Osize;
EasyCAT 0:543d6784d4cc 677 context->slavelist[slave].Ibits = Isize;
EasyCAT 0:543d6784d4cc 678 }
EasyCAT 0:543d6784d4cc 679
EasyCAT 0:543d6784d4cc 680 return 1;
EasyCAT 0:543d6784d4cc 681 }
EasyCAT 0:543d6784d4cc 682
EasyCAT 0:543d6784d4cc 683 static int ecx_map_sii(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 684 {
EasyCAT 0:543d6784d4cc 685 int Isize, Osize;
EasyCAT 0:543d6784d4cc 686 int nSM;
EasyCAT 0:543d6784d4cc 687 ec_eepromPDOt eepPDO;
EasyCAT 0:543d6784d4cc 688
EasyCAT 0:543d6784d4cc 689 Osize = context->slavelist[slave].Obits;
EasyCAT 0:543d6784d4cc 690 Isize = context->slavelist[slave].Ibits;
EasyCAT 0:543d6784d4cc 691
EasyCAT 0:543d6784d4cc 692 if (!Isize && !Osize) /* find PDO in previous slave with same ID */
EasyCAT 0:543d6784d4cc 693 {
EasyCAT 0:543d6784d4cc 694 (void)ecx_lookup_mapping(context, slave, &Osize, &Isize);
EasyCAT 0:543d6784d4cc 695 }
EasyCAT 0:543d6784d4cc 696 if (!Isize && !Osize) /* find PDO mapping by SII */
EasyCAT 0:543d6784d4cc 697 {
EasyCAT 0:543d6784d4cc 698 memset(&eepPDO, 0, sizeof(eepPDO));
EasyCAT 0:543d6784d4cc 699 Isize = (int)ecx_siiPDO(context, slave, &eepPDO, 0);
EasyCAT 0:543d6784d4cc 700 EC_PRINT(" SII Isize:%d\n", Isize);
EasyCAT 0:543d6784d4cc 701 for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
EasyCAT 0:543d6784d4cc 702 {
EasyCAT 0:543d6784d4cc 703 if (eepPDO.SMbitsize[nSM] > 0)
EasyCAT 0:543d6784d4cc 704 {
EasyCAT 0:543d6784d4cc 705 context->slavelist[slave].SM[nSM].SMlength = htoes((eepPDO.SMbitsize[nSM] + 7) / 8);
EasyCAT 0:543d6784d4cc 706 context->slavelist[slave].SMtype[nSM] = 4;
EasyCAT 0:543d6784d4cc 707 EC_PRINT(" SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]);
EasyCAT 0:543d6784d4cc 708 }
EasyCAT 0:543d6784d4cc 709 }
EasyCAT 0:543d6784d4cc 710 Osize = (int)ecx_siiPDO(context, slave, &eepPDO, 1);
EasyCAT 0:543d6784d4cc 711 EC_PRINT(" SII Osize:%d\n", Osize);
EasyCAT 0:543d6784d4cc 712 for( nSM=0 ; nSM < EC_MAXSM ; nSM++ )
EasyCAT 0:543d6784d4cc 713 {
EasyCAT 0:543d6784d4cc 714 if (eepPDO.SMbitsize[nSM] > 0)
EasyCAT 0:543d6784d4cc 715 {
EasyCAT 0:543d6784d4cc 716 context->slavelist[slave].SM[nSM].SMlength = htoes((eepPDO.SMbitsize[nSM] + 7) / 8);
EasyCAT 0:543d6784d4cc 717 context->slavelist[slave].SMtype[nSM] = 3;
EasyCAT 0:543d6784d4cc 718 EC_PRINT(" SM%d length %d\n", nSM, eepPDO.SMbitsize[nSM]);
EasyCAT 0:543d6784d4cc 719 }
EasyCAT 0:543d6784d4cc 720 }
EasyCAT 0:543d6784d4cc 721 }
EasyCAT 0:543d6784d4cc 722 context->slavelist[slave].Obits = Osize;
EasyCAT 0:543d6784d4cc 723 context->slavelist[slave].Ibits = Isize;
EasyCAT 0:543d6784d4cc 724 EC_PRINT(" ISIZE:%d %d OSIZE:%d\n",
EasyCAT 0:543d6784d4cc 725 context->slavelist[slave].Ibits, Isize,context->slavelist[slave].Obits);
EasyCAT 0:543d6784d4cc 726
EasyCAT 0:543d6784d4cc 727 return 1;
EasyCAT 0:543d6784d4cc 728 }
EasyCAT 0:543d6784d4cc 729
EasyCAT 0:543d6784d4cc 730 static int ecx_map_sm(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 731 {
EasyCAT 0:543d6784d4cc 732 uint16 configadr;
EasyCAT 0:543d6784d4cc 733 int nSM;
EasyCAT 0:543d6784d4cc 734
EasyCAT 0:543d6784d4cc 735 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 736
EasyCAT 0:543d6784d4cc 737 EC_PRINT(" SM programming\n");
EasyCAT 0:543d6784d4cc 738 if (!context->slavelist[slave].mbx_l && context->slavelist[slave].SM[0].StartAddr)
EasyCAT 0:543d6784d4cc 739 {
EasyCAT 0:543d6784d4cc 740 ecx_FPWR(context->port, configadr, ECT_REG_SM0,
EasyCAT 0:543d6784d4cc 741 sizeof(ec_smt), &(context->slavelist[slave].SM[0]), EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 742 EC_PRINT(" SM0 Type:%d StartAddr:%4.4x Flags:%8.8x\n",
EasyCAT 0:543d6784d4cc 743 context->slavelist[slave].SMtype[0],
EasyCAT 0:543d6784d4cc 744 context->slavelist[slave].SM[0].StartAddr,
EasyCAT 0:543d6784d4cc 745 context->slavelist[slave].SM[0].SMflags);
EasyCAT 0:543d6784d4cc 746 }
EasyCAT 0:543d6784d4cc 747 if (!context->slavelist[slave].mbx_l && context->slavelist[slave].SM[1].StartAddr)
EasyCAT 0:543d6784d4cc 748 {
EasyCAT 0:543d6784d4cc 749 ecx_FPWR(context->port, configadr, ECT_REG_SM1,
EasyCAT 0:543d6784d4cc 750 sizeof(ec_smt), &context->slavelist[slave].SM[1], EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 751 EC_PRINT(" SM1 Type:%d StartAddr:%4.4x Flags:%8.8x\n",
EasyCAT 0:543d6784d4cc 752 context->slavelist[slave].SMtype[1],
EasyCAT 0:543d6784d4cc 753 context->slavelist[slave].SM[1].StartAddr,
EasyCAT 0:543d6784d4cc 754 context->slavelist[slave].SM[1].SMflags);
EasyCAT 0:543d6784d4cc 755 }
EasyCAT 0:543d6784d4cc 756 /* program SM2 to SMx */
EasyCAT 0:543d6784d4cc 757 for( nSM = 2 ; nSM < EC_MAXSM ; nSM++ )
EasyCAT 0:543d6784d4cc 758 {
EasyCAT 0:543d6784d4cc 759 if (context->slavelist[slave].SM[nSM].StartAddr)
EasyCAT 0:543d6784d4cc 760 {
EasyCAT 0:543d6784d4cc 761 /* check if SM length is zero -> clear enable flag */
EasyCAT 0:543d6784d4cc 762 if( context->slavelist[slave].SM[nSM].SMlength == 0)
EasyCAT 0:543d6784d4cc 763 {
EasyCAT 0:543d6784d4cc 764 context->slavelist[slave].SM[nSM].SMflags =
EasyCAT 0:543d6784d4cc 765 htoel( etohl(context->slavelist[slave].SM[nSM].SMflags) & EC_SMENABLEMASK);
EasyCAT 0:543d6784d4cc 766 }
EasyCAT 0:543d6784d4cc 767 /* if SM length is non zero always set enable flag */
EasyCAT 0:543d6784d4cc 768 else
EasyCAT 0:543d6784d4cc 769 {
EasyCAT 0:543d6784d4cc 770 context->slavelist[slave].SM[nSM].SMflags =
EasyCAT 0:543d6784d4cc 771 htoel( etohl(context->slavelist[slave].SM[nSM].SMflags) | ~EC_SMENABLEMASK);
EasyCAT 0:543d6784d4cc 772 }
EasyCAT 0:543d6784d4cc 773 ecx_FPWR(context->port, configadr, (uint16)(ECT_REG_SM0 + (nSM * sizeof(ec_smt))),
EasyCAT 0:543d6784d4cc 774 sizeof(ec_smt), &context->slavelist[slave].SM[nSM], EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 775 EC_PRINT(" SM%d Type:%d StartAddr:%4.4x Flags:%8.8x\n", nSM,
EasyCAT 0:543d6784d4cc 776 context->slavelist[slave].SMtype[nSM],
EasyCAT 0:543d6784d4cc 777 context->slavelist[slave].SM[nSM].StartAddr,
EasyCAT 0:543d6784d4cc 778 context->slavelist[slave].SM[nSM].SMflags);
EasyCAT 0:543d6784d4cc 779 }
EasyCAT 0:543d6784d4cc 780 }
EasyCAT 0:543d6784d4cc 781 if (context->slavelist[slave].Ibits > 7)
EasyCAT 0:543d6784d4cc 782 {
EasyCAT 0:543d6784d4cc 783 context->slavelist[slave].Ibytes = (context->slavelist[slave].Ibits + 7) / 8;
EasyCAT 0:543d6784d4cc 784 }
EasyCAT 0:543d6784d4cc 785 if (context->slavelist[slave].Obits > 7)
EasyCAT 0:543d6784d4cc 786 {
EasyCAT 0:543d6784d4cc 787 context->slavelist[slave].Obytes = (context->slavelist[slave].Obits + 7) / 8;
EasyCAT 0:543d6784d4cc 788 }
EasyCAT 0:543d6784d4cc 789
EasyCAT 0:543d6784d4cc 790 return 1;
EasyCAT 0:543d6784d4cc 791 }
EasyCAT 0:543d6784d4cc 792
EasyCAT 0:543d6784d4cc 793 #if EC_MAX_MAPT > 1
EasyCAT 0:543d6784d4cc 794 OSAL_THREAD_FUNC ecx_mapper_thread(void *param)
EasyCAT 0:543d6784d4cc 795 {
EasyCAT 0:543d6784d4cc 796 ecx_mapt_t *maptp;
EasyCAT 0:543d6784d4cc 797 maptp = param;
EasyCAT 0:543d6784d4cc 798 ecx_map_coe_soe(maptp->context, maptp->slave, maptp->thread_n);
EasyCAT 0:543d6784d4cc 799 maptp->running = 0;
EasyCAT 0:543d6784d4cc 800 }
EasyCAT 0:543d6784d4cc 801
EasyCAT 0:543d6784d4cc 802 static int ecx_find_mapt(void)
EasyCAT 0:543d6784d4cc 803 {
EasyCAT 0:543d6784d4cc 804 int p;
EasyCAT 0:543d6784d4cc 805 p = 0;
EasyCAT 0:543d6784d4cc 806 while((p < EC_MAX_MAPT) && ecx_mapt[p].running)
EasyCAT 0:543d6784d4cc 807 {
EasyCAT 0:543d6784d4cc 808 p++;
EasyCAT 0:543d6784d4cc 809 }
EasyCAT 0:543d6784d4cc 810 if(p < EC_MAX_MAPT)
EasyCAT 0:543d6784d4cc 811 {
EasyCAT 0:543d6784d4cc 812 return p;
EasyCAT 0:543d6784d4cc 813 }
EasyCAT 0:543d6784d4cc 814 else
EasyCAT 0:543d6784d4cc 815 {
EasyCAT 0:543d6784d4cc 816 return -1;
EasyCAT 0:543d6784d4cc 817 }
EasyCAT 0:543d6784d4cc 818 }
EasyCAT 0:543d6784d4cc 819 #endif
EasyCAT 0:543d6784d4cc 820
EasyCAT 0:543d6784d4cc 821 static int ecx_get_threadcount(void)
EasyCAT 0:543d6784d4cc 822 {
EasyCAT 0:543d6784d4cc 823 int thrc, thrn;
EasyCAT 0:543d6784d4cc 824 thrc = 0;
EasyCAT 0:543d6784d4cc 825 for(thrn = 0 ; thrn < EC_MAX_MAPT ; thrn++)
EasyCAT 0:543d6784d4cc 826 {
EasyCAT 0:543d6784d4cc 827 thrc += ecx_mapt[thrn].running;
EasyCAT 0:543d6784d4cc 828 }
EasyCAT 0:543d6784d4cc 829 return thrc;
EasyCAT 0:543d6784d4cc 830 }
EasyCAT 0:543d6784d4cc 831
EasyCAT 0:543d6784d4cc 832 static void ecx_config_find_mappings(ecx_contextt *context, uint8 group)
EasyCAT 0:543d6784d4cc 833 {
EasyCAT 0:543d6784d4cc 834 int thrn, thrc;
EasyCAT 0:543d6784d4cc 835 uint16 slave;
EasyCAT 0:543d6784d4cc 836
EasyCAT 0:543d6784d4cc 837 for (thrn = 0; thrn < EC_MAX_MAPT; thrn++)
EasyCAT 0:543d6784d4cc 838 {
EasyCAT 0:543d6784d4cc 839 ecx_mapt[thrn].running = 0;
EasyCAT 0:543d6784d4cc 840 }
EasyCAT 0:543d6784d4cc 841 /* find CoE and SoE mapping of slaves in multiple threads */
EasyCAT 0:543d6784d4cc 842 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 843 {
EasyCAT 0:543d6784d4cc 844 if (!group || (group == context->slavelist[slave].group))
EasyCAT 0:543d6784d4cc 845 {
EasyCAT 0:543d6784d4cc 846 #if EC_MAX_MAPT > 1
EasyCAT 0:543d6784d4cc 847 /* multi-threaded version */
EasyCAT 0:543d6784d4cc 848 while ((thrn = ecx_find_mapt()) < 0)
EasyCAT 0:543d6784d4cc 849 {
EasyCAT 0:543d6784d4cc 850 osal_usleep(1000);
EasyCAT 0:543d6784d4cc 851 }
EasyCAT 0:543d6784d4cc 852 ecx_mapt[thrn].context = context;
EasyCAT 0:543d6784d4cc 853 ecx_mapt[thrn].slave = slave;
EasyCAT 0:543d6784d4cc 854 ecx_mapt[thrn].thread_n = thrn;
EasyCAT 0:543d6784d4cc 855 ecx_mapt[thrn].running = 1;
EasyCAT 0:543d6784d4cc 856 osal_thread_create(&(ecx_threadh[thrn]), 128000,
EasyCAT 0:543d6784d4cc 857 &ecx_mapper_thread, &(ecx_mapt[thrn]));
EasyCAT 0:543d6784d4cc 858 #else
EasyCAT 0:543d6784d4cc 859 /* serialised version */
EasyCAT 0:543d6784d4cc 860 ecx_map_coe_soe(context, slave, 0);
EasyCAT 0:543d6784d4cc 861 #endif
EasyCAT 0:543d6784d4cc 862 }
EasyCAT 0:543d6784d4cc 863 }
EasyCAT 0:543d6784d4cc 864 /* wait for all threads to finish */
EasyCAT 0:543d6784d4cc 865 do
EasyCAT 0:543d6784d4cc 866 {
EasyCAT 0:543d6784d4cc 867 thrc = ecx_get_threadcount();
EasyCAT 0:543d6784d4cc 868 if (thrc)
EasyCAT 0:543d6784d4cc 869 {
EasyCAT 0:543d6784d4cc 870 osal_usleep(1000);
EasyCAT 0:543d6784d4cc 871 }
EasyCAT 0:543d6784d4cc 872 } while (thrc);
EasyCAT 0:543d6784d4cc 873 /* find SII mapping of slave and program SM */
EasyCAT 0:543d6784d4cc 874 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 875 {
EasyCAT 0:543d6784d4cc 876 if (!group || (group == context->slavelist[slave].group))
EasyCAT 0:543d6784d4cc 877 {
EasyCAT 0:543d6784d4cc 878 ecx_map_sii(context, slave);
EasyCAT 0:543d6784d4cc 879 ecx_map_sm(context, slave);
EasyCAT 0:543d6784d4cc 880 }
EasyCAT 0:543d6784d4cc 881 }
EasyCAT 0:543d6784d4cc 882 }
EasyCAT 0:543d6784d4cc 883
EasyCAT 0:543d6784d4cc 884 static void ecx_config_create_input_mappings(ecx_contextt *context, void *pIOmap,
EasyCAT 0:543d6784d4cc 885 uint8 group, int16 slave, uint32 * LogAddr, uint8 * BitPos)
EasyCAT 0:543d6784d4cc 886 {
EasyCAT 0:543d6784d4cc 887 int BitCount = 0;
EasyCAT 0:543d6784d4cc 888 int ByteCount = 0;
EasyCAT 0:543d6784d4cc 889 int FMMUsize = 0;
EasyCAT 0:543d6784d4cc 890 int FMMUdone = 0;
EasyCAT 0:543d6784d4cc 891 uint8 SMc = 0;
EasyCAT 0:543d6784d4cc 892 uint16 EndAddr;
EasyCAT 0:543d6784d4cc 893 uint16 SMlength;
EasyCAT 0:543d6784d4cc 894 uint16 configadr;
EasyCAT 0:543d6784d4cc 895 uint8 FMMUc;
EasyCAT 0:543d6784d4cc 896
EasyCAT 0:543d6784d4cc 897 EC_PRINT(" =Slave %d, INPUT MAPPING\n", slave);
EasyCAT 0:543d6784d4cc 898
EasyCAT 0:543d6784d4cc 899 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 900 FMMUc = context->slavelist[slave].FMMUunused;
EasyCAT 0:543d6784d4cc 901 if (context->slavelist[slave].Obits) /* find free FMMU */
EasyCAT 0:543d6784d4cc 902 {
EasyCAT 0:543d6784d4cc 903 while (context->slavelist[slave].FMMU[FMMUc].LogStart)
EasyCAT 0:543d6784d4cc 904 {
EasyCAT 0:543d6784d4cc 905 FMMUc++;
EasyCAT 0:543d6784d4cc 906 }
EasyCAT 0:543d6784d4cc 907 }
EasyCAT 0:543d6784d4cc 908 /* search for SM that contribute to the input mapping */
EasyCAT 0:543d6784d4cc 909 while ((SMc < (EC_MAXSM - 1)) && (FMMUdone < ((context->slavelist[slave].Ibits + 7) / 8)))
EasyCAT 0:543d6784d4cc 910 {
EasyCAT 0:543d6784d4cc 911 EC_PRINT(" FMMU %d\n", FMMUc);
EasyCAT 0:543d6784d4cc 912 while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 4))
EasyCAT 0:543d6784d4cc 913 {
EasyCAT 0:543d6784d4cc 914 SMc++;
EasyCAT 0:543d6784d4cc 915 }
EasyCAT 0:543d6784d4cc 916 EC_PRINT(" SM%d\n", SMc);
EasyCAT 0:543d6784d4cc 917 context->slavelist[slave].FMMU[FMMUc].PhysStart =
EasyCAT 0:543d6784d4cc 918 context->slavelist[slave].SM[SMc].StartAddr;
EasyCAT 0:543d6784d4cc 919 SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
EasyCAT 0:543d6784d4cc 920 ByteCount += SMlength;
EasyCAT 0:543d6784d4cc 921 BitCount += SMlength * 8;
EasyCAT 0:543d6784d4cc 922 EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
EasyCAT 0:543d6784d4cc 923 while ((BitCount < context->slavelist[slave].Ibits) && (SMc < (EC_MAXSM - 1))) /* more SM for input */
EasyCAT 0:543d6784d4cc 924 {
EasyCAT 0:543d6784d4cc 925 SMc++;
EasyCAT 0:543d6784d4cc 926 while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 4))
EasyCAT 0:543d6784d4cc 927 {
EasyCAT 0:543d6784d4cc 928 SMc++;
EasyCAT 0:543d6784d4cc 929 }
EasyCAT 0:543d6784d4cc 930 /* if addresses from more SM connect use one FMMU otherwise break up in multiple FMMU */
EasyCAT 0:543d6784d4cc 931 if (etohs(context->slavelist[slave].SM[SMc].StartAddr) > EndAddr)
EasyCAT 0:543d6784d4cc 932 {
EasyCAT 0:543d6784d4cc 933 break;
EasyCAT 0:543d6784d4cc 934 }
EasyCAT 0:543d6784d4cc 935 EC_PRINT(" SM%d\n", SMc);
EasyCAT 0:543d6784d4cc 936 SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
EasyCAT 0:543d6784d4cc 937 ByteCount += SMlength;
EasyCAT 0:543d6784d4cc 938 BitCount += SMlength * 8;
EasyCAT 0:543d6784d4cc 939 EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
EasyCAT 0:543d6784d4cc 940 }
EasyCAT 0:543d6784d4cc 941
EasyCAT 0:543d6784d4cc 942 /* bit oriented slave */
EasyCAT 0:543d6784d4cc 943 if (!context->slavelist[slave].Ibytes)
EasyCAT 0:543d6784d4cc 944 {
EasyCAT 0:543d6784d4cc 945 context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
EasyCAT 0:543d6784d4cc 946 context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
EasyCAT 0:543d6784d4cc 947 *BitPos += context->slavelist[slave].Ibits - 1;
EasyCAT 0:543d6784d4cc 948 if (*BitPos > 7)
EasyCAT 0:543d6784d4cc 949 {
EasyCAT 0:543d6784d4cc 950 *LogAddr += 1;
EasyCAT 0:543d6784d4cc 951 *BitPos -= 8;
EasyCAT 0:543d6784d4cc 952 }
EasyCAT 0:543d6784d4cc 953 FMMUsize = *LogAddr - etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) + 1;
EasyCAT 0:543d6784d4cc 954 context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
EasyCAT 0:543d6784d4cc 955 context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
EasyCAT 0:543d6784d4cc 956 *BitPos += 1;
EasyCAT 0:543d6784d4cc 957 if (*BitPos > 7)
EasyCAT 0:543d6784d4cc 958 {
EasyCAT 0:543d6784d4cc 959 *LogAddr += 1;
EasyCAT 0:543d6784d4cc 960 *BitPos -= 8;
EasyCAT 0:543d6784d4cc 961 }
EasyCAT 0:543d6784d4cc 962 }
EasyCAT 0:543d6784d4cc 963 /* byte oriented slave */
EasyCAT 0:543d6784d4cc 964 else
EasyCAT 0:543d6784d4cc 965 {
EasyCAT 0:543d6784d4cc 966 if (*BitPos)
EasyCAT 0:543d6784d4cc 967 {
EasyCAT 0:543d6784d4cc 968 *LogAddr += 1;
EasyCAT 0:543d6784d4cc 969 *BitPos = 0;
EasyCAT 0:543d6784d4cc 970 }
EasyCAT 0:543d6784d4cc 971 context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
EasyCAT 0:543d6784d4cc 972 context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
EasyCAT 0:543d6784d4cc 973 *BitPos = 7;
EasyCAT 0:543d6784d4cc 974 FMMUsize = ByteCount;
EasyCAT 0:543d6784d4cc 975 if ((FMMUsize + FMMUdone)> (int)context->slavelist[slave].Ibytes)
EasyCAT 0:543d6784d4cc 976 {
EasyCAT 0:543d6784d4cc 977 FMMUsize = context->slavelist[slave].Ibytes - FMMUdone;
EasyCAT 0:543d6784d4cc 978 }
EasyCAT 0:543d6784d4cc 979 *LogAddr += FMMUsize;
EasyCAT 0:543d6784d4cc 980 context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
EasyCAT 0:543d6784d4cc 981 context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
EasyCAT 0:543d6784d4cc 982 *BitPos = 0;
EasyCAT 0:543d6784d4cc 983 }
EasyCAT 0:543d6784d4cc 984 FMMUdone += FMMUsize;
EasyCAT 0:543d6784d4cc 985 if (context->slavelist[slave].FMMU[FMMUc].LogLength)
EasyCAT 0:543d6784d4cc 986 {
EasyCAT 0:543d6784d4cc 987 context->slavelist[slave].FMMU[FMMUc].PhysStartBit = 0;
EasyCAT 0:543d6784d4cc 988 context->slavelist[slave].FMMU[FMMUc].FMMUtype = 1;
EasyCAT 0:543d6784d4cc 989 context->slavelist[slave].FMMU[FMMUc].FMMUactive = 1;
EasyCAT 0:543d6784d4cc 990 /* program FMMU for input */
EasyCAT 0:543d6784d4cc 991 ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc),
EasyCAT 0:543d6784d4cc 992 sizeof(ec_fmmut), &(context->slavelist[slave].FMMU[FMMUc]), EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 993 /* add one for an input FMMU */
EasyCAT 0:543d6784d4cc 994 context->grouplist[group].inputsWKC++;
EasyCAT 0:543d6784d4cc 995 }
EasyCAT 0:543d6784d4cc 996 if (!context->slavelist[slave].inputs)
EasyCAT 0:543d6784d4cc 997 {
EasyCAT 0:543d6784d4cc 998 if (group)
EasyCAT 0:543d6784d4cc 999 {
EasyCAT 0:543d6784d4cc 1000 context->slavelist[slave].inputs =
EasyCAT 0:543d6784d4cc 1001 (uint8 *)(pIOmap) +
EasyCAT 0:543d6784d4cc 1002 etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) -
EasyCAT 0:543d6784d4cc 1003 context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1004 }
EasyCAT 0:543d6784d4cc 1005 else
EasyCAT 0:543d6784d4cc 1006 {
EasyCAT 0:543d6784d4cc 1007 context->slavelist[slave].inputs =
EasyCAT 0:543d6784d4cc 1008 (uint8 *)(pIOmap) +
EasyCAT 0:543d6784d4cc 1009 etohl(context->slavelist[slave].FMMU[FMMUc].LogStart);
EasyCAT 0:543d6784d4cc 1010 }
EasyCAT 0:543d6784d4cc 1011 context->slavelist[slave].Istartbit =
EasyCAT 0:543d6784d4cc 1012 context->slavelist[slave].FMMU[FMMUc].LogStartbit;
EasyCAT 0:543d6784d4cc 1013 EC_PRINT(" Inputs %p startbit %d\n",
EasyCAT 0:543d6784d4cc 1014 context->slavelist[slave].inputs,
EasyCAT 0:543d6784d4cc 1015 context->slavelist[slave].Istartbit);
EasyCAT 0:543d6784d4cc 1016 }
EasyCAT 0:543d6784d4cc 1017 FMMUc++;
EasyCAT 0:543d6784d4cc 1018 }
EasyCAT 0:543d6784d4cc 1019 context->slavelist[slave].FMMUunused = FMMUc;
EasyCAT 0:543d6784d4cc 1020 }
EasyCAT 0:543d6784d4cc 1021
EasyCAT 0:543d6784d4cc 1022 static void ecx_config_create_output_mappings(ecx_contextt *context, void *pIOmap,
EasyCAT 0:543d6784d4cc 1023 uint8 group, int16 slave, uint32 * LogAddr, uint8 * BitPos)
EasyCAT 0:543d6784d4cc 1024 {
EasyCAT 0:543d6784d4cc 1025 int BitCount = 0;
EasyCAT 0:543d6784d4cc 1026 int ByteCount = 0;
EasyCAT 0:543d6784d4cc 1027 int FMMUsize = 0;
EasyCAT 0:543d6784d4cc 1028 int FMMUdone = 0;
EasyCAT 0:543d6784d4cc 1029 uint8 SMc = 0;
EasyCAT 0:543d6784d4cc 1030 uint16 EndAddr;
EasyCAT 0:543d6784d4cc 1031 uint16 SMlength;
EasyCAT 0:543d6784d4cc 1032 uint16 configadr;
EasyCAT 0:543d6784d4cc 1033 uint8 FMMUc;
EasyCAT 0:543d6784d4cc 1034
EasyCAT 0:543d6784d4cc 1035 EC_PRINT(" OUTPUT MAPPING\n");
EasyCAT 0:543d6784d4cc 1036
EasyCAT 0:543d6784d4cc 1037 FMMUc = context->slavelist[slave].FMMUunused;
EasyCAT 0:543d6784d4cc 1038 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1039
EasyCAT 0:543d6784d4cc 1040 /* search for SM that contribute to the output mapping */
EasyCAT 0:543d6784d4cc 1041 while ((SMc < (EC_MAXSM - 1)) && (FMMUdone < ((context->slavelist[slave].Obits + 7) / 8)))
EasyCAT 0:543d6784d4cc 1042 {
EasyCAT 0:543d6784d4cc 1043 EC_PRINT(" FMMU %d\n", FMMUc);
EasyCAT 0:543d6784d4cc 1044 while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 3))
EasyCAT 0:543d6784d4cc 1045 {
EasyCAT 0:543d6784d4cc 1046 SMc++;
EasyCAT 0:543d6784d4cc 1047 }
EasyCAT 0:543d6784d4cc 1048 EC_PRINT(" SM%d\n", SMc);
EasyCAT 0:543d6784d4cc 1049 context->slavelist[slave].FMMU[FMMUc].PhysStart =
EasyCAT 0:543d6784d4cc 1050 context->slavelist[slave].SM[SMc].StartAddr;
EasyCAT 0:543d6784d4cc 1051 SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
EasyCAT 0:543d6784d4cc 1052 ByteCount += SMlength;
EasyCAT 0:543d6784d4cc 1053 BitCount += SMlength * 8;
EasyCAT 0:543d6784d4cc 1054 EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
EasyCAT 0:543d6784d4cc 1055 while ((BitCount < context->slavelist[slave].Obits) && (SMc < (EC_MAXSM - 1))) /* more SM for output */
EasyCAT 0:543d6784d4cc 1056 {
EasyCAT 0:543d6784d4cc 1057 SMc++;
EasyCAT 0:543d6784d4cc 1058 while ((SMc < (EC_MAXSM - 1)) && (context->slavelist[slave].SMtype[SMc] != 3))
EasyCAT 0:543d6784d4cc 1059 {
EasyCAT 0:543d6784d4cc 1060 SMc++;
EasyCAT 0:543d6784d4cc 1061 }
EasyCAT 0:543d6784d4cc 1062 /* if addresses from more SM connect use one FMMU otherwise break up in multiple FMMU */
EasyCAT 0:543d6784d4cc 1063 if (etohs(context->slavelist[slave].SM[SMc].StartAddr) > EndAddr)
EasyCAT 0:543d6784d4cc 1064 {
EasyCAT 0:543d6784d4cc 1065 break;
EasyCAT 0:543d6784d4cc 1066 }
EasyCAT 0:543d6784d4cc 1067 EC_PRINT(" SM%d\n", SMc);
EasyCAT 0:543d6784d4cc 1068 SMlength = etohs(context->slavelist[slave].SM[SMc].SMlength);
EasyCAT 0:543d6784d4cc 1069 ByteCount += SMlength;
EasyCAT 0:543d6784d4cc 1070 BitCount += SMlength * 8;
EasyCAT 0:543d6784d4cc 1071 EndAddr = etohs(context->slavelist[slave].SM[SMc].StartAddr) + SMlength;
EasyCAT 0:543d6784d4cc 1072 }
EasyCAT 0:543d6784d4cc 1073
EasyCAT 0:543d6784d4cc 1074 /* bit oriented slave */
EasyCAT 0:543d6784d4cc 1075 if (!context->slavelist[slave].Obytes)
EasyCAT 0:543d6784d4cc 1076 {
EasyCAT 0:543d6784d4cc 1077 context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
EasyCAT 0:543d6784d4cc 1078 context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
EasyCAT 0:543d6784d4cc 1079 *BitPos += context->slavelist[slave].Obits - 1;
EasyCAT 0:543d6784d4cc 1080 if (*BitPos > 7)
EasyCAT 0:543d6784d4cc 1081 {
EasyCAT 0:543d6784d4cc 1082 *LogAddr += 1;
EasyCAT 0:543d6784d4cc 1083 *BitPos -= 8;
EasyCAT 0:543d6784d4cc 1084 }
EasyCAT 0:543d6784d4cc 1085 FMMUsize = *LogAddr - etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) + 1;
EasyCAT 0:543d6784d4cc 1086 context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
EasyCAT 0:543d6784d4cc 1087 context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
EasyCAT 0:543d6784d4cc 1088 *BitPos += 1;
EasyCAT 0:543d6784d4cc 1089 if (*BitPos > 7)
EasyCAT 0:543d6784d4cc 1090 {
EasyCAT 0:543d6784d4cc 1091 *LogAddr += 1;
EasyCAT 0:543d6784d4cc 1092 *BitPos -= 8;
EasyCAT 0:543d6784d4cc 1093 }
EasyCAT 0:543d6784d4cc 1094 }
EasyCAT 0:543d6784d4cc 1095 /* byte oriented slave */
EasyCAT 0:543d6784d4cc 1096 else
EasyCAT 0:543d6784d4cc 1097 {
EasyCAT 0:543d6784d4cc 1098 if (*BitPos)
EasyCAT 0:543d6784d4cc 1099 {
EasyCAT 0:543d6784d4cc 1100 *LogAddr += 1;
EasyCAT 0:543d6784d4cc 1101 *BitPos = 0;
EasyCAT 0:543d6784d4cc 1102 }
EasyCAT 0:543d6784d4cc 1103 context->slavelist[slave].FMMU[FMMUc].LogStart = htoel(*LogAddr);
EasyCAT 0:543d6784d4cc 1104 context->slavelist[slave].FMMU[FMMUc].LogStartbit = *BitPos;
EasyCAT 0:543d6784d4cc 1105 *BitPos = 7;
EasyCAT 0:543d6784d4cc 1106 FMMUsize = ByteCount;
EasyCAT 0:543d6784d4cc 1107 if ((FMMUsize + FMMUdone)> (int)context->slavelist[slave].Obytes)
EasyCAT 0:543d6784d4cc 1108 {
EasyCAT 0:543d6784d4cc 1109 FMMUsize = context->slavelist[slave].Obytes - FMMUdone;
EasyCAT 0:543d6784d4cc 1110 }
EasyCAT 0:543d6784d4cc 1111 *LogAddr += FMMUsize;
EasyCAT 0:543d6784d4cc 1112 context->slavelist[slave].FMMU[FMMUc].LogLength = htoes(FMMUsize);
EasyCAT 0:543d6784d4cc 1113 context->slavelist[slave].FMMU[FMMUc].LogEndbit = *BitPos;
EasyCAT 0:543d6784d4cc 1114 *BitPos = 0;
EasyCAT 0:543d6784d4cc 1115 }
EasyCAT 0:543d6784d4cc 1116 FMMUdone += FMMUsize;
EasyCAT 0:543d6784d4cc 1117 context->slavelist[slave].FMMU[FMMUc].PhysStartBit = 0;
EasyCAT 0:543d6784d4cc 1118 context->slavelist[slave].FMMU[FMMUc].FMMUtype = 2;
EasyCAT 0:543d6784d4cc 1119 context->slavelist[slave].FMMU[FMMUc].FMMUactive = 1;
EasyCAT 0:543d6784d4cc 1120 /* program FMMU for output */
EasyCAT 0:543d6784d4cc 1121 ecx_FPWR(context->port, configadr, ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc),
EasyCAT 0:543d6784d4cc 1122 sizeof(ec_fmmut), &(context->slavelist[slave].FMMU[FMMUc]), EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 1123 context->grouplist[group].outputsWKC++;
EasyCAT 0:543d6784d4cc 1124 if (!context->slavelist[slave].outputs)
EasyCAT 0:543d6784d4cc 1125 {
EasyCAT 0:543d6784d4cc 1126 if (group)
EasyCAT 0:543d6784d4cc 1127 {
EasyCAT 0:543d6784d4cc 1128 context->slavelist[slave].outputs =
EasyCAT 0:543d6784d4cc 1129 (uint8 *)(pIOmap) +
EasyCAT 0:543d6784d4cc 1130 etohl(context->slavelist[slave].FMMU[FMMUc].LogStart) -
EasyCAT 0:543d6784d4cc 1131 context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1132 }
EasyCAT 0:543d6784d4cc 1133 else
EasyCAT 0:543d6784d4cc 1134 {
EasyCAT 0:543d6784d4cc 1135 context->slavelist[slave].outputs =
EasyCAT 0:543d6784d4cc 1136 (uint8 *)(pIOmap) +
EasyCAT 0:543d6784d4cc 1137 etohl(context->slavelist[slave].FMMU[FMMUc].LogStart);
EasyCAT 0:543d6784d4cc 1138 }
EasyCAT 0:543d6784d4cc 1139 context->slavelist[slave].Ostartbit =
EasyCAT 0:543d6784d4cc 1140 context->slavelist[slave].FMMU[FMMUc].LogStartbit;
EasyCAT 0:543d6784d4cc 1141 EC_PRINT(" slave %d Outputs %p startbit %d\n",
EasyCAT 0:543d6784d4cc 1142 slave,
EasyCAT 0:543d6784d4cc 1143 context->slavelist[slave].outputs,
EasyCAT 0:543d6784d4cc 1144 context->slavelist[slave].Ostartbit);
EasyCAT 0:543d6784d4cc 1145 }
EasyCAT 0:543d6784d4cc 1146 FMMUc++;
EasyCAT 0:543d6784d4cc 1147 }
EasyCAT 0:543d6784d4cc 1148 context->slavelist[slave].FMMUunused = FMMUc;
EasyCAT 0:543d6784d4cc 1149 }
EasyCAT 0:543d6784d4cc 1150
EasyCAT 0:543d6784d4cc 1151 /** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
EasyCAT 0:543d6784d4cc 1152 * in sequential order (legacy SOEM way).
EasyCAT 0:543d6784d4cc 1153 *
EasyCAT 0:543d6784d4cc 1154 *
EasyCAT 0:543d6784d4cc 1155 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1156 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1157 * @param[in] group = group to map, 0 = all groups
EasyCAT 0:543d6784d4cc 1158 * @return IOmap size
EasyCAT 0:543d6784d4cc 1159 */
EasyCAT 0:543d6784d4cc 1160 int ecx_config_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
EasyCAT 0:543d6784d4cc 1161 {
EasyCAT 0:543d6784d4cc 1162 uint16 slave, configadr;
EasyCAT 0:543d6784d4cc 1163 uint8 BitPos;
EasyCAT 0:543d6784d4cc 1164 uint32 LogAddr = 0;
EasyCAT 0:543d6784d4cc 1165 uint32 oLogAddr = 0;
EasyCAT 0:543d6784d4cc 1166 uint32 diff;
EasyCAT 0:543d6784d4cc 1167 uint16 currentsegment = 0;
EasyCAT 0:543d6784d4cc 1168 uint32 segmentsize = 0;
EasyCAT 0:543d6784d4cc 1169
EasyCAT 0:543d6784d4cc 1170 if ((*(context->slavecount) > 0) && (group < context->maxgroup))
EasyCAT 0:543d6784d4cc 1171 {
EasyCAT 0:543d6784d4cc 1172 EC_PRINT("ec_config_map_group IOmap:%p group:%d\n", pIOmap, group);
EasyCAT 0:543d6784d4cc 1173 LogAddr = context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1174 oLogAddr = LogAddr;
EasyCAT 0:543d6784d4cc 1175 BitPos = 0;
EasyCAT 0:543d6784d4cc 1176 context->grouplist[group].nsegments = 0;
EasyCAT 0:543d6784d4cc 1177 context->grouplist[group].outputsWKC = 0;
EasyCAT 0:543d6784d4cc 1178 context->grouplist[group].inputsWKC = 0;
EasyCAT 0:543d6784d4cc 1179
EasyCAT 0:543d6784d4cc 1180 /* Find mappings and program syncmanagers */
EasyCAT 0:543d6784d4cc 1181 ecx_config_find_mappings(context, group);
EasyCAT 0:543d6784d4cc 1182
EasyCAT 0:543d6784d4cc 1183 /* do output mapping of slave and program FMMUs */
EasyCAT 0:543d6784d4cc 1184 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 1185 {
EasyCAT 0:543d6784d4cc 1186 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1187
EasyCAT 0:543d6784d4cc 1188 if (!group || (group == context->slavelist[slave].group))
EasyCAT 0:543d6784d4cc 1189 {
EasyCAT 0:543d6784d4cc 1190 /* create output mapping */
EasyCAT 0:543d6784d4cc 1191 if (context->slavelist[slave].Obits)
EasyCAT 0:543d6784d4cc 1192 {
EasyCAT 0:543d6784d4cc 1193 ecx_config_create_output_mappings (context, pIOmap, group, slave, &LogAddr, &BitPos);
EasyCAT 0:543d6784d4cc 1194 diff = LogAddr - oLogAddr;
EasyCAT 0:543d6784d4cc 1195 oLogAddr = LogAddr;
EasyCAT 0:543d6784d4cc 1196 if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
EasyCAT 0:543d6784d4cc 1197 {
EasyCAT 0:543d6784d4cc 1198 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1199 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
EasyCAT 0:543d6784d4cc 1200 {
EasyCAT 0:543d6784d4cc 1201 currentsegment++;
EasyCAT 0:543d6784d4cc 1202 segmentsize = diff;
EasyCAT 0:543d6784d4cc 1203 }
EasyCAT 0:543d6784d4cc 1204 }
EasyCAT 0:543d6784d4cc 1205 else
EasyCAT 0:543d6784d4cc 1206 {
EasyCAT 0:543d6784d4cc 1207 segmentsize += diff;
EasyCAT 0:543d6784d4cc 1208 }
EasyCAT 0:543d6784d4cc 1209 }
EasyCAT 0:543d6784d4cc 1210 }
EasyCAT 0:543d6784d4cc 1211 }
EasyCAT 0:543d6784d4cc 1212 if (BitPos)
EasyCAT 0:543d6784d4cc 1213 {
EasyCAT 0:543d6784d4cc 1214 LogAddr++;
EasyCAT 0:543d6784d4cc 1215 oLogAddr = LogAddr;
EasyCAT 0:543d6784d4cc 1216 BitPos = 0;
EasyCAT 0:543d6784d4cc 1217 if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
EasyCAT 0:543d6784d4cc 1218 {
EasyCAT 0:543d6784d4cc 1219 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1220 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
EasyCAT 0:543d6784d4cc 1221 {
EasyCAT 0:543d6784d4cc 1222 currentsegment++;
EasyCAT 0:543d6784d4cc 1223 segmentsize = 1;
EasyCAT 0:543d6784d4cc 1224 }
EasyCAT 0:543d6784d4cc 1225 }
EasyCAT 0:543d6784d4cc 1226 else
EasyCAT 0:543d6784d4cc 1227 {
EasyCAT 0:543d6784d4cc 1228 segmentsize += 1;
EasyCAT 0:543d6784d4cc 1229 }
EasyCAT 0:543d6784d4cc 1230 }
EasyCAT 0:543d6784d4cc 1231 context->grouplist[group].outputs = pIOmap;
EasyCAT 0:543d6784d4cc 1232 context->grouplist[group].Obytes = LogAddr - context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1233 context->grouplist[group].nsegments = currentsegment + 1;
EasyCAT 0:543d6784d4cc 1234 context->grouplist[group].Isegment = currentsegment;
EasyCAT 0:543d6784d4cc 1235 context->grouplist[group].Ioffset = segmentsize;
EasyCAT 0:543d6784d4cc 1236 if (!group)
EasyCAT 0:543d6784d4cc 1237 {
EasyCAT 0:543d6784d4cc 1238 context->slavelist[0].outputs = pIOmap;
EasyCAT 0:543d6784d4cc 1239 context->slavelist[0].Obytes = LogAddr -
EasyCAT 0:543d6784d4cc 1240 context->grouplist[group].logstartaddr; /* store output bytes in master record */
EasyCAT 0:543d6784d4cc 1241 }
EasyCAT 0:543d6784d4cc 1242
EasyCAT 0:543d6784d4cc 1243 /* do input mapping of slave and program FMMUs */
EasyCAT 0:543d6784d4cc 1244 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 1245 {
EasyCAT 0:543d6784d4cc 1246 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1247 if (!group || (group == context->slavelist[slave].group))
EasyCAT 0:543d6784d4cc 1248 {
EasyCAT 0:543d6784d4cc 1249 /* create input mapping */
EasyCAT 0:543d6784d4cc 1250 if (context->slavelist[slave].Ibits)
EasyCAT 0:543d6784d4cc 1251 {
EasyCAT 0:543d6784d4cc 1252
EasyCAT 0:543d6784d4cc 1253 ecx_config_create_input_mappings(context, pIOmap, group, slave, &LogAddr, &BitPos);
EasyCAT 0:543d6784d4cc 1254 diff = LogAddr - oLogAddr;
EasyCAT 0:543d6784d4cc 1255 oLogAddr = LogAddr;
EasyCAT 0:543d6784d4cc 1256 if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
EasyCAT 0:543d6784d4cc 1257 {
EasyCAT 0:543d6784d4cc 1258 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1259 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
EasyCAT 0:543d6784d4cc 1260 {
EasyCAT 0:543d6784d4cc 1261 currentsegment++;
EasyCAT 0:543d6784d4cc 1262 segmentsize = diff;
EasyCAT 0:543d6784d4cc 1263 }
EasyCAT 0:543d6784d4cc 1264 }
EasyCAT 0:543d6784d4cc 1265 else
EasyCAT 0:543d6784d4cc 1266 {
EasyCAT 0:543d6784d4cc 1267 segmentsize += diff;
EasyCAT 0:543d6784d4cc 1268 }
EasyCAT 0:543d6784d4cc 1269 }
EasyCAT 0:543d6784d4cc 1270
EasyCAT 0:543d6784d4cc 1271 ecx_eeprom2pdi(context, slave); /* set Eeprom control to PDI */
EasyCAT 0:543d6784d4cc 1272 ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , EC_TIMEOUTRET3); /* set safeop status */
EasyCAT 0:543d6784d4cc 1273
EasyCAT 0:543d6784d4cc 1274 if (context->slavelist[slave].blockLRW)
EasyCAT 0:543d6784d4cc 1275 {
EasyCAT 0:543d6784d4cc 1276 context->grouplist[group].blockLRW++;
EasyCAT 0:543d6784d4cc 1277 }
EasyCAT 0:543d6784d4cc 1278 context->grouplist[group].Ebuscurrent += context->slavelist[slave].Ebuscurrent;
EasyCAT 0:543d6784d4cc 1279 }
EasyCAT 0:543d6784d4cc 1280 }
EasyCAT 0:543d6784d4cc 1281 if (BitPos)
EasyCAT 0:543d6784d4cc 1282 {
EasyCAT 0:543d6784d4cc 1283 LogAddr++;
EasyCAT 0:543d6784d4cc 1284 oLogAddr = LogAddr;
EasyCAT 0:543d6784d4cc 1285 BitPos = 0;
EasyCAT 0:543d6784d4cc 1286 if ((segmentsize + 1) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
EasyCAT 0:543d6784d4cc 1287 {
EasyCAT 0:543d6784d4cc 1288 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1289 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
EasyCAT 0:543d6784d4cc 1290 {
EasyCAT 0:543d6784d4cc 1291 currentsegment++;
EasyCAT 0:543d6784d4cc 1292 segmentsize = 1;
EasyCAT 0:543d6784d4cc 1293 }
EasyCAT 0:543d6784d4cc 1294 }
EasyCAT 0:543d6784d4cc 1295 else
EasyCAT 0:543d6784d4cc 1296 {
EasyCAT 0:543d6784d4cc 1297 segmentsize += 1;
EasyCAT 0:543d6784d4cc 1298 }
EasyCAT 0:543d6784d4cc 1299 }
EasyCAT 0:543d6784d4cc 1300 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1301 context->grouplist[group].nsegments = currentsegment + 1;
EasyCAT 0:543d6784d4cc 1302 context->grouplist[group].inputs = (uint8 *)(pIOmap) + context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1303 context->grouplist[group].Ibytes = LogAddr -
EasyCAT 0:543d6784d4cc 1304 context->grouplist[group].logstartaddr -
EasyCAT 0:543d6784d4cc 1305 context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1306 if (!group)
EasyCAT 0:543d6784d4cc 1307 {
EasyCAT 0:543d6784d4cc 1308 context->slavelist[0].inputs = (uint8 *)(pIOmap) + context->slavelist[0].Obytes;
EasyCAT 0:543d6784d4cc 1309 context->slavelist[0].Ibytes = LogAddr -
EasyCAT 0:543d6784d4cc 1310 context->grouplist[group].logstartaddr -
EasyCAT 0:543d6784d4cc 1311 context->slavelist[0].Obytes; /* store input bytes in master record */
EasyCAT 0:543d6784d4cc 1312 }
EasyCAT 0:543d6784d4cc 1313
EasyCAT 0:543d6784d4cc 1314 EC_PRINT("IOmapSize %d\n", LogAddr - context->grouplist[group].logstartaddr);
EasyCAT 0:543d6784d4cc 1315
EasyCAT 0:543d6784d4cc 1316 return (LogAddr - context->grouplist[group].logstartaddr);
EasyCAT 0:543d6784d4cc 1317 }
EasyCAT 0:543d6784d4cc 1318
EasyCAT 0:543d6784d4cc 1319 return 0;
EasyCAT 0:543d6784d4cc 1320 }
EasyCAT 0:543d6784d4cc 1321
EasyCAT 0:543d6784d4cc 1322 /** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
EasyCAT 0:543d6784d4cc 1323 * overlapping. NOTE: Must use this for TI ESC when using LRW.
EasyCAT 0:543d6784d4cc 1324 *
EasyCAT 0:543d6784d4cc 1325 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1326 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1327 * @param[in] group = group to map, 0 = all groups
EasyCAT 0:543d6784d4cc 1328 * @return IOmap size
EasyCAT 0:543d6784d4cc 1329 */
EasyCAT 0:543d6784d4cc 1330 int ecx_config_overlap_map_group(ecx_contextt *context, void *pIOmap, uint8 group)
EasyCAT 0:543d6784d4cc 1331 {
EasyCAT 0:543d6784d4cc 1332 uint16 slave, configadr;
EasyCAT 0:543d6784d4cc 1333 uint8 BitPos;
EasyCAT 0:543d6784d4cc 1334 uint32 mLogAddr = 0;
EasyCAT 0:543d6784d4cc 1335 uint32 siLogAddr = 0;
EasyCAT 0:543d6784d4cc 1336 uint32 soLogAddr = 0;
EasyCAT 0:543d6784d4cc 1337 uint32 tempLogAddr;
EasyCAT 0:543d6784d4cc 1338 uint32 diff;
EasyCAT 0:543d6784d4cc 1339 uint16 currentsegment = 0;
EasyCAT 0:543d6784d4cc 1340 uint32 segmentsize = 0;
EasyCAT 0:543d6784d4cc 1341
EasyCAT 0:543d6784d4cc 1342 if ((*(context->slavecount) > 0) && (group < context->maxgroup))
EasyCAT 0:543d6784d4cc 1343 {
EasyCAT 0:543d6784d4cc 1344 EC_PRINT("ec_config_map_group IOmap:%p group:%d\n", pIOmap, group);
EasyCAT 0:543d6784d4cc 1345 mLogAddr = context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1346 siLogAddr = mLogAddr;
EasyCAT 0:543d6784d4cc 1347 soLogAddr = mLogAddr;
EasyCAT 0:543d6784d4cc 1348 BitPos = 0;
EasyCAT 0:543d6784d4cc 1349 context->grouplist[group].nsegments = 0;
EasyCAT 0:543d6784d4cc 1350 context->grouplist[group].outputsWKC = 0;
EasyCAT 0:543d6784d4cc 1351 context->grouplist[group].inputsWKC = 0;
EasyCAT 0:543d6784d4cc 1352
EasyCAT 0:543d6784d4cc 1353 /* Find mappings and program syncmanagers */
EasyCAT 0:543d6784d4cc 1354 ecx_config_find_mappings(context, group);
EasyCAT 0:543d6784d4cc 1355
EasyCAT 0:543d6784d4cc 1356 /* do IO mapping of slave and program FMMUs */
EasyCAT 0:543d6784d4cc 1357 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 1358 {
EasyCAT 0:543d6784d4cc 1359 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1360 siLogAddr = soLogAddr = mLogAddr;
EasyCAT 0:543d6784d4cc 1361
EasyCAT 0:543d6784d4cc 1362 if (!group || (group == context->slavelist[slave].group))
EasyCAT 0:543d6784d4cc 1363 {
EasyCAT 0:543d6784d4cc 1364 /* create output mapping */
EasyCAT 0:543d6784d4cc 1365 if (context->slavelist[slave].Obits)
EasyCAT 0:543d6784d4cc 1366 {
EasyCAT 0:543d6784d4cc 1367
EasyCAT 0:543d6784d4cc 1368 ecx_config_create_output_mappings(context, pIOmap, group,
EasyCAT 0:543d6784d4cc 1369 slave, &soLogAddr, &BitPos);
EasyCAT 0:543d6784d4cc 1370 if (BitPos)
EasyCAT 0:543d6784d4cc 1371 {
EasyCAT 0:543d6784d4cc 1372 soLogAddr++;
EasyCAT 0:543d6784d4cc 1373 BitPos = 0;
EasyCAT 0:543d6784d4cc 1374 }
EasyCAT 0:543d6784d4cc 1375 }
EasyCAT 0:543d6784d4cc 1376
EasyCAT 0:543d6784d4cc 1377 /* create input mapping */
EasyCAT 0:543d6784d4cc 1378 if (context->slavelist[slave].Ibits)
EasyCAT 0:543d6784d4cc 1379 {
EasyCAT 0:543d6784d4cc 1380 ecx_config_create_input_mappings(context, pIOmap, group,
EasyCAT 0:543d6784d4cc 1381 slave, &siLogAddr, &BitPos);
EasyCAT 0:543d6784d4cc 1382 if (BitPos)
EasyCAT 0:543d6784d4cc 1383 {
EasyCAT 0:543d6784d4cc 1384 siLogAddr++;
EasyCAT 0:543d6784d4cc 1385 BitPos = 0;
EasyCAT 0:543d6784d4cc 1386 }
EasyCAT 0:543d6784d4cc 1387 }
EasyCAT 0:543d6784d4cc 1388
EasyCAT 0:543d6784d4cc 1389 tempLogAddr = (siLogAddr > soLogAddr) ? siLogAddr : soLogAddr;
EasyCAT 0:543d6784d4cc 1390 diff = tempLogAddr - mLogAddr;
EasyCAT 0:543d6784d4cc 1391 mLogAddr = tempLogAddr;
EasyCAT 0:543d6784d4cc 1392
EasyCAT 0:543d6784d4cc 1393 if ((segmentsize + diff) > (EC_MAXLRWDATA - EC_FIRSTDCDATAGRAM))
EasyCAT 0:543d6784d4cc 1394 {
EasyCAT 0:543d6784d4cc 1395 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1396 if (currentsegment < (EC_MAXIOSEGMENTS - 1))
EasyCAT 0:543d6784d4cc 1397 {
EasyCAT 0:543d6784d4cc 1398 currentsegment++;
EasyCAT 0:543d6784d4cc 1399 segmentsize = diff;
EasyCAT 0:543d6784d4cc 1400 }
EasyCAT 0:543d6784d4cc 1401 }
EasyCAT 0:543d6784d4cc 1402 else
EasyCAT 0:543d6784d4cc 1403 {
EasyCAT 0:543d6784d4cc 1404 segmentsize += diff;
EasyCAT 0:543d6784d4cc 1405 }
EasyCAT 0:543d6784d4cc 1406
EasyCAT 0:543d6784d4cc 1407 ecx_eeprom2pdi(context, slave); /* set Eeprom control to PDI */
EasyCAT 0:543d6784d4cc 1408 ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP), EC_TIMEOUTRET3); /* set safeop status */
EasyCAT 0:543d6784d4cc 1409
EasyCAT 0:543d6784d4cc 1410 if (context->slavelist[slave].blockLRW)
EasyCAT 0:543d6784d4cc 1411 {
EasyCAT 0:543d6784d4cc 1412 context->grouplist[group].blockLRW++;
EasyCAT 0:543d6784d4cc 1413 }
EasyCAT 0:543d6784d4cc 1414 context->grouplist[group].Ebuscurrent += context->slavelist[slave].Ebuscurrent;
EasyCAT 0:543d6784d4cc 1415
EasyCAT 0:543d6784d4cc 1416 }
EasyCAT 0:543d6784d4cc 1417 }
EasyCAT 0:543d6784d4cc 1418
EasyCAT 0:543d6784d4cc 1419 context->grouplist[group].IOsegment[currentsegment] = segmentsize;
EasyCAT 0:543d6784d4cc 1420 context->grouplist[group].nsegments = currentsegment + 1;
EasyCAT 0:543d6784d4cc 1421 context->grouplist[group].Isegment = 0;
EasyCAT 0:543d6784d4cc 1422 context->grouplist[group].Ioffset = 0;
EasyCAT 0:543d6784d4cc 1423
EasyCAT 0:543d6784d4cc 1424 context->grouplist[group].Obytes = soLogAddr - context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1425 context->grouplist[group].Ibytes = siLogAddr - context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1426 context->grouplist[group].outputs = pIOmap;
EasyCAT 0:543d6784d4cc 1427 context->grouplist[group].inputs = (uint8 *)pIOmap + context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1428
EasyCAT 0:543d6784d4cc 1429 /* Move calculated inputs with OBytes offset*/
EasyCAT 0:543d6784d4cc 1430 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 1431 {
EasyCAT 0:543d6784d4cc 1432 context->slavelist[slave].inputs += context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1433 }
EasyCAT 0:543d6784d4cc 1434
EasyCAT 0:543d6784d4cc 1435 if (!group)
EasyCAT 0:543d6784d4cc 1436 {
EasyCAT 0:543d6784d4cc 1437 /* store output bytes in master record */
EasyCAT 0:543d6784d4cc 1438 context->slavelist[0].outputs = pIOmap;
EasyCAT 0:543d6784d4cc 1439 context->slavelist[0].Obytes = soLogAddr - context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1440 context->slavelist[0].inputs = (uint8 *)pIOmap + context->slavelist[0].Obytes;
EasyCAT 0:543d6784d4cc 1441 context->slavelist[0].Ibytes = siLogAddr - context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1442 }
EasyCAT 0:543d6784d4cc 1443
EasyCAT 0:543d6784d4cc 1444 EC_PRINT("IOmapSize %d\n", context->grouplist[group].Obytes + context->grouplist[group].Ibytes);
EasyCAT 0:543d6784d4cc 1445
EasyCAT 0:543d6784d4cc 1446 return (context->grouplist[group].Obytes + context->grouplist[group].Ibytes);
EasyCAT 0:543d6784d4cc 1447 }
EasyCAT 0:543d6784d4cc 1448
EasyCAT 0:543d6784d4cc 1449 return 0;
EasyCAT 0:543d6784d4cc 1450 }
EasyCAT 0:543d6784d4cc 1451
EasyCAT 0:543d6784d4cc 1452
EasyCAT 0:543d6784d4cc 1453 /** Recover slave.
EasyCAT 0:543d6784d4cc 1454 *
EasyCAT 0:543d6784d4cc 1455 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1456 * @param[in] slave = slave to recover
EasyCAT 0:543d6784d4cc 1457 * @param[in] timeout = local timeout f.e. EC_TIMEOUTRET3
EasyCAT 0:543d6784d4cc 1458 * @return >0 if successful
EasyCAT 0:543d6784d4cc 1459 */
EasyCAT 0:543d6784d4cc 1460 int ecx_recover_slave(ecx_contextt *context, uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 1461 {
EasyCAT 0:543d6784d4cc 1462 int rval;
EasyCAT 0:543d6784d4cc 1463 int wkc;
EasyCAT 0:543d6784d4cc 1464 uint16 ADPh, configadr, readadr;
EasyCAT 0:543d6784d4cc 1465
EasyCAT 0:543d6784d4cc 1466 rval = 0;
EasyCAT 0:543d6784d4cc 1467 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1468 ADPh = (uint16)(1 - slave);
EasyCAT 0:543d6784d4cc 1469 /* check if we found another slave than the requested */
EasyCAT 0:543d6784d4cc 1470 readadr = 0xfffe;
EasyCAT 0:543d6784d4cc 1471 wkc = ecx_APRD(context->port, ADPh, ECT_REG_STADR, sizeof(readadr), &readadr, timeout);
EasyCAT 0:543d6784d4cc 1472 /* correct slave found, finished */
EasyCAT 0:543d6784d4cc 1473 if(readadr == configadr)
EasyCAT 0:543d6784d4cc 1474 {
EasyCAT 0:543d6784d4cc 1475 return 1;
EasyCAT 0:543d6784d4cc 1476 }
EasyCAT 0:543d6784d4cc 1477 /* only try if no config address*/
EasyCAT 0:543d6784d4cc 1478 if( (wkc > 0) && (readadr == 0))
EasyCAT 0:543d6784d4cc 1479 {
EasyCAT 0:543d6784d4cc 1480 /* clear possible slaves at EC_TEMPNODE */
EasyCAT 0:543d6784d4cc 1481 ecx_FPWRw(context->port, EC_TEMPNODE, ECT_REG_STADR, htoes(0) , 0);
EasyCAT 0:543d6784d4cc 1482 /* set temporary node address of slave */
EasyCAT 0:543d6784d4cc 1483 if(ecx_APWRw(context->port, ADPh, ECT_REG_STADR, htoes(EC_TEMPNODE) , timeout) <= 0)
EasyCAT 0:543d6784d4cc 1484 {
EasyCAT 0:543d6784d4cc 1485 ecx_FPWRw(context->port, EC_TEMPNODE, ECT_REG_STADR, htoes(0) , 0);
EasyCAT 0:543d6784d4cc 1486 return 0; /* slave fails to respond */
EasyCAT 0:543d6784d4cc 1487 }
EasyCAT 0:543d6784d4cc 1488
EasyCAT 0:543d6784d4cc 1489 context->slavelist[slave].configadr = EC_TEMPNODE; /* temporary config address */
EasyCAT 0:543d6784d4cc 1490 ecx_eeprom2master(context, slave); /* set Eeprom control to master */
EasyCAT 0:543d6784d4cc 1491
EasyCAT 0:543d6784d4cc 1492 /* check if slave is the same as configured before */
EasyCAT 0:543d6784d4cc 1493 if ((ecx_FPRDw(context->port, EC_TEMPNODE, ECT_REG_ALIAS, timeout) ==
EasyCAT 0:543d6784d4cc 1494 htoes(context->slavelist[slave].aliasadr)) &&
EasyCAT 0:543d6784d4cc 1495 (ecx_readeeprom(context, slave, ECT_SII_ID, EC_TIMEOUTEEP) ==
EasyCAT 0:543d6784d4cc 1496 htoel(context->slavelist[slave].eep_id)) &&
EasyCAT 0:543d6784d4cc 1497 (ecx_readeeprom(context, slave, ECT_SII_MANUF, EC_TIMEOUTEEP) ==
EasyCAT 0:543d6784d4cc 1498 htoel(context->slavelist[slave].eep_man)) &&
EasyCAT 0:543d6784d4cc 1499 (ecx_readeeprom(context, slave, ECT_SII_REV, EC_TIMEOUTEEP) ==
EasyCAT 0:543d6784d4cc 1500 htoel(context->slavelist[slave].eep_rev)))
EasyCAT 0:543d6784d4cc 1501 {
EasyCAT 0:543d6784d4cc 1502 rval = ecx_FPWRw(context->port, EC_TEMPNODE, ECT_REG_STADR, htoes(configadr) , timeout);
EasyCAT 0:543d6784d4cc 1503 context->slavelist[slave].configadr = configadr;
EasyCAT 0:543d6784d4cc 1504 }
EasyCAT 0:543d6784d4cc 1505 else
EasyCAT 0:543d6784d4cc 1506 {
EasyCAT 0:543d6784d4cc 1507 /* slave is not the expected one, remove config address*/
EasyCAT 0:543d6784d4cc 1508 ecx_FPWRw(context->port, EC_TEMPNODE, ECT_REG_STADR, htoes(0) , timeout);
EasyCAT 0:543d6784d4cc 1509 context->slavelist[slave].configadr = configadr;
EasyCAT 0:543d6784d4cc 1510 }
EasyCAT 0:543d6784d4cc 1511 }
EasyCAT 0:543d6784d4cc 1512
EasyCAT 0:543d6784d4cc 1513 return rval;
EasyCAT 0:543d6784d4cc 1514 }
EasyCAT 0:543d6784d4cc 1515
EasyCAT 0:543d6784d4cc 1516 /** Reconfigure slave.
EasyCAT 0:543d6784d4cc 1517 *
EasyCAT 0:543d6784d4cc 1518 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1519 * @param[in] slave = slave to reconfigure
EasyCAT 0:543d6784d4cc 1520 * @param[in] timeout = local timeout f.e. EC_TIMEOUTRET3
EasyCAT 0:543d6784d4cc 1521 * @return Slave state
EasyCAT 0:543d6784d4cc 1522 */
EasyCAT 0:543d6784d4cc 1523 int ecx_reconfig_slave(ecx_contextt *context, uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 1524 {
EasyCAT 0:543d6784d4cc 1525 int state, nSM, FMMUc;
EasyCAT 0:543d6784d4cc 1526 uint16 configadr;
EasyCAT 0:543d6784d4cc 1527
EasyCAT 0:543d6784d4cc 1528 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1529 if (ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_INIT) , timeout) <= 0)
EasyCAT 0:543d6784d4cc 1530 {
EasyCAT 0:543d6784d4cc 1531 return 0;
EasyCAT 0:543d6784d4cc 1532 }
EasyCAT 0:543d6784d4cc 1533 state = 0;
EasyCAT 0:543d6784d4cc 1534 ecx_eeprom2pdi(context, slave); /* set Eeprom control to PDI */
EasyCAT 0:543d6784d4cc 1535 /* check state change init */
EasyCAT 0:543d6784d4cc 1536 state = ecx_statecheck(context, slave, EC_STATE_INIT, EC_TIMEOUTSTATE);
EasyCAT 0:543d6784d4cc 1537 if(state == EC_STATE_INIT)
EasyCAT 0:543d6784d4cc 1538 {
EasyCAT 0:543d6784d4cc 1539 /* program all enabled SM */
EasyCAT 0:543d6784d4cc 1540 for( nSM = 0 ; nSM < EC_MAXSM ; nSM++ )
EasyCAT 0:543d6784d4cc 1541 {
EasyCAT 0:543d6784d4cc 1542 if (context->slavelist[slave].SM[nSM].StartAddr)
EasyCAT 0:543d6784d4cc 1543 {
EasyCAT 0:543d6784d4cc 1544 ecx_FPWR(context->port, configadr, (uint16)(ECT_REG_SM0 + (nSM * sizeof(ec_smt))),
EasyCAT 0:543d6784d4cc 1545 sizeof(ec_smt), &context->slavelist[slave].SM[nSM], timeout);
EasyCAT 0:543d6784d4cc 1546 }
EasyCAT 0:543d6784d4cc 1547 }
EasyCAT 0:543d6784d4cc 1548 ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_PRE_OP) , timeout);
EasyCAT 0:543d6784d4cc 1549 state = ecx_statecheck(context, slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */
EasyCAT 0:543d6784d4cc 1550 if( state == EC_STATE_PRE_OP)
EasyCAT 0:543d6784d4cc 1551 {
EasyCAT 0:543d6784d4cc 1552 /* execute special slave configuration hook Pre-Op to Safe-OP */
EasyCAT 0:543d6784d4cc 1553 if(context->slavelist[slave].PO2SOconfig) /* only if registered */
EasyCAT 0:543d6784d4cc 1554 {
EasyCAT 0:543d6784d4cc 1555 context->slavelist[slave].PO2SOconfig(slave);
EasyCAT 0:543d6784d4cc 1556 }
EasyCAT 0:543d6784d4cc 1557 ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL, htoes(EC_STATE_SAFE_OP) , timeout); /* set safeop status */
EasyCAT 0:543d6784d4cc 1558 state = ecx_statecheck(context, slave, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE); /* check state change safe-op */
EasyCAT 0:543d6784d4cc 1559 /* program configured FMMU */
EasyCAT 0:543d6784d4cc 1560 for( FMMUc = 0 ; FMMUc < context->slavelist[slave].FMMUunused ; FMMUc++ )
EasyCAT 0:543d6784d4cc 1561 {
EasyCAT 0:543d6784d4cc 1562 ecx_FPWR(context->port, configadr, (uint16)(ECT_REG_FMMU0 + (sizeof(ec_fmmut) * FMMUc)),
EasyCAT 0:543d6784d4cc 1563 sizeof(ec_fmmut), &context->slavelist[slave].FMMU[FMMUc], timeout);
EasyCAT 0:543d6784d4cc 1564 }
EasyCAT 0:543d6784d4cc 1565 }
EasyCAT 0:543d6784d4cc 1566 }
EasyCAT 0:543d6784d4cc 1567
EasyCAT 0:543d6784d4cc 1568 return state;
EasyCAT 0:543d6784d4cc 1569 }
EasyCAT 0:543d6784d4cc 1570
EasyCAT 0:543d6784d4cc 1571 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 1572 /** Enumerate and init all slaves.
EasyCAT 0:543d6784d4cc 1573 *
EasyCAT 0:543d6784d4cc 1574 * @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
EasyCAT 0:543d6784d4cc 1575 * @return Workcounter of slave discover datagram = number of slaves found
EasyCAT 0:543d6784d4cc 1576 * @see ecx_config_init
EasyCAT 0:543d6784d4cc 1577 */
EasyCAT 0:543d6784d4cc 1578 int ec_config_init(uint8 usetable)
EasyCAT 0:543d6784d4cc 1579 {
EasyCAT 0:543d6784d4cc 1580 return ecx_config_init(&ecx_context, usetable);
EasyCAT 0:543d6784d4cc 1581 }
EasyCAT 0:543d6784d4cc 1582
EasyCAT 0:543d6784d4cc 1583 /** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
EasyCAT 0:543d6784d4cc 1584 * in sequential order (legacy SOEM way).
EasyCAT 0:543d6784d4cc 1585 *
EasyCAT 0:543d6784d4cc 1586 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1587 * @param[in] group = group to map, 0 = all groups
EasyCAT 0:543d6784d4cc 1588 * @return IOmap size
EasyCAT 0:543d6784d4cc 1589 * @see ecx_config_map_group
EasyCAT 0:543d6784d4cc 1590 */
EasyCAT 0:543d6784d4cc 1591 int ec_config_map_group(void *pIOmap, uint8 group)
EasyCAT 0:543d6784d4cc 1592 {
EasyCAT 0:543d6784d4cc 1593 return ecx_config_map_group(&ecx_context, pIOmap, group);
EasyCAT 0:543d6784d4cc 1594 }
EasyCAT 0:543d6784d4cc 1595
EasyCAT 0:543d6784d4cc 1596 /** Map all PDOs in one group of slaves to IOmap with Outputs/Inputs
EasyCAT 0:543d6784d4cc 1597 * overlapping. NOTE: Must use this for TI ESC when using LRW.
EasyCAT 0:543d6784d4cc 1598 *
EasyCAT 0:543d6784d4cc 1599 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1600 * @param[in] group = group to map, 0 = all groups
EasyCAT 0:543d6784d4cc 1601 * @return IOmap size
EasyCAT 0:543d6784d4cc 1602 * @see ecx_config_overlap_map_group
EasyCAT 0:543d6784d4cc 1603 */
EasyCAT 0:543d6784d4cc 1604 int ec_config_overlap_map_group(void *pIOmap, uint8 group)
EasyCAT 0:543d6784d4cc 1605 {
EasyCAT 0:543d6784d4cc 1606 return ecx_config_overlap_map_group(&ecx_context, pIOmap, group);
EasyCAT 0:543d6784d4cc 1607 }
EasyCAT 0:543d6784d4cc 1608
EasyCAT 0:543d6784d4cc 1609 /** Map all PDOs from slaves to IOmap with Outputs/Inputs
EasyCAT 0:543d6784d4cc 1610 * in sequential order (legacy SOEM way).
EasyCAT 0:543d6784d4cc 1611 *
EasyCAT 0:543d6784d4cc 1612 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1613 * @return IOmap size
EasyCAT 0:543d6784d4cc 1614 */
EasyCAT 0:543d6784d4cc 1615 int ec_config_map(void *pIOmap)
EasyCAT 0:543d6784d4cc 1616 {
EasyCAT 0:543d6784d4cc 1617 return ec_config_map_group(pIOmap, 0);
EasyCAT 0:543d6784d4cc 1618 }
EasyCAT 0:543d6784d4cc 1619
EasyCAT 0:543d6784d4cc 1620 /** Map all PDOs from slaves to IOmap with Outputs/Inputs
EasyCAT 0:543d6784d4cc 1621 * overlapping. NOTE: Must use this for TI ESC when using LRW.
EasyCAT 0:543d6784d4cc 1622 *
EasyCAT 0:543d6784d4cc 1623 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1624 * @return IOmap size
EasyCAT 0:543d6784d4cc 1625 */
EasyCAT 0:543d6784d4cc 1626 int ec_config_overlap_map(void *pIOmap)
EasyCAT 0:543d6784d4cc 1627 {
EasyCAT 0:543d6784d4cc 1628 return ec_config_overlap_map_group(pIOmap, 0);
EasyCAT 0:543d6784d4cc 1629 }
EasyCAT 0:543d6784d4cc 1630
EasyCAT 0:543d6784d4cc 1631 /** Enumerate / map and init all slaves.
EasyCAT 0:543d6784d4cc 1632 *
EasyCAT 0:543d6784d4cc 1633 * @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
EasyCAT 0:543d6784d4cc 1634 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1635 * @return Workcounter of slave discover datagram = number of slaves found
EasyCAT 0:543d6784d4cc 1636 */
EasyCAT 0:543d6784d4cc 1637 int ec_config(uint8 usetable, void *pIOmap)
EasyCAT 0:543d6784d4cc 1638 {
EasyCAT 0:543d6784d4cc 1639 int wkc;
EasyCAT 0:543d6784d4cc 1640 wkc = ec_config_init(usetable);
EasyCAT 0:543d6784d4cc 1641 if (wkc)
EasyCAT 0:543d6784d4cc 1642 {
EasyCAT 0:543d6784d4cc 1643 ec_config_map(pIOmap);
EasyCAT 0:543d6784d4cc 1644 }
EasyCAT 0:543d6784d4cc 1645 return wkc;
EasyCAT 0:543d6784d4cc 1646 }
EasyCAT 0:543d6784d4cc 1647
EasyCAT 0:543d6784d4cc 1648 /** Enumerate / map and init all slaves.
EasyCAT 0:543d6784d4cc 1649 *
EasyCAT 0:543d6784d4cc 1650 * @param[in] usetable = TRUE when using configtable to init slaves, FALSE otherwise
EasyCAT 0:543d6784d4cc 1651 * @param[out] pIOmap = pointer to IOmap
EasyCAT 0:543d6784d4cc 1652 * @return Workcounter of slave discover datagram = number of slaves found
EasyCAT 0:543d6784d4cc 1653 */
EasyCAT 0:543d6784d4cc 1654 int ec_config_overlap(uint8 usetable, void *pIOmap)
EasyCAT 0:543d6784d4cc 1655 {
EasyCAT 0:543d6784d4cc 1656 int wkc;
EasyCAT 0:543d6784d4cc 1657 wkc = ec_config_init(usetable);
EasyCAT 0:543d6784d4cc 1658 if (wkc)
EasyCAT 0:543d6784d4cc 1659 {
EasyCAT 0:543d6784d4cc 1660 ec_config_overlap_map(pIOmap);
EasyCAT 0:543d6784d4cc 1661 }
EasyCAT 0:543d6784d4cc 1662 return wkc;
EasyCAT 0:543d6784d4cc 1663 }
EasyCAT 0:543d6784d4cc 1664
EasyCAT 0:543d6784d4cc 1665 /** Recover slave.
EasyCAT 0:543d6784d4cc 1666 *
EasyCAT 0:543d6784d4cc 1667 * @param[in] slave = slave to recover
EasyCAT 0:543d6784d4cc 1668 * @param[in] timeout = local timeout f.e. EC_TIMEOUTRET3
EasyCAT 0:543d6784d4cc 1669 * @return >0 if successful
EasyCAT 0:543d6784d4cc 1670 * @see ecx_recover_slave
EasyCAT 0:543d6784d4cc 1671 */
EasyCAT 0:543d6784d4cc 1672 int ec_recover_slave(uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 1673 {
EasyCAT 0:543d6784d4cc 1674 return ecx_recover_slave(&ecx_context, slave, timeout);
EasyCAT 0:543d6784d4cc 1675 }
EasyCAT 0:543d6784d4cc 1676
EasyCAT 0:543d6784d4cc 1677 /** Reconfigure slave.
EasyCAT 0:543d6784d4cc 1678 *
EasyCAT 0:543d6784d4cc 1679 * @param[in] slave = slave to reconfigure
EasyCAT 0:543d6784d4cc 1680 * @param[in] timeout = local timeout f.e. EC_TIMEOUTRET3
EasyCAT 0:543d6784d4cc 1681 * @return Slave state
EasyCAT 0:543d6784d4cc 1682 * @see ecx_reconfig_slave
EasyCAT 0:543d6784d4cc 1683 */
EasyCAT 0:543d6784d4cc 1684 int ec_reconfig_slave(uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 1685 {
EasyCAT 0:543d6784d4cc 1686 return ecx_reconfig_slave(&ecx_context, slave, timeout);
EasyCAT 0:543d6784d4cc 1687 }
EasyCAT 0:543d6784d4cc 1688 #endif