SOEM EtherCAT Master library for STM Nucleo F767ZI
Dependents: EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB
- This repository contains the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the ecosystem by AB&T Tecnologie Informatiche.
- It has been developed for the EasyCAT LAB , a complete educational and experimental EtherCAT® system, composed of one master and two slaves .
- The EasyCAT LAB is provided as a kit by AB&T Tecnologie Informatiche, to allow everybody to have an educational EtherCAT® system up and running in a matter of minutes.
Warning
- Currently only the Nucleo STM32F767ZI board is supported.
SOEM/ethercatconfig.c@0:543d6784d4cc, 2019-06-11 (annotated)
- 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?
User | Revision | Line number | New 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 |