AB&T
/
EasyCAT_LAB_very_simple
EasyCAT LAB - EtherCAT master very simple example
- This repository contains a very basic example 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.
- It uses the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the ecosystem by AB&T Tecnologie Informatiche.
- The slaves are based on the EasyCAT SHIELD and the Arduino UNO.
Note
- This example uses two LAB 2 slaves.
Note
- In this example, to keep things as simple as possible, only two bytes of data are exchanged between the slaves and the TFT display is not used .
soem_start.cpp@2:368e7d4d8171, 11 months ago (annotated)
- Committer:
- EasyCAT
- Date:
- Wed Oct 25 15:38:52 2023 +0000
- Revision:
- 2:368e7d4d8171
- Parent:
- 0:bc829777f1ea
Bug fix
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sulymarco | 0:bc829777f1ea | 1 | |
sulymarco | 0:bc829777f1ea | 2 | #include "soem_start.h" |
sulymarco | 0:bc829777f1ea | 3 | #include "ethercat.h" |
sulymarco | 0:bc829777f1ea | 4 | #include "string.h" |
sulymarco | 0:bc829777f1ea | 5 | #include "oshw.h" |
sulymarco | 0:bc829777f1ea | 6 | |
sulymarco | 0:bc829777f1ea | 7 | #include "mbed.h" |
sulymarco | 0:bc829777f1ea | 8 | |
sulymarco | 0:bc829777f1ea | 9 | #include <inttypes.h> |
sulymarco | 0:bc829777f1ea | 10 | |
sulymarco | 0:bc829777f1ea | 11 | |
sulymarco | 0:bc829777f1ea | 12 | boolean printSDO = TRUE; |
sulymarco | 0:bc829777f1ea | 13 | boolean printMAP = TRUE; |
sulymarco | 0:bc829777f1ea | 14 | |
sulymarco | 0:bc829777f1ea | 15 | ec_ODlistt ODlist; |
sulymarco | 0:bc829777f1ea | 16 | ec_OElistt OElist; |
sulymarco | 0:bc829777f1ea | 17 | char usdo[128]; |
sulymarco | 0:bc829777f1ea | 18 | char hstr[1024]; |
sulymarco | 0:bc829777f1ea | 19 | |
sulymarco | 0:bc829777f1ea | 20 | char extern IOmap[]; |
sulymarco | 0:bc829777f1ea | 21 | |
sulymarco | 0:bc829777f1ea | 22 | uint32_t error_counter = 0; |
sulymarco | 0:bc829777f1ea | 23 | |
sulymarco | 0:bc829777f1ea | 24 | |
sulymarco | 0:bc829777f1ea | 25 | char* dtype2string(uint16 dtype); |
sulymarco | 0:bc829777f1ea | 26 | char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype); |
sulymarco | 0:bc829777f1ea | 27 | int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset); |
sulymarco | 0:bc829777f1ea | 28 | void si_sdo(int cnt); |
sulymarco | 0:bc829777f1ea | 29 | int si_map_sdo(int slave); |
sulymarco | 0:bc829777f1ea | 30 | int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset); |
sulymarco | 0:bc829777f1ea | 31 | bool network_scanning(void); |
sulymarco | 0:bc829777f1ea | 32 | |
sulymarco | 0:bc829777f1ea | 33 | |
sulymarco | 0:bc829777f1ea | 34 | |
sulymarco | 0:bc829777f1ea | 35 | //---- convert Ethercat types to string ---------------------------------------- |
sulymarco | 0:bc829777f1ea | 36 | |
sulymarco | 0:bc829777f1ea | 37 | |
sulymarco | 0:bc829777f1ea | 38 | char* dtype2string(uint16 dtype) |
sulymarco | 0:bc829777f1ea | 39 | { |
sulymarco | 0:bc829777f1ea | 40 | switch(dtype) |
sulymarco | 0:bc829777f1ea | 41 | { |
sulymarco | 0:bc829777f1ea | 42 | case ECT_BOOLEAN: |
sulymarco | 0:bc829777f1ea | 43 | sprintf(hstr, "BOOLEAN"); |
sulymarco | 0:bc829777f1ea | 44 | break; |
sulymarco | 0:bc829777f1ea | 45 | case ECT_INTEGER8: |
sulymarco | 0:bc829777f1ea | 46 | sprintf(hstr, "INTEGER8"); |
sulymarco | 0:bc829777f1ea | 47 | break; |
sulymarco | 0:bc829777f1ea | 48 | case ECT_INTEGER16: |
sulymarco | 0:bc829777f1ea | 49 | sprintf(hstr, "INTEGER16"); |
sulymarco | 0:bc829777f1ea | 50 | break; |
sulymarco | 0:bc829777f1ea | 51 | case ECT_INTEGER32: |
sulymarco | 0:bc829777f1ea | 52 | sprintf(hstr, "INTEGER32"); |
sulymarco | 0:bc829777f1ea | 53 | break; |
sulymarco | 0:bc829777f1ea | 54 | case ECT_INTEGER24: |
sulymarco | 0:bc829777f1ea | 55 | sprintf(hstr, "INTEGER24"); |
sulymarco | 0:bc829777f1ea | 56 | break; |
sulymarco | 0:bc829777f1ea | 57 | case ECT_INTEGER64: |
sulymarco | 0:bc829777f1ea | 58 | sprintf(hstr, "INTEGER64"); |
sulymarco | 0:bc829777f1ea | 59 | break; |
sulymarco | 0:bc829777f1ea | 60 | case ECT_UNSIGNED8: |
sulymarco | 0:bc829777f1ea | 61 | sprintf(hstr, "UNSIGNED8"); |
sulymarco | 0:bc829777f1ea | 62 | break; |
sulymarco | 0:bc829777f1ea | 63 | case ECT_UNSIGNED16: |
sulymarco | 0:bc829777f1ea | 64 | sprintf(hstr, "UNSIGNED16"); |
sulymarco | 0:bc829777f1ea | 65 | break; |
sulymarco | 0:bc829777f1ea | 66 | case ECT_UNSIGNED32: |
sulymarco | 0:bc829777f1ea | 67 | sprintf(hstr, "UNSIGNED32"); |
sulymarco | 0:bc829777f1ea | 68 | break; |
sulymarco | 0:bc829777f1ea | 69 | case ECT_UNSIGNED24: |
sulymarco | 0:bc829777f1ea | 70 | sprintf(hstr, "UNSIGNED24"); |
sulymarco | 0:bc829777f1ea | 71 | break; |
sulymarco | 0:bc829777f1ea | 72 | case ECT_UNSIGNED64: |
sulymarco | 0:bc829777f1ea | 73 | sprintf(hstr, "UNSIGNED64"); |
sulymarco | 0:bc829777f1ea | 74 | break; |
sulymarco | 0:bc829777f1ea | 75 | case ECT_REAL32: |
sulymarco | 0:bc829777f1ea | 76 | sprintf(hstr, "REAL32"); |
sulymarco | 0:bc829777f1ea | 77 | break; |
sulymarco | 0:bc829777f1ea | 78 | case ECT_REAL64: |
sulymarco | 0:bc829777f1ea | 79 | sprintf(hstr, "REAL64"); |
sulymarco | 0:bc829777f1ea | 80 | break; |
sulymarco | 0:bc829777f1ea | 81 | case ECT_BIT1: |
sulymarco | 0:bc829777f1ea | 82 | sprintf(hstr, "BIT1"); |
sulymarco | 0:bc829777f1ea | 83 | break; |
sulymarco | 0:bc829777f1ea | 84 | case ECT_BIT2: |
sulymarco | 0:bc829777f1ea | 85 | sprintf(hstr, "BIT2"); |
sulymarco | 0:bc829777f1ea | 86 | break; |
sulymarco | 0:bc829777f1ea | 87 | case ECT_BIT3: |
sulymarco | 0:bc829777f1ea | 88 | sprintf(hstr, "BIT3"); |
sulymarco | 0:bc829777f1ea | 89 | break; |
sulymarco | 0:bc829777f1ea | 90 | case ECT_BIT4: |
sulymarco | 0:bc829777f1ea | 91 | sprintf(hstr, "BIT4"); |
sulymarco | 0:bc829777f1ea | 92 | break; |
sulymarco | 0:bc829777f1ea | 93 | case ECT_BIT5: |
sulymarco | 0:bc829777f1ea | 94 | sprintf(hstr, "BIT5"); |
sulymarco | 0:bc829777f1ea | 95 | break; |
sulymarco | 0:bc829777f1ea | 96 | case ECT_BIT6: |
sulymarco | 0:bc829777f1ea | 97 | sprintf(hstr, "BIT6"); |
sulymarco | 0:bc829777f1ea | 98 | break; |
sulymarco | 0:bc829777f1ea | 99 | case ECT_BIT7: |
sulymarco | 0:bc829777f1ea | 100 | sprintf(hstr, "BIT7"); |
sulymarco | 0:bc829777f1ea | 101 | break; |
sulymarco | 0:bc829777f1ea | 102 | case ECT_BIT8: |
sulymarco | 0:bc829777f1ea | 103 | sprintf(hstr, "BIT8"); |
sulymarco | 0:bc829777f1ea | 104 | break; |
sulymarco | 0:bc829777f1ea | 105 | case ECT_VISIBLE_STRING: |
sulymarco | 0:bc829777f1ea | 106 | sprintf(hstr, "VISIBLE_STRING"); |
sulymarco | 0:bc829777f1ea | 107 | break; |
sulymarco | 0:bc829777f1ea | 108 | case ECT_OCTET_STRING: |
sulymarco | 0:bc829777f1ea | 109 | sprintf(hstr, "OCTET_STRING"); |
sulymarco | 0:bc829777f1ea | 110 | break; |
sulymarco | 0:bc829777f1ea | 111 | default: |
sulymarco | 0:bc829777f1ea | 112 | sprintf(hstr, "Type 0x%4.4X", dtype); |
sulymarco | 0:bc829777f1ea | 113 | } |
sulymarco | 0:bc829777f1ea | 114 | return hstr; |
sulymarco | 0:bc829777f1ea | 115 | } |
sulymarco | 0:bc829777f1ea | 116 | |
sulymarco | 0:bc829777f1ea | 117 | |
sulymarco | 0:bc829777f1ea | 118 | //------------------------------------------------------------------------------ |
sulymarco | 0:bc829777f1ea | 119 | |
sulymarco | 0:bc829777f1ea | 120 | char* SDO2string(uint16 slave, uint16 index, uint8 subidx, uint16 dtype) |
sulymarco | 0:bc829777f1ea | 121 | { |
sulymarco | 0:bc829777f1ea | 122 | int l = sizeof(usdo) - 1, i; |
sulymarco | 0:bc829777f1ea | 123 | uint8 *u8; |
sulymarco | 0:bc829777f1ea | 124 | int8 *i8; |
sulymarco | 0:bc829777f1ea | 125 | uint16 *u16; |
sulymarco | 0:bc829777f1ea | 126 | int16 *i16; |
sulymarco | 0:bc829777f1ea | 127 | uint32 *u32; |
sulymarco | 0:bc829777f1ea | 128 | int32 *i32; |
sulymarco | 0:bc829777f1ea | 129 | uint64 *u64; |
sulymarco | 0:bc829777f1ea | 130 | int64 *i64; |
sulymarco | 0:bc829777f1ea | 131 | float *sr; |
sulymarco | 0:bc829777f1ea | 132 | double *dr; |
sulymarco | 0:bc829777f1ea | 133 | char es[32]; |
sulymarco | 0:bc829777f1ea | 134 | |
sulymarco | 0:bc829777f1ea | 135 | memset(&usdo, 0, 128); |
sulymarco | 0:bc829777f1ea | 136 | ec_SDOread(slave, index, subidx, FALSE, &l, &usdo, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 137 | if (EcatError) |
sulymarco | 0:bc829777f1ea | 138 | { |
sulymarco | 0:bc829777f1ea | 139 | return ec_elist2string(); |
sulymarco | 0:bc829777f1ea | 140 | } |
sulymarco | 0:bc829777f1ea | 141 | else |
sulymarco | 0:bc829777f1ea | 142 | { |
sulymarco | 0:bc829777f1ea | 143 | switch(dtype) |
sulymarco | 0:bc829777f1ea | 144 | { |
sulymarco | 0:bc829777f1ea | 145 | case ECT_BOOLEAN: |
sulymarco | 0:bc829777f1ea | 146 | u8 = (uint8*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 147 | if (*u8) sprintf(hstr, "TRUE"); |
sulymarco | 0:bc829777f1ea | 148 | else sprintf(hstr, "FALSE"); |
sulymarco | 0:bc829777f1ea | 149 | break; |
sulymarco | 0:bc829777f1ea | 150 | case ECT_INTEGER8: |
sulymarco | 0:bc829777f1ea | 151 | i8 = (int8*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 152 | sprintf(hstr, "0x%2.2x %d", *i8, *i8); |
sulymarco | 0:bc829777f1ea | 153 | break; |
sulymarco | 0:bc829777f1ea | 154 | case ECT_INTEGER16: |
sulymarco | 0:bc829777f1ea | 155 | i16 = (int16*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 156 | sprintf(hstr, "0x%4.4x %d", *i16, *i16); |
sulymarco | 0:bc829777f1ea | 157 | break; |
sulymarco | 0:bc829777f1ea | 158 | case ECT_INTEGER32: |
sulymarco | 0:bc829777f1ea | 159 | case ECT_INTEGER24: |
sulymarco | 0:bc829777f1ea | 160 | i32 = (int32*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 161 | sprintf(hstr, "0x%8.8x %d", *i32, *i32); |
sulymarco | 0:bc829777f1ea | 162 | break; |
sulymarco | 0:bc829777f1ea | 163 | case ECT_INTEGER64: |
sulymarco | 0:bc829777f1ea | 164 | i64 = (int64*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 165 | sprintf(hstr, "0x%16.16"PRIx64" %"PRId64, *i64, *i64); |
sulymarco | 0:bc829777f1ea | 166 | break; |
sulymarco | 0:bc829777f1ea | 167 | case ECT_UNSIGNED8: |
sulymarco | 0:bc829777f1ea | 168 | u8 = (uint8*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 169 | sprintf(hstr, "0x%2.2x %u", *u8, *u8); |
sulymarco | 0:bc829777f1ea | 170 | break; |
sulymarco | 0:bc829777f1ea | 171 | case ECT_UNSIGNED16: |
sulymarco | 0:bc829777f1ea | 172 | u16 = (uint16*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 173 | sprintf(hstr, "0x%4.4x %u", *u16, *u16); |
sulymarco | 0:bc829777f1ea | 174 | break; |
sulymarco | 0:bc829777f1ea | 175 | case ECT_UNSIGNED32: |
sulymarco | 0:bc829777f1ea | 176 | case ECT_UNSIGNED24: |
sulymarco | 0:bc829777f1ea | 177 | u32 = (uint32*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 178 | sprintf(hstr, "0x%8.8x %u", *u32, *u32); |
sulymarco | 0:bc829777f1ea | 179 | break; |
sulymarco | 0:bc829777f1ea | 180 | case ECT_UNSIGNED64: |
sulymarco | 0:bc829777f1ea | 181 | u64 = (uint64*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 182 | sprintf(hstr, "0x%16.16"PRIx64" %"PRIu64, *u64, *u64); |
sulymarco | 0:bc829777f1ea | 183 | break; |
sulymarco | 0:bc829777f1ea | 184 | case ECT_REAL32: |
sulymarco | 0:bc829777f1ea | 185 | sr = (float*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 186 | sprintf(hstr, "%f", *sr); |
sulymarco | 0:bc829777f1ea | 187 | break; |
sulymarco | 0:bc829777f1ea | 188 | case ECT_REAL64: |
sulymarco | 0:bc829777f1ea | 189 | dr = (double*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 190 | sprintf(hstr, "%f", *dr); |
sulymarco | 0:bc829777f1ea | 191 | break; |
sulymarco | 0:bc829777f1ea | 192 | case ECT_BIT1: |
sulymarco | 0:bc829777f1ea | 193 | case ECT_BIT2: |
sulymarco | 0:bc829777f1ea | 194 | case ECT_BIT3: |
sulymarco | 0:bc829777f1ea | 195 | case ECT_BIT4: |
sulymarco | 0:bc829777f1ea | 196 | case ECT_BIT5: |
sulymarco | 0:bc829777f1ea | 197 | case ECT_BIT6: |
sulymarco | 0:bc829777f1ea | 198 | case ECT_BIT7: |
sulymarco | 0:bc829777f1ea | 199 | case ECT_BIT8: |
sulymarco | 0:bc829777f1ea | 200 | u8 = (uint8*) &usdo[0]; |
sulymarco | 0:bc829777f1ea | 201 | sprintf(hstr, "0x%x", *u8); |
sulymarco | 0:bc829777f1ea | 202 | break; |
sulymarco | 0:bc829777f1ea | 203 | case ECT_VISIBLE_STRING: |
sulymarco | 0:bc829777f1ea | 204 | strcpy(hstr, usdo); |
sulymarco | 0:bc829777f1ea | 205 | break; |
sulymarco | 0:bc829777f1ea | 206 | case ECT_OCTET_STRING: |
sulymarco | 0:bc829777f1ea | 207 | hstr[0] = 0x00; |
sulymarco | 0:bc829777f1ea | 208 | for (i = 0 ; i < l ; i++) |
sulymarco | 0:bc829777f1ea | 209 | { |
sulymarco | 0:bc829777f1ea | 210 | sprintf(es, "0x%2.2x ", usdo[i]); |
sulymarco | 0:bc829777f1ea | 211 | strcat( hstr, es); |
sulymarco | 0:bc829777f1ea | 212 | } |
sulymarco | 0:bc829777f1ea | 213 | break; |
sulymarco | 0:bc829777f1ea | 214 | default: |
sulymarco | 0:bc829777f1ea | 215 | sprintf(hstr, "Unknown type"); |
sulymarco | 0:bc829777f1ea | 216 | } |
sulymarco | 0:bc829777f1ea | 217 | return hstr; |
sulymarco | 0:bc829777f1ea | 218 | } |
sulymarco | 0:bc829777f1ea | 219 | } |
sulymarco | 0:bc829777f1ea | 220 | |
sulymarco | 0:bc829777f1ea | 221 | |
sulymarco | 0:bc829777f1ea | 222 | //----- read PDO assign structure ---------------------------------------------- |
sulymarco | 0:bc829777f1ea | 223 | |
sulymarco | 0:bc829777f1ea | 224 | int si_PDOassign(uint16 slave, uint16 PDOassign, int mapoffset, int bitoffset) |
sulymarco | 0:bc829777f1ea | 225 | { |
sulymarco | 0:bc829777f1ea | 226 | uint16 idxloop, nidx, subidxloop, rdat, idx, subidx; |
sulymarco | 0:bc829777f1ea | 227 | uint8 subcnt; |
sulymarco | 0:bc829777f1ea | 228 | int wkc, bsize = 0, rdl; |
sulymarco | 0:bc829777f1ea | 229 | int32 rdat2; |
sulymarco | 0:bc829777f1ea | 230 | uint8 bitlen, obj_subidx; |
sulymarco | 0:bc829777f1ea | 231 | uint16 obj_idx; |
sulymarco | 0:bc829777f1ea | 232 | int abs_offset, abs_bit; |
sulymarco | 0:bc829777f1ea | 233 | |
sulymarco | 0:bc829777f1ea | 234 | rdl = sizeof(rdat); rdat = 0; |
sulymarco | 0:bc829777f1ea | 235 | // read PDO assign subindex 0 (= number of PDO's) |
sulymarco | 0:bc829777f1ea | 236 | wkc = ec_SDOread(slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 237 | rdat = etohs(rdat); |
sulymarco | 0:bc829777f1ea | 238 | |
sulymarco | 0:bc829777f1ea | 239 | if ((wkc > 0) && (rdat > 0)) // positive result from slave? |
sulymarco | 0:bc829777f1ea | 240 | { |
sulymarco | 0:bc829777f1ea | 241 | nidx = rdat; // number of available sub indexes |
sulymarco | 0:bc829777f1ea | 242 | bsize = 0; |
sulymarco | 0:bc829777f1ea | 243 | |
sulymarco | 0:bc829777f1ea | 244 | for (idxloop = 1; idxloop <= nidx; idxloop++) // read all PDO's |
sulymarco | 0:bc829777f1ea | 245 | { |
sulymarco | 0:bc829777f1ea | 246 | rdl = sizeof(rdat); rdat = 0; |
sulymarco | 0:bc829777f1ea | 247 | // read PDO assign |
sulymarco | 0:bc829777f1ea | 248 | wkc = ec_SDOread(slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 249 | |
sulymarco | 0:bc829777f1ea | 250 | idx = etohl(rdat); // result is index of PDO |
sulymarco | 0:bc829777f1ea | 251 | if (idx > 0) |
sulymarco | 0:bc829777f1ea | 252 | { |
sulymarco | 0:bc829777f1ea | 253 | rdl = sizeof(subcnt); subcnt = 0; |
sulymarco | 0:bc829777f1ea | 254 | // read number of subindexes of PDO |
sulymarco | 0:bc829777f1ea | 255 | wkc = ec_SDOread(slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 256 | subidx = subcnt; |
sulymarco | 0:bc829777f1ea | 257 | // for each subindex |
sulymarco | 0:bc829777f1ea | 258 | for (subidxloop = 1; subidxloop <= subidx; subidxloop++) |
sulymarco | 0:bc829777f1ea | 259 | { |
sulymarco | 0:bc829777f1ea | 260 | rdl = sizeof(rdat2); rdat2 = 0; |
sulymarco | 0:bc829777f1ea | 261 | // read SDO that is mapped in PDO |
sulymarco | 0:bc829777f1ea | 262 | wkc = ec_SDOread(slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 263 | rdat2 = etohl(rdat2); |
sulymarco | 0:bc829777f1ea | 264 | |
sulymarco | 0:bc829777f1ea | 265 | bitlen = LO_BYTE(rdat2); // extract bitlength of SDO |
sulymarco | 0:bc829777f1ea | 266 | bsize += bitlen; |
sulymarco | 0:bc829777f1ea | 267 | obj_idx = (uint16)(rdat2 >> 16); |
sulymarco | 0:bc829777f1ea | 268 | obj_subidx = (uint8)((rdat2 >> 8) & 0x000000ff); |
sulymarco | 0:bc829777f1ea | 269 | abs_offset = mapoffset + (bitoffset / 8); |
sulymarco | 0:bc829777f1ea | 270 | abs_bit = bitoffset % 8; |
sulymarco | 0:bc829777f1ea | 271 | ODlist.Slave = slave; |
sulymarco | 0:bc829777f1ea | 272 | ODlist.Index[0] = obj_idx; |
sulymarco | 0:bc829777f1ea | 273 | OElist.Entries = 0; |
sulymarco | 0:bc829777f1ea | 274 | wkc = 0; |
sulymarco | 0:bc829777f1ea | 275 | |
sulymarco | 0:bc829777f1ea | 276 | if(obj_idx || obj_subidx) // read object entry from dictionary if not a filler (0x0000:0x00) |
sulymarco | 0:bc829777f1ea | 277 | wkc = ec_readOEsingle(0, obj_subidx, &ODlist, &OElist); |
sulymarco | 0:bc829777f1ea | 278 | printf(" [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen); |
sulymarco | 0:bc829777f1ea | 279 | |
sulymarco | 0:bc829777f1ea | 280 | if((wkc > 0) && OElist.Entries) |
sulymarco | 0:bc829777f1ea | 281 | { |
sulymarco | 0:bc829777f1ea | 282 | printf(" %-12s %s\n", dtype2string(OElist.DataType[obj_subidx]), OElist.Name[obj_subidx]); |
sulymarco | 0:bc829777f1ea | 283 | } |
sulymarco | 0:bc829777f1ea | 284 | else |
sulymarco | 0:bc829777f1ea | 285 | printf("\n"); |
sulymarco | 0:bc829777f1ea | 286 | bitoffset += bitlen; |
sulymarco | 0:bc829777f1ea | 287 | }; |
sulymarco | 0:bc829777f1ea | 288 | }; |
sulymarco | 0:bc829777f1ea | 289 | }; |
sulymarco | 0:bc829777f1ea | 290 | }; |
sulymarco | 0:bc829777f1ea | 291 | |
sulymarco | 0:bc829777f1ea | 292 | return bsize; // return total found bitlength (PDO) |
sulymarco | 0:bc829777f1ea | 293 | } |
sulymarco | 0:bc829777f1ea | 294 | |
sulymarco | 0:bc829777f1ea | 295 | |
sulymarco | 0:bc829777f1ea | 296 | //---- PDO mapping according to CoE -------------------------------------------- |
sulymarco | 0:bc829777f1ea | 297 | |
sulymarco | 0:bc829777f1ea | 298 | int si_map_sdo(int slave) |
sulymarco | 0:bc829777f1ea | 299 | { |
sulymarco | 0:bc829777f1ea | 300 | int wkc, rdl; |
sulymarco | 0:bc829777f1ea | 301 | int retVal = 0; |
sulymarco | 0:bc829777f1ea | 302 | uint8 nSM, iSM, tSM; |
sulymarco | 0:bc829777f1ea | 303 | int Tsize, outputs_bo, inputs_bo; |
sulymarco | 0:bc829777f1ea | 304 | uint8 SMt_bug_add; |
sulymarco | 0:bc829777f1ea | 305 | |
sulymarco | 0:bc829777f1ea | 306 | printf("PDO mapping according to CoE :\n\n"); |
sulymarco | 0:bc829777f1ea | 307 | SMt_bug_add = 0; |
sulymarco | 0:bc829777f1ea | 308 | outputs_bo = 0; |
sulymarco | 0:bc829777f1ea | 309 | inputs_bo = 0; |
sulymarco | 0:bc829777f1ea | 310 | rdl = sizeof(nSM); nSM = 0; |
sulymarco | 0:bc829777f1ea | 311 | // read SyncManager Communication Type object count |
sulymarco | 0:bc829777f1ea | 312 | wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 313 | |
sulymarco | 0:bc829777f1ea | 314 | if ((wkc > 0) && (nSM > 2)) // positive result from slave ? |
sulymarco | 0:bc829777f1ea | 315 | { |
sulymarco | 0:bc829777f1ea | 316 | nSM--; // make nSM equal to number of defined SM |
sulymarco | 0:bc829777f1ea | 317 | |
sulymarco | 0:bc829777f1ea | 318 | if (nSM > EC_MAXSM) // limit to maximum number of SM defined, |
sulymarco | 0:bc829777f1ea | 319 | nSM = EC_MAXSM; // if true the slave can't be configured |
sulymarco | 0:bc829777f1ea | 320 | |
sulymarco | 0:bc829777f1ea | 321 | for (iSM = 2 ; iSM <= nSM ; iSM++) // iterate for every SM type defined |
sulymarco | 0:bc829777f1ea | 322 | { |
sulymarco | 0:bc829777f1ea | 323 | rdl = sizeof(tSM); tSM = 0; |
sulymarco | 0:bc829777f1ea | 324 | // read SyncManager Communication Type |
sulymarco | 0:bc829777f1ea | 325 | wkc = ec_SDOread(slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM); |
sulymarco | 0:bc829777f1ea | 326 | if (wkc > 0) |
sulymarco | 0:bc829777f1ea | 327 | { |
sulymarco | 0:bc829777f1ea | 328 | if((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave! |
sulymarco | 0:bc829777f1ea | 329 | { |
sulymarco | 0:bc829777f1ea | 330 | SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4 |
sulymarco | 0:bc829777f1ea | 331 | printf("Activated SM type workaround, possible incorrect mapping.\n"); |
sulymarco | 0:bc829777f1ea | 332 | } |
sulymarco | 0:bc829777f1ea | 333 | |
sulymarco | 0:bc829777f1ea | 334 | if(tSM) // only add if SMt > 0 |
sulymarco | 0:bc829777f1ea | 335 | tSM += SMt_bug_add; |
sulymarco | 0:bc829777f1ea | 336 | |
sulymarco | 0:bc829777f1ea | 337 | if (tSM == 3) // outputs |
sulymarco | 0:bc829777f1ea | 338 | { // read the assign RXPDO |
sulymarco | 0:bc829777f1ea | 339 | |
sulymarco | 0:bc829777f1ea | 340 | printf(" SM%1d outputs\n addr b index: sub bitl data_type name\n", iSM); |
sulymarco | 0:bc829777f1ea | 341 | Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].outputs - (uint8 *)&IOmap[0]), outputs_bo ); |
sulymarco | 0:bc829777f1ea | 342 | outputs_bo += Tsize; |
sulymarco | 0:bc829777f1ea | 343 | } |
sulymarco | 0:bc829777f1ea | 344 | |
sulymarco | 0:bc829777f1ea | 345 | if (tSM == 4) // inputs |
sulymarco | 0:bc829777f1ea | 346 | { // read the assign TXPDO |
sulymarco | 0:bc829777f1ea | 347 | |
sulymarco | 0:bc829777f1ea | 348 | printf(" SM%1d inputs\n addr b index: sub bitl data_type name\n", iSM); |
sulymarco | 0:bc829777f1ea | 349 | Tsize = si_PDOassign(slave, ECT_SDO_PDOASSIGN + iSM, (int)(ec_slave[slave].inputs - (uint8 *)&IOmap[0]), inputs_bo ); |
sulymarco | 0:bc829777f1ea | 350 | inputs_bo += Tsize; |
sulymarco | 0:bc829777f1ea | 351 | } |
sulymarco | 0:bc829777f1ea | 352 | } |
sulymarco | 0:bc829777f1ea | 353 | } |
sulymarco | 0:bc829777f1ea | 354 | } |
sulymarco | 0:bc829777f1ea | 355 | |
sulymarco | 0:bc829777f1ea | 356 | if ((outputs_bo > 0) || (inputs_bo > 0)) // found some I/O bits? |
sulymarco | 0:bc829777f1ea | 357 | retVal = 1; |
sulymarco | 0:bc829777f1ea | 358 | return retVal; |
sulymarco | 0:bc829777f1ea | 359 | } |
sulymarco | 0:bc829777f1ea | 360 | |
sulymarco | 0:bc829777f1ea | 361 | |
sulymarco | 0:bc829777f1ea | 362 | //---- CoE objects description ------------------------------------------------- |
sulymarco | 0:bc829777f1ea | 363 | |
sulymarco | 0:bc829777f1ea | 364 | void si_sdo(int cnt) |
sulymarco | 0:bc829777f1ea | 365 | { |
sulymarco | 0:bc829777f1ea | 366 | int i, j; |
sulymarco | 0:bc829777f1ea | 367 | |
sulymarco | 0:bc829777f1ea | 368 | ODlist.Entries = 0; |
sulymarco | 0:bc829777f1ea | 369 | memset(&ODlist, 0, sizeof(ODlist)); |
sulymarco | 0:bc829777f1ea | 370 | if( ec_readODlist(cnt, &ODlist)) |
sulymarco | 0:bc829777f1ea | 371 | { |
sulymarco | 0:bc829777f1ea | 372 | printf(" CoE Object Description found, %d entries.\n",ODlist.Entries); |
sulymarco | 0:bc829777f1ea | 373 | for( i = 0 ; i < ODlist.Entries ; i++) |
sulymarco | 0:bc829777f1ea | 374 | { |
sulymarco | 0:bc829777f1ea | 375 | ec_readODdescription(i, &ODlist); |
sulymarco | 0:bc829777f1ea | 376 | while(EcatError) printf("%s", ec_elist2string()); |
sulymarco | 0:bc829777f1ea | 377 | printf(" Index: %4.4x Datatype: %4.4x Objectcode: %2.2x Name: %s\n", |
sulymarco | 0:bc829777f1ea | 378 | ODlist.Index[i], ODlist.DataType[i], ODlist.ObjectCode[i], ODlist.Name[i]); |
sulymarco | 0:bc829777f1ea | 379 | memset(&OElist, 0, sizeof(OElist)); |
sulymarco | 0:bc829777f1ea | 380 | ec_readOE(i, &ODlist, &OElist); |
sulymarco | 0:bc829777f1ea | 381 | while(EcatError) printf("%s", ec_elist2string()); |
sulymarco | 0:bc829777f1ea | 382 | for( j = 0 ; j < ODlist.MaxSub[i]+1 ; j++) |
sulymarco | 0:bc829777f1ea | 383 | { |
sulymarco | 0:bc829777f1ea | 384 | if ((OElist.DataType[j] > 0) && (OElist.BitLength[j] > 0)) |
sulymarco | 0:bc829777f1ea | 385 | { |
sulymarco | 0:bc829777f1ea | 386 | printf(" Sub: %2.2x Datatype: %4.4x Bitlength: %4.4x Obj.access: %4.4x Name: %s\n", |
sulymarco | 0:bc829777f1ea | 387 | j, OElist.DataType[j], OElist.BitLength[j], OElist.ObjAccess[j], OElist.Name[j]); |
sulymarco | 0:bc829777f1ea | 388 | if ((OElist.ObjAccess[j] & 0x0007)) |
sulymarco | 0:bc829777f1ea | 389 | { |
sulymarco | 0:bc829777f1ea | 390 | printf(" Value :%s\n", SDO2string(cnt, ODlist.Index[i], j, OElist.DataType[j])); |
sulymarco | 0:bc829777f1ea | 391 | } |
sulymarco | 0:bc829777f1ea | 392 | } |
sulymarco | 0:bc829777f1ea | 393 | } |
sulymarco | 0:bc829777f1ea | 394 | } |
sulymarco | 0:bc829777f1ea | 395 | } |
sulymarco | 0:bc829777f1ea | 396 | else |
sulymarco | 0:bc829777f1ea | 397 | { |
sulymarco | 0:bc829777f1ea | 398 | while(EcatError) printf("%s", ec_elist2string()); |
sulymarco | 0:bc829777f1ea | 399 | } |
sulymarco | 0:bc829777f1ea | 400 | } |
sulymarco | 0:bc829777f1ea | 401 | |
sulymarco | 0:bc829777f1ea | 402 | |
sulymarco | 0:bc829777f1ea | 403 | //---- PDO mapping according to SII -------------------------------------------- |
sulymarco | 0:bc829777f1ea | 404 | |
sulymarco | 0:bc829777f1ea | 405 | int si_map_sii(int slave) |
sulymarco | 0:bc829777f1ea | 406 | { |
sulymarco | 0:bc829777f1ea | 407 | int retVal = 0; |
sulymarco | 0:bc829777f1ea | 408 | int Tsize, outputs_bo, inputs_bo; |
sulymarco | 0:bc829777f1ea | 409 | |
sulymarco | 0:bc829777f1ea | 410 | printf("\nPDO mapping according to SII :\n\n"); |
sulymarco | 0:bc829777f1ea | 411 | |
sulymarco | 0:bc829777f1ea | 412 | outputs_bo = 0; |
sulymarco | 0:bc829777f1ea | 413 | inputs_bo = 0; |
sulymarco | 0:bc829777f1ea | 414 | // read the assign RXPDOs |
sulymarco | 0:bc829777f1ea | 415 | Tsize = si_siiPDO(slave, 1, (int)(ec_slave[slave].outputs - (uint8*)&IOmap), outputs_bo ); |
sulymarco | 0:bc829777f1ea | 416 | outputs_bo += Tsize; |
sulymarco | 0:bc829777f1ea | 417 | // read the assign TXPDOs |
sulymarco | 0:bc829777f1ea | 418 | Tsize = si_siiPDO(slave, 0, (int)(ec_slave[slave].inputs - (uint8*)&IOmap), inputs_bo ); |
sulymarco | 0:bc829777f1ea | 419 | inputs_bo += Tsize; |
sulymarco | 0:bc829777f1ea | 420 | |
sulymarco | 0:bc829777f1ea | 421 | if ((outputs_bo > 0) || (inputs_bo > 0)) // found some I/O bits ? |
sulymarco | 0:bc829777f1ea | 422 | retVal = 1; |
sulymarco | 0:bc829777f1ea | 423 | return retVal; |
sulymarco | 0:bc829777f1ea | 424 | } |
sulymarco | 0:bc829777f1ea | 425 | |
sulymarco | 0:bc829777f1ea | 426 | |
sulymarco | 0:bc829777f1ea | 427 | //------------------------------------------------------------------------------ |
sulymarco | 0:bc829777f1ea | 428 | |
sulymarco | 0:bc829777f1ea | 429 | int si_siiPDO(uint16 slave, uint8 t, int mapoffset, int bitoffset) |
sulymarco | 0:bc829777f1ea | 430 | { |
sulymarco | 0:bc829777f1ea | 431 | uint16 a , w, c, e, er, Size; |
sulymarco | 0:bc829777f1ea | 432 | uint8 eectl; |
sulymarco | 0:bc829777f1ea | 433 | uint16 obj_idx; |
sulymarco | 0:bc829777f1ea | 434 | uint8 obj_subidx; |
sulymarco | 0:bc829777f1ea | 435 | uint8 obj_name; |
sulymarco | 0:bc829777f1ea | 436 | uint8 obj_datatype; |
sulymarco | 0:bc829777f1ea | 437 | uint8 bitlen; |
sulymarco | 0:bc829777f1ea | 438 | int totalsize; |
sulymarco | 0:bc829777f1ea | 439 | ec_eepromPDOt eepPDO; |
sulymarco | 0:bc829777f1ea | 440 | ec_eepromPDOt *PDO; |
sulymarco | 0:bc829777f1ea | 441 | int abs_offset, abs_bit; |
sulymarco | 0:bc829777f1ea | 442 | char str_name[EC_MAXNAME + 1]; |
sulymarco | 0:bc829777f1ea | 443 | |
sulymarco | 0:bc829777f1ea | 444 | eectl = ec_slave[slave].eep_pdi; |
sulymarco | 0:bc829777f1ea | 445 | Size = 0; |
sulymarco | 0:bc829777f1ea | 446 | totalsize = 0; |
sulymarco | 0:bc829777f1ea | 447 | PDO = &eepPDO; |
sulymarco | 0:bc829777f1ea | 448 | PDO->nPDO = 0; |
sulymarco | 0:bc829777f1ea | 449 | PDO->Length = 0; |
sulymarco | 0:bc829777f1ea | 450 | PDO->Index[1] = 0; |
sulymarco | 0:bc829777f1ea | 451 | |
sulymarco | 0:bc829777f1ea | 452 | for (c = 0 ; c < EC_MAXSM ; c++) |
sulymarco | 0:bc829777f1ea | 453 | PDO->SMbitsize[c] = 0; |
sulymarco | 0:bc829777f1ea | 454 | |
sulymarco | 0:bc829777f1ea | 455 | if (t > 1) |
sulymarco | 0:bc829777f1ea | 456 | t = 1; |
sulymarco | 0:bc829777f1ea | 457 | |
sulymarco | 0:bc829777f1ea | 458 | PDO->Startpos = ec_siifind(slave, ECT_SII_PDO + t); |
sulymarco | 0:bc829777f1ea | 459 | |
sulymarco | 0:bc829777f1ea | 460 | if (PDO->Startpos > 0) |
sulymarco | 0:bc829777f1ea | 461 | { |
sulymarco | 0:bc829777f1ea | 462 | a = PDO->Startpos; |
sulymarco | 0:bc829777f1ea | 463 | w = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 464 | w += (ec_siigetbyte(slave, a++) << 8); |
sulymarco | 0:bc829777f1ea | 465 | PDO->Length = w; |
sulymarco | 0:bc829777f1ea | 466 | c = 1; |
sulymarco | 0:bc829777f1ea | 467 | |
sulymarco | 0:bc829777f1ea | 468 | do // traverse through all PDOs |
sulymarco | 0:bc829777f1ea | 469 | { |
sulymarco | 0:bc829777f1ea | 470 | PDO->nPDO++; |
sulymarco | 0:bc829777f1ea | 471 | PDO->Index[PDO->nPDO] = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 472 | PDO->Index[PDO->nPDO] += (ec_siigetbyte(slave, a++) << 8); |
sulymarco | 0:bc829777f1ea | 473 | PDO->BitSize[PDO->nPDO] = 0; |
sulymarco | 0:bc829777f1ea | 474 | c++; |
sulymarco | 0:bc829777f1ea | 475 | |
sulymarco | 0:bc829777f1ea | 476 | e = ec_siigetbyte(slave, a++); // number of entries in PDO |
sulymarco | 0:bc829777f1ea | 477 | PDO->SyncM[PDO->nPDO] = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 478 | a++; |
sulymarco | 0:bc829777f1ea | 479 | obj_name = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 480 | a += 2; |
sulymarco | 0:bc829777f1ea | 481 | c += 2; |
sulymarco | 0:bc829777f1ea | 482 | |
sulymarco | 0:bc829777f1ea | 483 | if (PDO->SyncM[PDO->nPDO] < EC_MAXSM) // active and in range SM? |
sulymarco | 0:bc829777f1ea | 484 | { |
sulymarco | 0:bc829777f1ea | 485 | str_name[0] = 0; |
sulymarco | 0:bc829777f1ea | 486 | if(obj_name) |
sulymarco | 0:bc829777f1ea | 487 | ec_siistring(str_name, slave, obj_name); |
sulymarco | 0:bc829777f1ea | 488 | |
sulymarco | 0:bc829777f1ea | 489 | if (t) |
sulymarco | 0:bc829777f1ea | 490 | printf(" SM%1d RXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name); |
sulymarco | 0:bc829777f1ea | 491 | else |
sulymarco | 0:bc829777f1ea | 492 | printf(" SM%1d TXPDO 0x%4.4X %s\n", PDO->SyncM[PDO->nPDO], PDO->Index[PDO->nPDO], str_name); |
sulymarco | 0:bc829777f1ea | 493 | |
sulymarco | 0:bc829777f1ea | 494 | printf(" addr b index: sub bitl data_type name\n"); |
sulymarco | 0:bc829777f1ea | 495 | |
sulymarco | 0:bc829777f1ea | 496 | for (er = 1; er <= e; er++) // read all entries defined in PDO |
sulymarco | 0:bc829777f1ea | 497 | { |
sulymarco | 0:bc829777f1ea | 498 | c += 4; |
sulymarco | 0:bc829777f1ea | 499 | obj_idx = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 500 | obj_idx += (ec_siigetbyte(slave, a++) << 8); |
sulymarco | 0:bc829777f1ea | 501 | obj_subidx = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 502 | obj_name = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 503 | obj_datatype = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 504 | bitlen = ec_siigetbyte(slave, a++); |
sulymarco | 0:bc829777f1ea | 505 | abs_offset = mapoffset + (bitoffset / 8); |
sulymarco | 0:bc829777f1ea | 506 | abs_bit = bitoffset % 8; |
sulymarco | 0:bc829777f1ea | 507 | |
sulymarco | 0:bc829777f1ea | 508 | PDO->BitSize[PDO->nPDO] += bitlen; |
sulymarco | 0:bc829777f1ea | 509 | a += 2; |
sulymarco | 0:bc829777f1ea | 510 | |
sulymarco | 0:bc829777f1ea | 511 | if(obj_idx || obj_subidx) // skip entry if filler (0x0000:0x00) |
sulymarco | 0:bc829777f1ea | 512 | { |
sulymarco | 0:bc829777f1ea | 513 | str_name[0] = 0; |
sulymarco | 0:bc829777f1ea | 514 | if(obj_name) |
sulymarco | 0:bc829777f1ea | 515 | ec_siistring(str_name, slave, obj_name); |
sulymarco | 0:bc829777f1ea | 516 | |
sulymarco | 0:bc829777f1ea | 517 | printf(" [0x%4.4X.%1d] 0x%4.4X:0x%2.2X 0x%2.2X", abs_offset, abs_bit, obj_idx, obj_subidx, bitlen); |
sulymarco | 0:bc829777f1ea | 518 | printf(" %-12s %s\n", dtype2string(obj_datatype), str_name); |
sulymarco | 0:bc829777f1ea | 519 | } |
sulymarco | 0:bc829777f1ea | 520 | bitoffset += bitlen; |
sulymarco | 0:bc829777f1ea | 521 | totalsize += bitlen; |
sulymarco | 0:bc829777f1ea | 522 | } |
sulymarco | 0:bc829777f1ea | 523 | PDO->SMbitsize[ PDO->SyncM[PDO->nPDO] ] += PDO->BitSize[PDO->nPDO]; |
sulymarco | 0:bc829777f1ea | 524 | Size += PDO->BitSize[PDO->nPDO]; |
sulymarco | 0:bc829777f1ea | 525 | c++; |
sulymarco | 0:bc829777f1ea | 526 | } |
sulymarco | 0:bc829777f1ea | 527 | |
sulymarco | 0:bc829777f1ea | 528 | else // PDO deactivated because SM is 0xff or > EC_MAXSM |
sulymarco | 0:bc829777f1ea | 529 | { |
sulymarco | 0:bc829777f1ea | 530 | c += 4 * e; |
sulymarco | 0:bc829777f1ea | 531 | a += 8 * e; |
sulymarco | 0:bc829777f1ea | 532 | c++; |
sulymarco | 0:bc829777f1ea | 533 | } |
sulymarco | 0:bc829777f1ea | 534 | // limit number of PDO entries in buffer |
sulymarco | 0:bc829777f1ea | 535 | if (PDO->nPDO >= (EC_MAXEEPDO - 1)) c = PDO->Length; |
sulymarco | 0:bc829777f1ea | 536 | } |
sulymarco | 0:bc829777f1ea | 537 | while (c < PDO->Length); |
sulymarco | 0:bc829777f1ea | 538 | } |
sulymarco | 0:bc829777f1ea | 539 | |
sulymarco | 0:bc829777f1ea | 540 | if (eectl) |
sulymarco | 0:bc829777f1ea | 541 | ec_eeprom2pdi(slave); // if eeprom control was previously pdi then restore |
sulymarco | 0:bc829777f1ea | 542 | |
sulymarco | 0:bc829777f1ea | 543 | return totalsize; |
sulymarco | 0:bc829777f1ea | 544 | } |
sulymarco | 0:bc829777f1ea | 545 | |
sulymarco | 0:bc829777f1ea | 546 | |
sulymarco | 0:bc829777f1ea | 547 | //------------------------------------------------------------------------------ |
sulymarco | 0:bc829777f1ea | 548 | |
sulymarco | 0:bc829777f1ea | 549 | bool network_scanning(void) |
sulymarco | 0:bc829777f1ea | 550 | |
sulymarco | 0:bc829777f1ea | 551 | { |
sulymarco | 0:bc829777f1ea | 552 | int expectedWKC; |
sulymarco | 0:bc829777f1ea | 553 | int cnt, i, j, nSM; |
sulymarco | 0:bc829777f1ea | 554 | uint16 ssigen; |
sulymarco | 0:bc829777f1ea | 555 | |
sulymarco | 0:bc829777f1ea | 556 | if ( ec_config(FALSE, &IOmap) > 0 ) // find and configure the slaves |
sulymarco | 0:bc829777f1ea | 557 | { |
sulymarco | 0:bc829777f1ea | 558 | ec_configdc(); |
sulymarco | 0:bc829777f1ea | 559 | while(EcatError) printf("%s", ec_elist2string()); |
sulymarco | 0:bc829777f1ea | 560 | |
sulymarco | 0:bc829777f1ea | 561 | printf("%d slaves found and configured.\n",ec_slavecount); |
sulymarco | 0:bc829777f1ea | 562 | |
sulymarco | 0:bc829777f1ea | 563 | expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC; |
sulymarco | 0:bc829777f1ea | 564 | printf("Calculated workcounter %d\n", expectedWKC); |
sulymarco | 0:bc829777f1ea | 565 | // wait for all slaves to reach SAFE_OP state |
sulymarco | 0:bc829777f1ea | 566 | ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 3); |
sulymarco | 0:bc829777f1ea | 567 | |
sulymarco | 0:bc829777f1ea | 568 | if (ec_slave[0].state != EC_STATE_SAFE_OP ) |
sulymarco | 0:bc829777f1ea | 569 | { |
sulymarco | 0:bc829777f1ea | 570 | printf("Not all slaves reached safe operational state.\n"); |
sulymarco | 0:bc829777f1ea | 571 | ec_readstate(); |
sulymarco | 0:bc829777f1ea | 572 | for(i = 1; i<=ec_slavecount ; i++) |
sulymarco | 0:bc829777f1ea | 573 | { |
sulymarco | 0:bc829777f1ea | 574 | if(ec_slave[i].state != EC_STATE_SAFE_OP) |
sulymarco | 0:bc829777f1ea | 575 | { |
sulymarco | 0:bc829777f1ea | 576 | printf("Slave %d State=%2x StatusCode=%4x : %s\n", |
sulymarco | 0:bc829777f1ea | 577 | i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode)); |
sulymarco | 0:bc829777f1ea | 578 | } |
sulymarco | 0:bc829777f1ea | 579 | } |
sulymarco | 0:bc829777f1ea | 580 | } |
sulymarco | 0:bc829777f1ea | 581 | |
sulymarco | 0:bc829777f1ea | 582 | ec_readstate(); |
sulymarco | 0:bc829777f1ea | 583 | |
sulymarco | 0:bc829777f1ea | 584 | for( cnt = 1 ; cnt <= ec_slavecount ; cnt++) |
sulymarco | 0:bc829777f1ea | 585 | { |
sulymarco | 0:bc829777f1ea | 586 | printf("\nSlave:%d -------------------------------------------------\nName:%s\n Output size: %dbits\n Input size: %dbits\n State: %d\n Delay: %d[ns]\n Has DC: %d\n", |
sulymarco | 0:bc829777f1ea | 587 | cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, |
sulymarco | 0:bc829777f1ea | 588 | ec_slave[cnt].state, ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); |
sulymarco | 0:bc829777f1ea | 589 | |
sulymarco | 0:bc829777f1ea | 590 | |
sulymarco | 0:bc829777f1ea | 591 | if (ec_slave[cnt].hasdc) printf(" DCParentport:%d\n", ec_slave[cnt].parentport); |
sulymarco | 0:bc829777f1ea | 592 | printf(" Activeports:%d.%d.%d.%d\n", (ec_slave[cnt].activeports & 0x01) > 0 , |
sulymarco | 0:bc829777f1ea | 593 | (ec_slave[cnt].activeports & 0x02) > 0 , |
sulymarco | 0:bc829777f1ea | 594 | (ec_slave[cnt].activeports & 0x04) > 0 , |
sulymarco | 0:bc829777f1ea | 595 | (ec_slave[cnt].activeports & 0x08) > 0 ); |
sulymarco | 0:bc829777f1ea | 596 | |
sulymarco | 0:bc829777f1ea | 597 | printf(" Configured address: %4.4X\n", ec_slave[cnt].configadr); |
sulymarco | 0:bc829777f1ea | 598 | printf(" Outputs address: %X\n", ec_slave[cnt].outputs); |
sulymarco | 0:bc829777f1ea | 599 | printf(" Inputs address: %X\n", ec_slave[cnt].inputs); |
sulymarco | 0:bc829777f1ea | 600 | |
sulymarco | 0:bc829777f1ea | 601 | printf(" Man: %8.8x ID: %8.8x Rev: %8.8x\n", (int)ec_slave[cnt].eep_man, (int)ec_slave[cnt].eep_id, (int)ec_slave[cnt].eep_rev); |
sulymarco | 0:bc829777f1ea | 602 | for(nSM = 0 ; nSM < EC_MAXSM ; nSM++) |
sulymarco | 0:bc829777f1ea | 603 | { |
sulymarco | 0:bc829777f1ea | 604 | if(ec_slave[cnt].SM[nSM].StartAddr > 0) |
sulymarco | 0:bc829777f1ea | 605 | printf(" SM%1d A:%4.4x L:%4d F:%8.8x Type:%d\n",nSM, ec_slave[cnt].SM[nSM].StartAddr, ec_slave[cnt].SM[nSM].SMlength, |
sulymarco | 0:bc829777f1ea | 606 | (int)ec_slave[cnt].SM[nSM].SMflags, ec_slave[cnt].SMtype[nSM]); |
sulymarco | 0:bc829777f1ea | 607 | } |
sulymarco | 0:bc829777f1ea | 608 | for(j = 0 ; j < ec_slave[cnt].FMMUunused ; j++) |
sulymarco | 0:bc829777f1ea | 609 | { |
sulymarco | 0:bc829777f1ea | 610 | printf(" FMMU%1d Ls:%8.8x Ll:%4d Lsb:%d Leb:%d Ps:%4.4x Psb:%d Ty:%2.2x Act:%2.2x\n", j, |
sulymarco | 0:bc829777f1ea | 611 | (int)ec_slave[cnt].FMMU[j].LogStart, ec_slave[cnt].FMMU[j].LogLength, ec_slave[cnt].FMMU[j].LogStartbit, |
sulymarco | 0:bc829777f1ea | 612 | ec_slave[cnt].FMMU[j].LogEndbit, ec_slave[cnt].FMMU[j].PhysStart, ec_slave[cnt].FMMU[j].PhysStartBit, |
sulymarco | 0:bc829777f1ea | 613 | ec_slave[cnt].FMMU[j].FMMUtype, ec_slave[cnt].FMMU[j].FMMUactive); |
sulymarco | 0:bc829777f1ea | 614 | } |
sulymarco | 0:bc829777f1ea | 615 | printf(" FMMUfunc 0:%d 1:%d 2:%d 3:%d\n", |
sulymarco | 0:bc829777f1ea | 616 | ec_slave[cnt].FMMU0func, ec_slave[cnt].FMMU1func, ec_slave[cnt].FMMU2func, ec_slave[cnt].FMMU3func); |
sulymarco | 0:bc829777f1ea | 617 | printf(" MBX length wr: %d rd: %d MBX protocols : %2.2x\n", ec_slave[cnt].mbx_l, ec_slave[cnt].mbx_rl, ec_slave[cnt].mbx_proto); |
sulymarco | 0:bc829777f1ea | 618 | ssigen = ec_siifind(cnt, ECT_SII_GENERAL); |
sulymarco | 0:bc829777f1ea | 619 | |
sulymarco | 0:bc829777f1ea | 620 | if (ssigen) // SII general section |
sulymarco | 0:bc829777f1ea | 621 | { |
sulymarco | 0:bc829777f1ea | 622 | ec_slave[cnt].CoEdetails = ec_siigetbyte(cnt, ssigen + 0x07); |
sulymarco | 0:bc829777f1ea | 623 | ec_slave[cnt].FoEdetails = ec_siigetbyte(cnt, ssigen + 0x08); |
sulymarco | 0:bc829777f1ea | 624 | ec_slave[cnt].EoEdetails = ec_siigetbyte(cnt, ssigen + 0x09); |
sulymarco | 0:bc829777f1ea | 625 | ec_slave[cnt].SoEdetails = ec_siigetbyte(cnt, ssigen + 0x0a); |
sulymarco | 0:bc829777f1ea | 626 | if((ec_siigetbyte(cnt, ssigen + 0x0d) & 0x02) > 0) |
sulymarco | 0:bc829777f1ea | 627 | { |
sulymarco | 0:bc829777f1ea | 628 | ec_slave[cnt].blockLRW = 1; |
sulymarco | 0:bc829777f1ea | 629 | ec_slave[0].blockLRW++; |
sulymarco | 0:bc829777f1ea | 630 | } |
sulymarco | 0:bc829777f1ea | 631 | ec_slave[cnt].Ebuscurrent = ec_siigetbyte(cnt, ssigen + 0x0e); |
sulymarco | 0:bc829777f1ea | 632 | ec_slave[cnt].Ebuscurrent += ec_siigetbyte(cnt, ssigen + 0x0f) << 8; |
sulymarco | 0:bc829777f1ea | 633 | ec_slave[0].Ebuscurrent += ec_slave[cnt].Ebuscurrent; |
sulymarco | 0:bc829777f1ea | 634 | } |
sulymarco | 0:bc829777f1ea | 635 | printf(" CoE details: %2.2x FoE details: %2.2x EoE details: %2.2x SoE details: %2.2x\n", |
sulymarco | 0:bc829777f1ea | 636 | ec_slave[cnt].CoEdetails, ec_slave[cnt].FoEdetails, ec_slave[cnt].EoEdetails, ec_slave[cnt].SoEdetails); |
sulymarco | 0:bc829777f1ea | 637 | printf(" Ebus current: %d[mA]\n only LRD/LWR:%d\n", |
sulymarco | 0:bc829777f1ea | 638 | ec_slave[cnt].Ebuscurrent, ec_slave[cnt].blockLRW); |
sulymarco | 0:bc829777f1ea | 639 | |
sulymarco | 0:bc829777f1ea | 640 | if ((ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) && printSDO) |
sulymarco | 0:bc829777f1ea | 641 | si_sdo(cnt); |
sulymarco | 0:bc829777f1ea | 642 | |
sulymarco | 0:bc829777f1ea | 643 | if(printMAP) |
sulymarco | 0:bc829777f1ea | 644 | { |
sulymarco | 0:bc829777f1ea | 645 | if (ec_slave[cnt].mbx_proto & ECT_MBXPROT_COE) |
sulymarco | 0:bc829777f1ea | 646 | si_map_sdo(cnt); |
sulymarco | 0:bc829777f1ea | 647 | else |
sulymarco | 0:bc829777f1ea | 648 | si_map_sii(cnt); |
sulymarco | 0:bc829777f1ea | 649 | } |
sulymarco | 0:bc829777f1ea | 650 | } |
sulymarco | 0:bc829777f1ea | 651 | return 1; |
sulymarco | 0:bc829777f1ea | 652 | } |
sulymarco | 0:bc829777f1ea | 653 | |
sulymarco | 0:bc829777f1ea | 654 | else |
sulymarco | 0:bc829777f1ea | 655 | { |
sulymarco | 0:bc829777f1ea | 656 | // ec_close(); //******// |
sulymarco | 0:bc829777f1ea | 657 | |
sulymarco | 0:bc829777f1ea | 658 | return 0; // no slaves found |
sulymarco | 0:bc829777f1ea | 659 | } |
sulymarco | 0:bc829777f1ea | 660 | } |
sulymarco | 0:bc829777f1ea | 661 | |
sulymarco | 0:bc829777f1ea | 662 | |
sulymarco | 0:bc829777f1ea | 663 | |
sulymarco | 0:bc829777f1ea | 664 | |
sulymarco | 0:bc829777f1ea | 665 | |
sulymarco | 0:bc829777f1ea | 666 |