SOEM EtherCAT Master library for STM Nucleo F767ZI

Dependents:   EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB

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

Warning

/media/uploads/EasyCAT/easycat_lab.jpg

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EasyCAT 0:543d6784d4cc 1 /*
EasyCAT 0:543d6784d4cc 2 * Licensed under the GNU General Public License version 2 with exceptions. See
EasyCAT 0:543d6784d4cc 3 * LICENSE file in the project root for full license information
EasyCAT 0:543d6784d4cc 4 */
EasyCAT 0:543d6784d4cc 5
EasyCAT 0:543d6784d4cc 6 /**
EasyCAT 0:543d6784d4cc 7 * \file
EasyCAT 0:543d6784d4cc 8 * \brief
EasyCAT 0:543d6784d4cc 9 * Main EtherCAT functions.
EasyCAT 0:543d6784d4cc 10 *
EasyCAT 0:543d6784d4cc 11 * Initialisation, state set and read, mailbox primitives, EEPROM primitives,
EasyCAT 0:543d6784d4cc 12 * SII reading and processdata exchange.
EasyCAT 0:543d6784d4cc 13 *
EasyCAT 0:543d6784d4cc 14 * Defines ec_slave[]. All slave information is put in this structure.
EasyCAT 0:543d6784d4cc 15 * Needed for most user interaction with slaves.
EasyCAT 0:543d6784d4cc 16 */
EasyCAT 0:543d6784d4cc 17
EasyCAT 0:543d6784d4cc 18 #include <stdio.h>
EasyCAT 0:543d6784d4cc 19 #include <string.h>
EasyCAT 0:543d6784d4cc 20 #include "osal.h"
EasyCAT 0:543d6784d4cc 21 #include "oshw.h"
EasyCAT 0:543d6784d4cc 22 #include "ethercat.h"
EasyCAT 0:543d6784d4cc 23
EasyCAT 0:543d6784d4cc 24
EasyCAT 0:543d6784d4cc 25 /** delay in us for eeprom ready loop */
EasyCAT 0:543d6784d4cc 26 #define EC_LOCALDELAY 200
EasyCAT 0:543d6784d4cc 27
EasyCAT 0:543d6784d4cc 28 /** record for ethercat eeprom communications */
EasyCAT 0:543d6784d4cc 29 PACKED_BEGIN
EasyCAT 0:543d6784d4cc 30 typedef struct PACKED
EasyCAT 0:543d6784d4cc 31 {
EasyCAT 0:543d6784d4cc 32 uint16 comm;
EasyCAT 0:543d6784d4cc 33 uint16 addr;
EasyCAT 0:543d6784d4cc 34 uint16 d2;
EasyCAT 0:543d6784d4cc 35 } ec_eepromt;
EasyCAT 0:543d6784d4cc 36 PACKED_END
EasyCAT 0:543d6784d4cc 37
EasyCAT 0:543d6784d4cc 38 /** mailbox error structure */
EasyCAT 0:543d6784d4cc 39 PACKED_BEGIN
EasyCAT 0:543d6784d4cc 40 typedef struct PACKED
EasyCAT 0:543d6784d4cc 41 {
EasyCAT 0:543d6784d4cc 42 ec_mbxheadert MbxHeader;
EasyCAT 0:543d6784d4cc 43 uint16 Type;
EasyCAT 0:543d6784d4cc 44 uint16 Detail;
EasyCAT 0:543d6784d4cc 45 } ec_mbxerrort;
EasyCAT 0:543d6784d4cc 46 PACKED_END
EasyCAT 0:543d6784d4cc 47
EasyCAT 0:543d6784d4cc 48 /** emergency request structure */
EasyCAT 0:543d6784d4cc 49 PACKED_BEGIN
EasyCAT 0:543d6784d4cc 50 typedef struct PACKED
EasyCAT 0:543d6784d4cc 51 {
EasyCAT 0:543d6784d4cc 52 ec_mbxheadert MbxHeader;
EasyCAT 0:543d6784d4cc 53 uint16 CANOpen;
EasyCAT 0:543d6784d4cc 54 uint16 ErrorCode;
EasyCAT 0:543d6784d4cc 55 uint8 ErrorReg;
EasyCAT 0:543d6784d4cc 56 uint8 bData;
EasyCAT 0:543d6784d4cc 57 uint16 w1,w2;
EasyCAT 0:543d6784d4cc 58 } ec_emcyt;
EasyCAT 0:543d6784d4cc 59 PACKED_END
EasyCAT 0:543d6784d4cc 60
EasyCAT 0:543d6784d4cc 61 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 62 /** Main slave data array.
EasyCAT 0:543d6784d4cc 63 * Each slave found on the network gets its own record.
EasyCAT 0:543d6784d4cc 64 * ec_slave[0] is reserved for the master. Structure gets filled
EasyCAT 0:543d6784d4cc 65 * in by the configuration function ec_config().
EasyCAT 0:543d6784d4cc 66 */
EasyCAT 0:543d6784d4cc 67 ec_slavet ec_slave[EC_MAXSLAVE];
EasyCAT 0:543d6784d4cc 68 /** number of slaves found on the network */
EasyCAT 0:543d6784d4cc 69 int ec_slavecount;
EasyCAT 0:543d6784d4cc 70 /** slave group structure */
EasyCAT 0:543d6784d4cc 71 ec_groupt ec_group[EC_MAXGROUP];
EasyCAT 0:543d6784d4cc 72
EasyCAT 0:543d6784d4cc 73 /** cache for EEPROM read functions */
EasyCAT 0:543d6784d4cc 74 static uint8 ec_esibuf[EC_MAXEEPBUF];
EasyCAT 0:543d6784d4cc 75 /** bitmap for filled cache buffer bytes */
EasyCAT 0:543d6784d4cc 76 static uint32 ec_esimap[EC_MAXEEPBITMAP];
EasyCAT 0:543d6784d4cc 77 /** current slave for EEPROM cache buffer */
EasyCAT 0:543d6784d4cc 78 static ec_eringt ec_elist;
EasyCAT 0:543d6784d4cc 79 static ec_idxstackT ec_idxstack;
EasyCAT 0:543d6784d4cc 80
EasyCAT 0:543d6784d4cc 81 /** SyncManager Communication Type struct to store data of one slave */
EasyCAT 0:543d6784d4cc 82 static ec_SMcommtypet ec_SMcommtype[EC_MAX_MAPT];
EasyCAT 0:543d6784d4cc 83 /** PDO assign struct to store data of one slave */
EasyCAT 0:543d6784d4cc 84 static ec_PDOassignt ec_PDOassign[EC_MAX_MAPT];
EasyCAT 0:543d6784d4cc 85 /** PDO description struct to store data of one slave */
EasyCAT 0:543d6784d4cc 86 static ec_PDOdesct ec_PDOdesc[EC_MAX_MAPT];
EasyCAT 0:543d6784d4cc 87
EasyCAT 0:543d6784d4cc 88 /** buffer for EEPROM SM data */
EasyCAT 0:543d6784d4cc 89 static ec_eepromSMt ec_SM;
EasyCAT 0:543d6784d4cc 90 /** buffer for EEPROM FMMU data */
EasyCAT 0:543d6784d4cc 91 static ec_eepromFMMUt ec_FMMU;
EasyCAT 0:543d6784d4cc 92 /** Global variable TRUE if error available in error stack */
EasyCAT 0:543d6784d4cc 93 boolean EcatError = FALSE;
EasyCAT 0:543d6784d4cc 94
EasyCAT 0:543d6784d4cc 95 int64 ec_DCtime;
EasyCAT 0:543d6784d4cc 96
EasyCAT 0:543d6784d4cc 97 ecx_portt ecx_port;
EasyCAT 0:543d6784d4cc 98 ecx_redportt ecx_redport;
EasyCAT 0:543d6784d4cc 99
EasyCAT 0:543d6784d4cc 100 ecx_contextt ecx_context = {
EasyCAT 0:543d6784d4cc 101 &ecx_port, // .port =
EasyCAT 0:543d6784d4cc 102 &ec_slave[0], // .slavelist =
EasyCAT 0:543d6784d4cc 103 &ec_slavecount, // .slavecount =
EasyCAT 0:543d6784d4cc 104 EC_MAXSLAVE, // .maxslave =
EasyCAT 0:543d6784d4cc 105 &ec_group[0], // .grouplist =
EasyCAT 0:543d6784d4cc 106 EC_MAXGROUP, // .maxgroup =
EasyCAT 0:543d6784d4cc 107 &ec_esibuf[0], // .esibuf =
EasyCAT 0:543d6784d4cc 108 &ec_esimap[0], // .esimap =
EasyCAT 0:543d6784d4cc 109 0, // .esislave =
EasyCAT 0:543d6784d4cc 110 &ec_elist, // .elist =
EasyCAT 0:543d6784d4cc 111 &ec_idxstack, // .idxstack =
EasyCAT 0:543d6784d4cc 112 &EcatError, // .ecaterror =
EasyCAT 0:543d6784d4cc 113 0, // .DCtO =
EasyCAT 0:543d6784d4cc 114 0, // .DCl =
EasyCAT 0:543d6784d4cc 115 &ec_DCtime, // .DCtime =
EasyCAT 0:543d6784d4cc 116 &ec_SMcommtype[0], // .SMcommtype =
EasyCAT 0:543d6784d4cc 117 &ec_PDOassign[0], // .PDOassign =
EasyCAT 0:543d6784d4cc 118 &ec_PDOdesc[0], // .PDOdesc =
EasyCAT 0:543d6784d4cc 119 &ec_SM, // .eepSM =
EasyCAT 0:543d6784d4cc 120 &ec_FMMU, // .eepFMMU =
EasyCAT 0:543d6784d4cc 121 NULL, // .FOEhook()
EasyCAT 0:543d6784d4cc 122 NULL // .EOEhook()
EasyCAT 0:543d6784d4cc 123 };
EasyCAT 0:543d6784d4cc 124 #endif
EasyCAT 0:543d6784d4cc 125
EasyCAT 0:543d6784d4cc 126 /** Create list over available network adapters.
EasyCAT 0:543d6784d4cc 127 *
EasyCAT 0:543d6784d4cc 128 * @return First element in list over available network adapters.
EasyCAT 0:543d6784d4cc 129 */
EasyCAT 0:543d6784d4cc 130 ec_adaptert * ec_find_adapters (void)
EasyCAT 0:543d6784d4cc 131 {
EasyCAT 0:543d6784d4cc 132 ec_adaptert * ret_adapter;
EasyCAT 0:543d6784d4cc 133
EasyCAT 0:543d6784d4cc 134 ret_adapter = oshw_find_adapters ();
EasyCAT 0:543d6784d4cc 135
EasyCAT 0:543d6784d4cc 136 return ret_adapter;
EasyCAT 0:543d6784d4cc 137 }
EasyCAT 0:543d6784d4cc 138
EasyCAT 0:543d6784d4cc 139 /** Free dynamically allocated list over available network adapters.
EasyCAT 0:543d6784d4cc 140 *
EasyCAT 0:543d6784d4cc 141 * @param[in] adapter = Struct holding adapter name, description and pointer to next.
EasyCAT 0:543d6784d4cc 142 */
EasyCAT 0:543d6784d4cc 143 void ec_free_adapters (ec_adaptert * adapter)
EasyCAT 0:543d6784d4cc 144 {
EasyCAT 0:543d6784d4cc 145 oshw_free_adapters (adapter);
EasyCAT 0:543d6784d4cc 146 }
EasyCAT 0:543d6784d4cc 147
EasyCAT 0:543d6784d4cc 148 /** Pushes an error on the error list.
EasyCAT 0:543d6784d4cc 149 *
EasyCAT 0:543d6784d4cc 150 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 151 * @param[in] Ec pointer describing the error.
EasyCAT 0:543d6784d4cc 152 */
EasyCAT 0:543d6784d4cc 153 void ecx_pusherror(ecx_contextt *context, const ec_errort *Ec)
EasyCAT 0:543d6784d4cc 154 {
EasyCAT 0:543d6784d4cc 155 context->elist->Error[context->elist->head] = *Ec;
EasyCAT 0:543d6784d4cc 156 context->elist->Error[context->elist->head].Signal = TRUE;
EasyCAT 0:543d6784d4cc 157 context->elist->head++;
EasyCAT 0:543d6784d4cc 158 if (context->elist->head > EC_MAXELIST)
EasyCAT 0:543d6784d4cc 159 {
EasyCAT 0:543d6784d4cc 160 context->elist->head = 0;
EasyCAT 0:543d6784d4cc 161 }
EasyCAT 0:543d6784d4cc 162 if (context->elist->head == context->elist->tail)
EasyCAT 0:543d6784d4cc 163 {
EasyCAT 0:543d6784d4cc 164 context->elist->tail++;
EasyCAT 0:543d6784d4cc 165 }
EasyCAT 0:543d6784d4cc 166 if (context->elist->tail > EC_MAXELIST)
EasyCAT 0:543d6784d4cc 167 {
EasyCAT 0:543d6784d4cc 168 context->elist->tail = 0;
EasyCAT 0:543d6784d4cc 169 }
EasyCAT 0:543d6784d4cc 170 *(context->ecaterror) = TRUE;
EasyCAT 0:543d6784d4cc 171 }
EasyCAT 0:543d6784d4cc 172
EasyCAT 0:543d6784d4cc 173 /** Pops an error from the list.
EasyCAT 0:543d6784d4cc 174 *
EasyCAT 0:543d6784d4cc 175 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 176 * @param[out] Ec = Struct describing the error.
EasyCAT 0:543d6784d4cc 177 * @return TRUE if an error was popped.
EasyCAT 0:543d6784d4cc 178 */
EasyCAT 0:543d6784d4cc 179 boolean ecx_poperror(ecx_contextt *context, ec_errort *Ec)
EasyCAT 0:543d6784d4cc 180 {
EasyCAT 0:543d6784d4cc 181 boolean notEmpty = (context->elist->head != context->elist->tail);
EasyCAT 0:543d6784d4cc 182
EasyCAT 0:543d6784d4cc 183 *Ec = context->elist->Error[context->elist->tail];
EasyCAT 0:543d6784d4cc 184 context->elist->Error[context->elist->tail].Signal = FALSE;
EasyCAT 0:543d6784d4cc 185 if (notEmpty)
EasyCAT 0:543d6784d4cc 186 {
EasyCAT 0:543d6784d4cc 187 context->elist->tail++;
EasyCAT 0:543d6784d4cc 188 if (context->elist->tail > EC_MAXELIST)
EasyCAT 0:543d6784d4cc 189 {
EasyCAT 0:543d6784d4cc 190 context->elist->tail = 0;
EasyCAT 0:543d6784d4cc 191 }
EasyCAT 0:543d6784d4cc 192 }
EasyCAT 0:543d6784d4cc 193 else
EasyCAT 0:543d6784d4cc 194 {
EasyCAT 0:543d6784d4cc 195 *(context->ecaterror) = FALSE;
EasyCAT 0:543d6784d4cc 196 }
EasyCAT 0:543d6784d4cc 197 return notEmpty;
EasyCAT 0:543d6784d4cc 198 }
EasyCAT 0:543d6784d4cc 199
EasyCAT 0:543d6784d4cc 200 /** Check if error list has entries.
EasyCAT 0:543d6784d4cc 201 *
EasyCAT 0:543d6784d4cc 202 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 203 * @return TRUE if error list contains entries.
EasyCAT 0:543d6784d4cc 204 */
EasyCAT 0:543d6784d4cc 205 boolean ecx_iserror(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 206 {
EasyCAT 0:543d6784d4cc 207 return (context->elist->head != context->elist->tail);
EasyCAT 0:543d6784d4cc 208 }
EasyCAT 0:543d6784d4cc 209
EasyCAT 0:543d6784d4cc 210 /** Report packet error
EasyCAT 0:543d6784d4cc 211 *
EasyCAT 0:543d6784d4cc 212 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 213 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 214 * @param[in] Index = Index that generated error
EasyCAT 0:543d6784d4cc 215 * @param[in] SubIdx = Subindex that generated error
EasyCAT 0:543d6784d4cc 216 * @param[in] ErrorCode = Error code
EasyCAT 0:543d6784d4cc 217 */
EasyCAT 0:543d6784d4cc 218 void ecx_packeterror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode)
EasyCAT 0:543d6784d4cc 219 {
EasyCAT 0:543d6784d4cc 220 ec_errort Ec;
EasyCAT 0:543d6784d4cc 221
EasyCAT 0:543d6784d4cc 222 memset(&Ec, 0, sizeof(Ec));
EasyCAT 0:543d6784d4cc 223 Ec.Time = osal_current_time();
EasyCAT 0:543d6784d4cc 224 Ec.Slave = Slave;
EasyCAT 0:543d6784d4cc 225 Ec.Index = Index;
EasyCAT 0:543d6784d4cc 226 Ec.SubIdx = SubIdx;
EasyCAT 0:543d6784d4cc 227 *(context->ecaterror) = TRUE;
EasyCAT 0:543d6784d4cc 228 Ec.Etype = EC_ERR_TYPE_PACKET_ERROR;
EasyCAT 0:543d6784d4cc 229 Ec.ErrorCode = ErrorCode;
EasyCAT 0:543d6784d4cc 230 ecx_pusherror(context, &Ec);
EasyCAT 0:543d6784d4cc 231 }
EasyCAT 0:543d6784d4cc 232
EasyCAT 0:543d6784d4cc 233 /** Report Mailbox Error
EasyCAT 0:543d6784d4cc 234 *
EasyCAT 0:543d6784d4cc 235 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 236 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 237 * @param[in] Detail = Following EtherCAT specification
EasyCAT 0:543d6784d4cc 238 */
EasyCAT 0:543d6784d4cc 239 static void ecx_mbxerror(ecx_contextt *context, uint16 Slave,uint16 Detail)
EasyCAT 0:543d6784d4cc 240 {
EasyCAT 0:543d6784d4cc 241 ec_errort Ec;
EasyCAT 0:543d6784d4cc 242
EasyCAT 0:543d6784d4cc 243 memset(&Ec, 0, sizeof(Ec));
EasyCAT 0:543d6784d4cc 244 Ec.Time = osal_current_time();
EasyCAT 0:543d6784d4cc 245 Ec.Slave = Slave;
EasyCAT 0:543d6784d4cc 246 Ec.Index = 0;
EasyCAT 0:543d6784d4cc 247 Ec.SubIdx = 0;
EasyCAT 0:543d6784d4cc 248 Ec.Etype = EC_ERR_TYPE_MBX_ERROR;
EasyCAT 0:543d6784d4cc 249 Ec.ErrorCode = Detail;
EasyCAT 0:543d6784d4cc 250 ecx_pusherror(context, &Ec);
EasyCAT 0:543d6784d4cc 251 }
EasyCAT 0:543d6784d4cc 252
EasyCAT 0:543d6784d4cc 253 /** Report Mailbox Emergency Error
EasyCAT 0:543d6784d4cc 254 *
EasyCAT 0:543d6784d4cc 255 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 256 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 257 * @param[in] ErrorCode = Following EtherCAT specification
EasyCAT 0:543d6784d4cc 258 * @param[in] ErrorReg
EasyCAT 0:543d6784d4cc 259 * @param[in] b1
EasyCAT 0:543d6784d4cc 260 * @param[in] w1
EasyCAT 0:543d6784d4cc 261 * @param[in] w2
EasyCAT 0:543d6784d4cc 262 */
EasyCAT 0:543d6784d4cc 263 static void ecx_mbxemergencyerror(ecx_contextt *context, uint16 Slave,uint16 ErrorCode,uint16 ErrorReg,
EasyCAT 0:543d6784d4cc 264 uint8 b1, uint16 w1, uint16 w2)
EasyCAT 0:543d6784d4cc 265 {
EasyCAT 0:543d6784d4cc 266 ec_errort Ec;
EasyCAT 0:543d6784d4cc 267
EasyCAT 0:543d6784d4cc 268 memset(&Ec, 0, sizeof(Ec));
EasyCAT 0:543d6784d4cc 269 Ec.Time = osal_current_time();
EasyCAT 0:543d6784d4cc 270 Ec.Slave = Slave;
EasyCAT 0:543d6784d4cc 271 Ec.Index = 0;
EasyCAT 0:543d6784d4cc 272 Ec.SubIdx = 0;
EasyCAT 0:543d6784d4cc 273 Ec.Etype = EC_ERR_TYPE_EMERGENCY;
EasyCAT 0:543d6784d4cc 274 Ec.ErrorCode = ErrorCode;
EasyCAT 0:543d6784d4cc 275 Ec.ErrorReg = (uint8)ErrorReg;
EasyCAT 0:543d6784d4cc 276 Ec.b1 = b1;
EasyCAT 0:543d6784d4cc 277 Ec.w1 = w1;
EasyCAT 0:543d6784d4cc 278 Ec.w2 = w2;
EasyCAT 0:543d6784d4cc 279 ecx_pusherror(context, &Ec);
EasyCAT 0:543d6784d4cc 280 }
EasyCAT 0:543d6784d4cc 281
EasyCAT 0:543d6784d4cc 282 /** Initialise lib in single NIC mode
EasyCAT 0:543d6784d4cc 283 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 284 * @param[in] ifname = Dev name, f.e. "eth0"
EasyCAT 0:543d6784d4cc 285 * @return >0 if OK
EasyCAT 0:543d6784d4cc 286 */
EasyCAT 0:543d6784d4cc 287 int ecx_init(ecx_contextt *context, const char * ifname)
EasyCAT 0:543d6784d4cc 288 {
EasyCAT 0:543d6784d4cc 289 return ecx_setupnic(context->port, ifname, FALSE);
EasyCAT 0:543d6784d4cc 290 }
EasyCAT 0:543d6784d4cc 291
EasyCAT 0:543d6784d4cc 292 /** Initialise lib in redundant NIC mode
EasyCAT 0:543d6784d4cc 293 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 294 * @param[in] redport = pointer to redport, redundant port data
EasyCAT 0:543d6784d4cc 295 * @param[in] ifname = Primary Dev name, f.e. "eth0"
EasyCAT 0:543d6784d4cc 296 * @param[in] if2name = Secondary Dev name, f.e. "eth1"
EasyCAT 0:543d6784d4cc 297 * @return >0 if OK
EasyCAT 0:543d6784d4cc 298 */
EasyCAT 0:543d6784d4cc 299 int ecx_init_redundant(ecx_contextt *context, ecx_redportt *redport, const char *ifname, char *if2name)
EasyCAT 0:543d6784d4cc 300 {
EasyCAT 0:543d6784d4cc 301 int rval, zbuf;
EasyCAT 0:543d6784d4cc 302 ec_etherheadert *ehp;
EasyCAT 0:543d6784d4cc 303
EasyCAT 0:543d6784d4cc 304 context->port->redport = redport;
EasyCAT 0:543d6784d4cc 305 ecx_setupnic(context->port, ifname, FALSE);
EasyCAT 0:543d6784d4cc 306 rval = ecx_setupnic(context->port, if2name, TRUE);
EasyCAT 0:543d6784d4cc 307 /* prepare "dummy" BRD tx frame for redundant operation */
EasyCAT 0:543d6784d4cc 308 ehp = (ec_etherheadert *)&(context->port->txbuf2);
EasyCAT 0:543d6784d4cc 309 ehp->sa1 = oshw_htons(secMAC[0]);
EasyCAT 0:543d6784d4cc 310 zbuf = 0;
EasyCAT 0:543d6784d4cc 311 ecx_setupdatagram(context->port, &(context->port->txbuf2), EC_CMD_BRD, 0, 0x0000, 0x0000, 2, &zbuf);
EasyCAT 0:543d6784d4cc 312 context->port->txbuflength2 = ETH_HEADERSIZE + EC_HEADERSIZE + EC_WKCSIZE + 2;
EasyCAT 0:543d6784d4cc 313
EasyCAT 0:543d6784d4cc 314 return rval;
EasyCAT 0:543d6784d4cc 315 }
EasyCAT 0:543d6784d4cc 316
EasyCAT 0:543d6784d4cc 317 /** Close lib.
EasyCAT 0:543d6784d4cc 318 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 319 */
EasyCAT 0:543d6784d4cc 320 void ecx_close(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 321 {
EasyCAT 0:543d6784d4cc 322 ecx_closenic(context->port);
EasyCAT 0:543d6784d4cc 323 };
EasyCAT 0:543d6784d4cc 324
EasyCAT 0:543d6784d4cc 325 /** Read one byte from slave EEPROM via cache.
EasyCAT 0:543d6784d4cc 326 * If the cache location is empty then a read request is made to the slave.
EasyCAT 0:543d6784d4cc 327 * Depending on the slave capabilities the request is 4 or 8 bytes.
EasyCAT 0:543d6784d4cc 328 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 329 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 330 * @param[in] address = eeprom address in bytes (slave uses words)
EasyCAT 0:543d6784d4cc 331 * @return requested byte, if not available then 0xff
EasyCAT 0:543d6784d4cc 332 */
EasyCAT 0:543d6784d4cc 333 uint8 ecx_siigetbyte(ecx_contextt *context, uint16 slave, uint16 address)
EasyCAT 0:543d6784d4cc 334 {
EasyCAT 0:543d6784d4cc 335 uint16 configadr, eadr;
EasyCAT 0:543d6784d4cc 336 uint64 edat64;
EasyCAT 0:543d6784d4cc 337 uint32 edat32;
EasyCAT 0:543d6784d4cc 338 uint16 mapw, mapb;
EasyCAT 0:543d6784d4cc 339 int lp,cnt;
EasyCAT 0:543d6784d4cc 340 uint8 retval;
EasyCAT 0:543d6784d4cc 341
EasyCAT 0:543d6784d4cc 342 retval = 0xff;
EasyCAT 0:543d6784d4cc 343 if (slave != context->esislave) /* not the same slave? */
EasyCAT 0:543d6784d4cc 344 {
EasyCAT 0:543d6784d4cc 345 memset(context->esimap, 0x00, EC_MAXEEPBITMAP * sizeof(uint32)); /* clear esibuf cache map */
EasyCAT 0:543d6784d4cc 346 context->esislave = slave;
EasyCAT 0:543d6784d4cc 347 }
EasyCAT 0:543d6784d4cc 348 if (address < EC_MAXEEPBUF)
EasyCAT 0:543d6784d4cc 349 {
EasyCAT 0:543d6784d4cc 350 mapw = address >> 5;
EasyCAT 0:543d6784d4cc 351 mapb = address - (mapw << 5);
EasyCAT 0:543d6784d4cc 352 if (context->esimap[mapw] & (uint32)(1 << mapb))
EasyCAT 0:543d6784d4cc 353 {
EasyCAT 0:543d6784d4cc 354 /* byte is already in buffer */
EasyCAT 0:543d6784d4cc 355 retval = context->esibuf[address];
EasyCAT 0:543d6784d4cc 356 }
EasyCAT 0:543d6784d4cc 357 else
EasyCAT 0:543d6784d4cc 358 {
EasyCAT 0:543d6784d4cc 359 /* byte is not in buffer, put it there */
EasyCAT 0:543d6784d4cc 360 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 361 ecx_eeprom2master(context, slave); /* set eeprom control to master */
EasyCAT 0:543d6784d4cc 362 eadr = address >> 1;
EasyCAT 0:543d6784d4cc 363 edat64 = ecx_readeepromFP (context, configadr, eadr, EC_TIMEOUTEEP);
EasyCAT 0:543d6784d4cc 364 /* 8 byte response */
EasyCAT 0:543d6784d4cc 365 if (context->slavelist[slave].eep_8byte)
EasyCAT 0:543d6784d4cc 366 {
EasyCAT 0:543d6784d4cc 367 put_unaligned64(edat64, &(context->esibuf[eadr << 1]));
EasyCAT 0:543d6784d4cc 368 cnt = 8;
EasyCAT 0:543d6784d4cc 369 }
EasyCAT 0:543d6784d4cc 370 /* 4 byte response */
EasyCAT 0:543d6784d4cc 371 else
EasyCAT 0:543d6784d4cc 372 {
EasyCAT 0:543d6784d4cc 373 edat32 = (uint32)edat64;
EasyCAT 0:543d6784d4cc 374 put_unaligned32(edat32, &(context->esibuf[eadr << 1]));
EasyCAT 0:543d6784d4cc 375 cnt = 4;
EasyCAT 0:543d6784d4cc 376 }
EasyCAT 0:543d6784d4cc 377 /* find bitmap location */
EasyCAT 0:543d6784d4cc 378 mapw = eadr >> 4;
EasyCAT 0:543d6784d4cc 379 mapb = (eadr << 1) - (mapw << 5);
EasyCAT 0:543d6784d4cc 380 for(lp = 0 ; lp < cnt ; lp++)
EasyCAT 0:543d6784d4cc 381 {
EasyCAT 0:543d6784d4cc 382 /* set bitmap for each byte that is read */
EasyCAT 0:543d6784d4cc 383 context->esimap[mapw] |= (1 << mapb);
EasyCAT 0:543d6784d4cc 384 mapb++;
EasyCAT 0:543d6784d4cc 385 if (mapb > 31)
EasyCAT 0:543d6784d4cc 386 {
EasyCAT 0:543d6784d4cc 387 mapb = 0;
EasyCAT 0:543d6784d4cc 388 mapw++;
EasyCAT 0:543d6784d4cc 389 }
EasyCAT 0:543d6784d4cc 390 }
EasyCAT 0:543d6784d4cc 391 retval = context->esibuf[address];
EasyCAT 0:543d6784d4cc 392 }
EasyCAT 0:543d6784d4cc 393 }
EasyCAT 0:543d6784d4cc 394
EasyCAT 0:543d6784d4cc 395 return retval;
EasyCAT 0:543d6784d4cc 396 }
EasyCAT 0:543d6784d4cc 397
EasyCAT 0:543d6784d4cc 398 /** Find SII section header in slave EEPROM.
EasyCAT 0:543d6784d4cc 399 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 400 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 401 * @param[in] cat = section category
EasyCAT 0:543d6784d4cc 402 * @return byte address of section at section length entry, if not available then 0
EasyCAT 0:543d6784d4cc 403 */
EasyCAT 0:543d6784d4cc 404 int16 ecx_siifind(ecx_contextt *context, uint16 slave, uint16 cat)
EasyCAT 0:543d6784d4cc 405 {
EasyCAT 0:543d6784d4cc 406 int16 a;
EasyCAT 0:543d6784d4cc 407 uint16 p;
EasyCAT 0:543d6784d4cc 408 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 409
EasyCAT 0:543d6784d4cc 410 a = ECT_SII_START << 1;
EasyCAT 0:543d6784d4cc 411 /* read first SII section category */
EasyCAT 0:543d6784d4cc 412 p = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 413 p += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 414 /* traverse SII while category is not found and not EOF */
EasyCAT 0:543d6784d4cc 415 while ((p != cat) && (p != 0xffff))
EasyCAT 0:543d6784d4cc 416 {
EasyCAT 0:543d6784d4cc 417 /* read section length */
EasyCAT 0:543d6784d4cc 418 p = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 419 p += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 420 /* locate next section category */
EasyCAT 0:543d6784d4cc 421 a += p << 1;
EasyCAT 0:543d6784d4cc 422 /* read section category */
EasyCAT 0:543d6784d4cc 423 p = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 424 p += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 425 }
EasyCAT 0:543d6784d4cc 426 if (p != cat)
EasyCAT 0:543d6784d4cc 427 {
EasyCAT 0:543d6784d4cc 428 a = 0;
EasyCAT 0:543d6784d4cc 429 }
EasyCAT 0:543d6784d4cc 430 if (eectl)
EasyCAT 0:543d6784d4cc 431 {
EasyCAT 0:543d6784d4cc 432 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 433 }
EasyCAT 0:543d6784d4cc 434
EasyCAT 0:543d6784d4cc 435 return a;
EasyCAT 0:543d6784d4cc 436 }
EasyCAT 0:543d6784d4cc 437
EasyCAT 0:543d6784d4cc 438 /** Get string from SII string section in slave EEPROM.
EasyCAT 0:543d6784d4cc 439 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 440 * @param[out] str = requested string, 0x00 if not found
EasyCAT 0:543d6784d4cc 441 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 442 * @param[in] Sn = string number
EasyCAT 0:543d6784d4cc 443 */
EasyCAT 0:543d6784d4cc 444 void ecx_siistring(ecx_contextt *context, char *str, uint16 slave, uint16 Sn)
EasyCAT 0:543d6784d4cc 445 {
EasyCAT 0:543d6784d4cc 446 uint16 a,i,j,l,n,ba;
EasyCAT 0:543d6784d4cc 447 char *ptr;
EasyCAT 0:543d6784d4cc 448 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 449
EasyCAT 0:543d6784d4cc 450 ptr = str;
EasyCAT 0:543d6784d4cc 451 a = ecx_siifind (context, slave, ECT_SII_STRING); /* find string section */
EasyCAT 0:543d6784d4cc 452 if (a > 0)
EasyCAT 0:543d6784d4cc 453 {
EasyCAT 0:543d6784d4cc 454 ba = a + 2; /* skip SII section header */
EasyCAT 0:543d6784d4cc 455 n = ecx_siigetbyte(context, slave, ba++); /* read number of strings in section */
EasyCAT 0:543d6784d4cc 456 if (Sn <= n) /* is req string available? */
EasyCAT 0:543d6784d4cc 457 {
EasyCAT 0:543d6784d4cc 458 for (i = 1; i <= Sn; i++) /* walk through strings */
EasyCAT 0:543d6784d4cc 459 {
EasyCAT 0:543d6784d4cc 460 l = ecx_siigetbyte(context, slave, ba++); /* length of this string */
EasyCAT 0:543d6784d4cc 461 if (i < Sn)
EasyCAT 0:543d6784d4cc 462 {
EasyCAT 0:543d6784d4cc 463 ba += l;
EasyCAT 0:543d6784d4cc 464 }
EasyCAT 0:543d6784d4cc 465 else
EasyCAT 0:543d6784d4cc 466 {
EasyCAT 0:543d6784d4cc 467 ptr = str;
EasyCAT 0:543d6784d4cc 468 for (j = 1; j <= l; j++) /* copy one string */
EasyCAT 0:543d6784d4cc 469 {
EasyCAT 0:543d6784d4cc 470 if(j <= EC_MAXNAME)
EasyCAT 0:543d6784d4cc 471 {
EasyCAT 0:543d6784d4cc 472 *ptr = (char)ecx_siigetbyte(context, slave, ba++);
EasyCAT 0:543d6784d4cc 473 ptr++;
EasyCAT 0:543d6784d4cc 474 }
EasyCAT 0:543d6784d4cc 475 else
EasyCAT 0:543d6784d4cc 476 {
EasyCAT 0:543d6784d4cc 477 ba++;
EasyCAT 0:543d6784d4cc 478 }
EasyCAT 0:543d6784d4cc 479 }
EasyCAT 0:543d6784d4cc 480 }
EasyCAT 0:543d6784d4cc 481 }
EasyCAT 0:543d6784d4cc 482 *ptr = 0; /* add zero terminator */
EasyCAT 0:543d6784d4cc 483 }
EasyCAT 0:543d6784d4cc 484 else
EasyCAT 0:543d6784d4cc 485 {
EasyCAT 0:543d6784d4cc 486 ptr = str;
EasyCAT 0:543d6784d4cc 487 *ptr = 0; /* empty string */
EasyCAT 0:543d6784d4cc 488 }
EasyCAT 0:543d6784d4cc 489 }
EasyCAT 0:543d6784d4cc 490 if (eectl)
EasyCAT 0:543d6784d4cc 491 {
EasyCAT 0:543d6784d4cc 492 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 493 }
EasyCAT 0:543d6784d4cc 494 }
EasyCAT 0:543d6784d4cc 495
EasyCAT 0:543d6784d4cc 496 /** Get FMMU data from SII FMMU section in slave EEPROM.
EasyCAT 0:543d6784d4cc 497 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 498 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 499 * @param[out] FMMU = FMMU struct from SII, max. 4 FMMU's
EasyCAT 0:543d6784d4cc 500 * @return number of FMMU's defined in section
EasyCAT 0:543d6784d4cc 501 */
EasyCAT 0:543d6784d4cc 502 uint16 ecx_siiFMMU(ecx_contextt *context, uint16 slave, ec_eepromFMMUt* FMMU)
EasyCAT 0:543d6784d4cc 503 {
EasyCAT 0:543d6784d4cc 504 uint16 a;
EasyCAT 0:543d6784d4cc 505 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 506
EasyCAT 0:543d6784d4cc 507 FMMU->nFMMU = 0;
EasyCAT 0:543d6784d4cc 508 FMMU->FMMU0 = 0;
EasyCAT 0:543d6784d4cc 509 FMMU->FMMU1 = 0;
EasyCAT 0:543d6784d4cc 510 FMMU->FMMU2 = 0;
EasyCAT 0:543d6784d4cc 511 FMMU->FMMU3 = 0;
EasyCAT 0:543d6784d4cc 512 FMMU->Startpos = ecx_siifind(context, slave, ECT_SII_FMMU);
EasyCAT 0:543d6784d4cc 513
EasyCAT 0:543d6784d4cc 514 if (FMMU->Startpos > 0)
EasyCAT 0:543d6784d4cc 515 {
EasyCAT 0:543d6784d4cc 516 a = FMMU->Startpos;
EasyCAT 0:543d6784d4cc 517 FMMU->nFMMU = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 518 FMMU->nFMMU += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 519 FMMU->nFMMU *= 2;
EasyCAT 0:543d6784d4cc 520 FMMU->FMMU0 = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 521 FMMU->FMMU1 = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 522 if (FMMU->nFMMU > 2)
EasyCAT 0:543d6784d4cc 523 {
EasyCAT 0:543d6784d4cc 524 FMMU->FMMU2 = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 525 FMMU->FMMU3 = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 526 }
EasyCAT 0:543d6784d4cc 527 }
EasyCAT 0:543d6784d4cc 528 if (eectl)
EasyCAT 0:543d6784d4cc 529 {
EasyCAT 0:543d6784d4cc 530 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 531 }
EasyCAT 0:543d6784d4cc 532
EasyCAT 0:543d6784d4cc 533 return FMMU->nFMMU;
EasyCAT 0:543d6784d4cc 534 }
EasyCAT 0:543d6784d4cc 535
EasyCAT 0:543d6784d4cc 536 /** Get SM data from SII SM section in slave EEPROM.
EasyCAT 0:543d6784d4cc 537 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 538 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 539 * @param[out] SM = first SM struct from SII
EasyCAT 0:543d6784d4cc 540 * @return number of SM's defined in section
EasyCAT 0:543d6784d4cc 541 */
EasyCAT 0:543d6784d4cc 542 uint16 ecx_siiSM(ecx_contextt *context, uint16 slave, ec_eepromSMt* SM)
EasyCAT 0:543d6784d4cc 543 {
EasyCAT 0:543d6784d4cc 544 uint16 a,w;
EasyCAT 0:543d6784d4cc 545 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 546
EasyCAT 0:543d6784d4cc 547 SM->nSM = 0;
EasyCAT 0:543d6784d4cc 548 SM->Startpos = ecx_siifind(context, slave, ECT_SII_SM);
EasyCAT 0:543d6784d4cc 549 if (SM->Startpos > 0)
EasyCAT 0:543d6784d4cc 550 {
EasyCAT 0:543d6784d4cc 551 a = SM->Startpos;
EasyCAT 0:543d6784d4cc 552 w = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 553 w += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 554 SM->nSM = (w / 4);
EasyCAT 0:543d6784d4cc 555 SM->PhStart = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 556 SM->PhStart += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 557 SM->Plength = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 558 SM->Plength += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 559 SM->Creg = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 560 SM->Sreg = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 561 SM->Activate = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 562 SM->PDIctrl = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 563 }
EasyCAT 0:543d6784d4cc 564 if (eectl)
EasyCAT 0:543d6784d4cc 565 {
EasyCAT 0:543d6784d4cc 566 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 567 }
EasyCAT 0:543d6784d4cc 568
EasyCAT 0:543d6784d4cc 569 return SM->nSM;
EasyCAT 0:543d6784d4cc 570 }
EasyCAT 0:543d6784d4cc 571
EasyCAT 0:543d6784d4cc 572 /** Get next SM data from SII SM section in slave EEPROM.
EasyCAT 0:543d6784d4cc 573 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 574 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 575 * @param[out] SM = first SM struct from SII
EasyCAT 0:543d6784d4cc 576 * @param[in] n = SM number
EasyCAT 0:543d6784d4cc 577 * @return >0 if OK
EasyCAT 0:543d6784d4cc 578 */
EasyCAT 0:543d6784d4cc 579 uint16 ecx_siiSMnext(ecx_contextt *context, uint16 slave, ec_eepromSMt* SM, uint16 n)
EasyCAT 0:543d6784d4cc 580 {
EasyCAT 0:543d6784d4cc 581 uint16 a;
EasyCAT 0:543d6784d4cc 582 uint16 retVal = 0;
EasyCAT 0:543d6784d4cc 583 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 584
EasyCAT 0:543d6784d4cc 585 if (n < SM->nSM)
EasyCAT 0:543d6784d4cc 586 {
EasyCAT 0:543d6784d4cc 587 a = SM->Startpos + 2 + (n * 8);
EasyCAT 0:543d6784d4cc 588 SM->PhStart = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 589 SM->PhStart += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 590 SM->Plength = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 591 SM->Plength += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 592 SM->Creg = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 593 SM->Sreg = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 594 SM->Activate = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 595 SM->PDIctrl = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 596 retVal = 1;
EasyCAT 0:543d6784d4cc 597 }
EasyCAT 0:543d6784d4cc 598 if (eectl)
EasyCAT 0:543d6784d4cc 599 {
EasyCAT 0:543d6784d4cc 600 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 601 }
EasyCAT 0:543d6784d4cc 602
EasyCAT 0:543d6784d4cc 603 return retVal;
EasyCAT 0:543d6784d4cc 604 }
EasyCAT 0:543d6784d4cc 605
EasyCAT 0:543d6784d4cc 606 /** Get PDO data from SII PDO section in slave EEPROM.
EasyCAT 0:543d6784d4cc 607 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 608 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 609 * @param[out] PDO = PDO struct from SII
EasyCAT 0:543d6784d4cc 610 * @param[in] t = 0=RXPDO 1=TXPDO
EasyCAT 0:543d6784d4cc 611 * @return mapping size in bits of PDO
EasyCAT 0:543d6784d4cc 612 */
EasyCAT 0:543d6784d4cc 613 int ecx_siiPDO(ecx_contextt *context, uint16 slave, ec_eepromPDOt* PDO, uint8 t)
EasyCAT 0:543d6784d4cc 614 {
EasyCAT 0:543d6784d4cc 615 uint16 a , w, c, e, er, Size;
EasyCAT 0:543d6784d4cc 616 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 617
EasyCAT 0:543d6784d4cc 618 Size = 0;
EasyCAT 0:543d6784d4cc 619 PDO->nPDO = 0;
EasyCAT 0:543d6784d4cc 620 PDO->Length = 0;
EasyCAT 0:543d6784d4cc 621 PDO->Index[1] = 0;
EasyCAT 0:543d6784d4cc 622 for (c = 0 ; c < EC_MAXSM ; c++) PDO->SMbitsize[c] = 0;
EasyCAT 0:543d6784d4cc 623 if (t > 1)
EasyCAT 0:543d6784d4cc 624 t = 1;
EasyCAT 0:543d6784d4cc 625 PDO->Startpos = ecx_siifind(context, slave, ECT_SII_PDO + t);
EasyCAT 0:543d6784d4cc 626 if (PDO->Startpos > 0)
EasyCAT 0:543d6784d4cc 627 {
EasyCAT 0:543d6784d4cc 628 a = PDO->Startpos;
EasyCAT 0:543d6784d4cc 629 w = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 630 w += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 631 PDO->Length = w;
EasyCAT 0:543d6784d4cc 632 c = 1;
EasyCAT 0:543d6784d4cc 633 /* traverse through all PDOs */
EasyCAT 0:543d6784d4cc 634 do
EasyCAT 0:543d6784d4cc 635 {
EasyCAT 0:543d6784d4cc 636 PDO->nPDO++;
EasyCAT 0:543d6784d4cc 637 PDO->Index[PDO->nPDO] = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 638 PDO->Index[PDO->nPDO] += (ecx_siigetbyte(context, slave, a++) << 8);
EasyCAT 0:543d6784d4cc 639 PDO->BitSize[PDO->nPDO] = 0;
EasyCAT 0:543d6784d4cc 640 c++;
EasyCAT 0:543d6784d4cc 641 e = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 642 PDO->SyncM[PDO->nPDO] = ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 643 a += 4;
EasyCAT 0:543d6784d4cc 644 c += 2;
EasyCAT 0:543d6784d4cc 645 if (PDO->SyncM[PDO->nPDO] < EC_MAXSM) /* active and in range SM? */
EasyCAT 0:543d6784d4cc 646 {
EasyCAT 0:543d6784d4cc 647 /* read all entries defined in PDO */
EasyCAT 0:543d6784d4cc 648 for (er = 1; er <= e; er++)
EasyCAT 0:543d6784d4cc 649 {
EasyCAT 0:543d6784d4cc 650 c += 4;
EasyCAT 0:543d6784d4cc 651 a += 5;
EasyCAT 0:543d6784d4cc 652 PDO->BitSize[PDO->nPDO] += ecx_siigetbyte(context, slave, a++);
EasyCAT 0:543d6784d4cc 653 a += 2;
EasyCAT 0:543d6784d4cc 654 }
EasyCAT 0:543d6784d4cc 655 PDO->SMbitsize[ PDO->SyncM[PDO->nPDO] ] += PDO->BitSize[PDO->nPDO];
EasyCAT 0:543d6784d4cc 656 Size += PDO->BitSize[PDO->nPDO];
EasyCAT 0:543d6784d4cc 657 c++;
EasyCAT 0:543d6784d4cc 658 }
EasyCAT 0:543d6784d4cc 659 else /* PDO deactivated because SM is 0xff or > EC_MAXSM */
EasyCAT 0:543d6784d4cc 660 {
EasyCAT 0:543d6784d4cc 661 c += 4 * e;
EasyCAT 0:543d6784d4cc 662 a += 8 * e;
EasyCAT 0:543d6784d4cc 663 c++;
EasyCAT 0:543d6784d4cc 664 }
EasyCAT 0:543d6784d4cc 665 if (PDO->nPDO >= (EC_MAXEEPDO - 1))
EasyCAT 0:543d6784d4cc 666 {
EasyCAT 0:543d6784d4cc 667 c = PDO->Length; /* limit number of PDO entries in buffer */
EasyCAT 0:543d6784d4cc 668 }
EasyCAT 0:543d6784d4cc 669 }
EasyCAT 0:543d6784d4cc 670 while (c < PDO->Length);
EasyCAT 0:543d6784d4cc 671 }
EasyCAT 0:543d6784d4cc 672 if (eectl)
EasyCAT 0:543d6784d4cc 673 {
EasyCAT 0:543d6784d4cc 674 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 675 }
EasyCAT 0:543d6784d4cc 676
EasyCAT 0:543d6784d4cc 677 return (Size);
EasyCAT 0:543d6784d4cc 678 }
EasyCAT 0:543d6784d4cc 679
EasyCAT 0:543d6784d4cc 680 #define MAX_FPRD_MULTI 64
EasyCAT 0:543d6784d4cc 681
EasyCAT 0:543d6784d4cc 682 int ecx_FPRD_multi(ecx_contextt *context, int n, uint16 *configlst, ec_alstatust *slstatlst, int timeout)
EasyCAT 0:543d6784d4cc 683 {
EasyCAT 0:543d6784d4cc 684 int wkc;
EasyCAT 0:543d6784d4cc 685 uint8 idx;
EasyCAT 0:543d6784d4cc 686 ecx_portt *port;
EasyCAT 0:543d6784d4cc 687 int sldatapos[MAX_FPRD_MULTI];
EasyCAT 0:543d6784d4cc 688 int slcnt;
EasyCAT 0:543d6784d4cc 689
EasyCAT 0:543d6784d4cc 690 port = context->port;
EasyCAT 0:543d6784d4cc 691 idx = ecx_getindex(port);
EasyCAT 0:543d6784d4cc 692 slcnt = 0;
EasyCAT 0:543d6784d4cc 693 ecx_setupdatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx,
EasyCAT 0:543d6784d4cc 694 *(configlst + slcnt), ECT_REG_ALSTAT, sizeof(ec_alstatust), slstatlst + slcnt);
EasyCAT 0:543d6784d4cc 695 sldatapos[slcnt] = EC_HEADERSIZE;
EasyCAT 0:543d6784d4cc 696 while(++slcnt < (n - 1))
EasyCAT 0:543d6784d4cc 697 {
EasyCAT 0:543d6784d4cc 698 sldatapos[slcnt] = ecx_adddatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx, TRUE,
EasyCAT 0:543d6784d4cc 699 *(configlst + slcnt), ECT_REG_ALSTAT, sizeof(ec_alstatust), slstatlst + slcnt);
EasyCAT 0:543d6784d4cc 700 }
EasyCAT 0:543d6784d4cc 701 if(slcnt < n)
EasyCAT 0:543d6784d4cc 702 {
EasyCAT 0:543d6784d4cc 703 sldatapos[slcnt] = ecx_adddatagram(port, &(port->txbuf[idx]), EC_CMD_FPRD, idx, FALSE,
EasyCAT 0:543d6784d4cc 704 *(configlst + slcnt), ECT_REG_ALSTAT, sizeof(ec_alstatust), slstatlst + slcnt);
EasyCAT 0:543d6784d4cc 705 }
EasyCAT 0:543d6784d4cc 706 wkc = ecx_srconfirm(port, idx, timeout);
EasyCAT 0:543d6784d4cc 707 if (wkc >= 0)
EasyCAT 0:543d6784d4cc 708 {
EasyCAT 0:543d6784d4cc 709 for(slcnt = 0 ; slcnt < n ; slcnt++)
EasyCAT 0:543d6784d4cc 710 {
EasyCAT 0:543d6784d4cc 711 memcpy(slstatlst + slcnt, &(port->rxbuf[idx][sldatapos[slcnt]]), sizeof(ec_alstatust));
EasyCAT 0:543d6784d4cc 712 }
EasyCAT 0:543d6784d4cc 713 }
EasyCAT 0:543d6784d4cc 714 ecx_setbufstat(port, idx, EC_BUF_EMPTY);
EasyCAT 0:543d6784d4cc 715 return wkc;
EasyCAT 0:543d6784d4cc 716 }
EasyCAT 0:543d6784d4cc 717
EasyCAT 0:543d6784d4cc 718 /** Read all slave states in ec_slave.
EasyCAT 0:543d6784d4cc 719 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 720 * @return lowest state found
EasyCAT 0:543d6784d4cc 721 */
EasyCAT 0:543d6784d4cc 722 int ecx_readstate(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 723 {
EasyCAT 0:543d6784d4cc 724 uint16 slave, fslave, lslave, configadr, lowest, rval, bitwisestate;
EasyCAT 0:543d6784d4cc 725 ec_alstatust sl[MAX_FPRD_MULTI];
EasyCAT 0:543d6784d4cc 726 uint16 slca[MAX_FPRD_MULTI];
EasyCAT 0:543d6784d4cc 727 boolean noerrorflag, allslavessamestate;
EasyCAT 0:543d6784d4cc 728 boolean allslavespresent = FALSE;
EasyCAT 0:543d6784d4cc 729 int wkc;
EasyCAT 0:543d6784d4cc 730
EasyCAT 0:543d6784d4cc 731 /* Try to establish the state of all slaves sending only one broadcast datagram.
EasyCAT 0:543d6784d4cc 732 * This way a number of datagrams equal to the number of slaves will be sent only if needed.*/
EasyCAT 0:543d6784d4cc 733 rval = 0;
EasyCAT 0:543d6784d4cc 734 wkc = ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 735
EasyCAT 0:543d6784d4cc 736 if(wkc >= *(context->slavecount))
EasyCAT 0:543d6784d4cc 737 {
EasyCAT 0:543d6784d4cc 738 allslavespresent = TRUE;
EasyCAT 0:543d6784d4cc 739 }
EasyCAT 0:543d6784d4cc 740
EasyCAT 0:543d6784d4cc 741 rval = etohs(rval);
EasyCAT 0:543d6784d4cc 742 bitwisestate = (rval & 0x0f);
EasyCAT 0:543d6784d4cc 743
EasyCAT 0:543d6784d4cc 744 if ((rval & EC_STATE_ERROR) == 0)
EasyCAT 0:543d6784d4cc 745 {
EasyCAT 0:543d6784d4cc 746 noerrorflag = TRUE;
EasyCAT 0:543d6784d4cc 747 context->slavelist[0].ALstatuscode = 0;
EasyCAT 0:543d6784d4cc 748 }
EasyCAT 0:543d6784d4cc 749 else
EasyCAT 0:543d6784d4cc 750 {
EasyCAT 0:543d6784d4cc 751 noerrorflag = FALSE;
EasyCAT 0:543d6784d4cc 752 }
EasyCAT 0:543d6784d4cc 753
EasyCAT 0:543d6784d4cc 754 switch (bitwisestate)
EasyCAT 0:543d6784d4cc 755 {
EasyCAT 0:543d6784d4cc 756 case EC_STATE_INIT:
EasyCAT 0:543d6784d4cc 757 case EC_STATE_PRE_OP:
EasyCAT 0:543d6784d4cc 758 case EC_STATE_BOOT:
EasyCAT 0:543d6784d4cc 759 case EC_STATE_SAFE_OP:
EasyCAT 0:543d6784d4cc 760 case EC_STATE_OPERATIONAL:
EasyCAT 0:543d6784d4cc 761 allslavessamestate = TRUE;
EasyCAT 0:543d6784d4cc 762 context->slavelist[0].state = bitwisestate;
EasyCAT 0:543d6784d4cc 763 break;
EasyCAT 0:543d6784d4cc 764 default:
EasyCAT 0:543d6784d4cc 765 allslavessamestate = FALSE;
EasyCAT 0:543d6784d4cc 766 break;
EasyCAT 0:543d6784d4cc 767 }
EasyCAT 0:543d6784d4cc 768
EasyCAT 0:543d6784d4cc 769 if (noerrorflag && allslavessamestate && allslavespresent)
EasyCAT 0:543d6784d4cc 770 {
EasyCAT 0:543d6784d4cc 771 /* No slave has toggled the error flag so the alstatuscode
EasyCAT 0:543d6784d4cc 772 * (even if different from 0) should be ignored and
EasyCAT 0:543d6784d4cc 773 * the slaves have reached the same state so the internal state
EasyCAT 0:543d6784d4cc 774 * can be updated without sending any datagram. */
EasyCAT 0:543d6784d4cc 775 for (slave = 1; slave <= *(context->slavecount); slave++)
EasyCAT 0:543d6784d4cc 776 {
EasyCAT 0:543d6784d4cc 777 context->slavelist[slave].ALstatuscode = 0x0000;
EasyCAT 0:543d6784d4cc 778 context->slavelist[slave].state = bitwisestate;
EasyCAT 0:543d6784d4cc 779 }
EasyCAT 0:543d6784d4cc 780 lowest = bitwisestate;
EasyCAT 0:543d6784d4cc 781 }
EasyCAT 0:543d6784d4cc 782 else
EasyCAT 0:543d6784d4cc 783 {
EasyCAT 0:543d6784d4cc 784 /* Not all slaves have the same state or at least one is in error so one datagram per slave
EasyCAT 0:543d6784d4cc 785 * is needed. */
EasyCAT 0:543d6784d4cc 786 context->slavelist[0].ALstatuscode = 0;
EasyCAT 0:543d6784d4cc 787 lowest = 0xff;
EasyCAT 0:543d6784d4cc 788 fslave = 1;
EasyCAT 0:543d6784d4cc 789 do
EasyCAT 0:543d6784d4cc 790 {
EasyCAT 0:543d6784d4cc 791 lslave = *(context->slavecount);
EasyCAT 0:543d6784d4cc 792 if ((lslave - fslave) >= MAX_FPRD_MULTI)
EasyCAT 0:543d6784d4cc 793 {
EasyCAT 0:543d6784d4cc 794 lslave = fslave + MAX_FPRD_MULTI - 1;
EasyCAT 0:543d6784d4cc 795 }
EasyCAT 0:543d6784d4cc 796 for (slave = fslave; slave <= lslave; slave++)
EasyCAT 0:543d6784d4cc 797 {
EasyCAT 0:543d6784d4cc 798 const ec_alstatust zero = { 0, 0, 0 };
EasyCAT 0:543d6784d4cc 799
EasyCAT 0:543d6784d4cc 800 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 801 slca[slave - fslave] = configadr;
EasyCAT 0:543d6784d4cc 802 sl[slave - fslave] = zero;
EasyCAT 0:543d6784d4cc 803 }
EasyCAT 0:543d6784d4cc 804 ecx_FPRD_multi(context, (lslave - fslave) + 1, &(slca[0]), &(sl[0]), EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 805 for (slave = fslave; slave <= lslave; slave++)
EasyCAT 0:543d6784d4cc 806 {
EasyCAT 0:543d6784d4cc 807 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 808 rval = etohs(sl[slave - fslave].alstatus);
EasyCAT 0:543d6784d4cc 809 context->slavelist[slave].ALstatuscode = etohs(sl[slave - fslave].alstatuscode);
EasyCAT 0:543d6784d4cc 810 if ((rval & 0xf) < lowest)
EasyCAT 0:543d6784d4cc 811 {
EasyCAT 0:543d6784d4cc 812 lowest = (rval & 0xf);
EasyCAT 0:543d6784d4cc 813 }
EasyCAT 0:543d6784d4cc 814 context->slavelist[slave].state = rval;
EasyCAT 0:543d6784d4cc 815 context->slavelist[0].ALstatuscode |= context->slavelist[slave].ALstatuscode;
EasyCAT 0:543d6784d4cc 816 }
EasyCAT 0:543d6784d4cc 817 fslave = lslave + 1;
EasyCAT 0:543d6784d4cc 818 } while (lslave < *(context->slavecount));
EasyCAT 0:543d6784d4cc 819 context->slavelist[0].state = lowest;
EasyCAT 0:543d6784d4cc 820 }
EasyCAT 0:543d6784d4cc 821
EasyCAT 0:543d6784d4cc 822 return lowest;
EasyCAT 0:543d6784d4cc 823 }
EasyCAT 0:543d6784d4cc 824
EasyCAT 0:543d6784d4cc 825 /** Write slave state, if slave = 0 then write to all slaves.
EasyCAT 0:543d6784d4cc 826 * The function does not check if the actual state is changed.
EasyCAT 0:543d6784d4cc 827 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 828 * @param[in] slave = Slave number, 0 = master
EasyCAT 0:543d6784d4cc 829 * @return Workcounter or EC_NOFRAME
EasyCAT 0:543d6784d4cc 830 */
EasyCAT 0:543d6784d4cc 831 int ecx_writestate(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 832 {
EasyCAT 0:543d6784d4cc 833 int ret;
EasyCAT 0:543d6784d4cc 834 uint16 configadr, slstate;
EasyCAT 0:543d6784d4cc 835
EasyCAT 0:543d6784d4cc 836 if (slave == 0)
EasyCAT 0:543d6784d4cc 837 {
EasyCAT 0:543d6784d4cc 838 slstate = htoes(context->slavelist[slave].state);
EasyCAT 0:543d6784d4cc 839 ret = ecx_BWR(context->port, 0, ECT_REG_ALCTL, sizeof(slstate),
EasyCAT 0:543d6784d4cc 840 &slstate, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 841 }
EasyCAT 0:543d6784d4cc 842 else
EasyCAT 0:543d6784d4cc 843 {
EasyCAT 0:543d6784d4cc 844 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 845
EasyCAT 0:543d6784d4cc 846 ret = ecx_FPWRw(context->port, configadr, ECT_REG_ALCTL,
EasyCAT 0:543d6784d4cc 847 htoes(context->slavelist[slave].state), EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 848 }
EasyCAT 0:543d6784d4cc 849 return ret;
EasyCAT 0:543d6784d4cc 850 }
EasyCAT 0:543d6784d4cc 851
EasyCAT 0:543d6784d4cc 852 /** Check actual slave state.
EasyCAT 0:543d6784d4cc 853 * This is a blocking function.
EasyCAT 0:543d6784d4cc 854 * To refresh the state of all slaves ecx_readstate()should be called
EasyCAT 0:543d6784d4cc 855 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 856 * @param[in] slave = Slave number, 0 = all slaves (only the "slavelist[0].state" is refreshed)
EasyCAT 0:543d6784d4cc 857 * @param[in] reqstate = Requested state
EasyCAT 0:543d6784d4cc 858 * @param[in] timeout = Timeout value in us
EasyCAT 0:543d6784d4cc 859 * @return Requested state, or found state after timeout.
EasyCAT 0:543d6784d4cc 860 */
EasyCAT 0:543d6784d4cc 861 uint16 ecx_statecheck(ecx_contextt *context, uint16 slave, uint16 reqstate, int timeout)
EasyCAT 0:543d6784d4cc 862 {
EasyCAT 0:543d6784d4cc 863 uint16 configadr, state, rval;
EasyCAT 0:543d6784d4cc 864 ec_alstatust slstat;
EasyCAT 0:543d6784d4cc 865 osal_timert timer;
EasyCAT 0:543d6784d4cc 866
EasyCAT 0:543d6784d4cc 867 if ( slave > *(context->slavecount) )
EasyCAT 0:543d6784d4cc 868 {
EasyCAT 0:543d6784d4cc 869 return 0;
EasyCAT 0:543d6784d4cc 870 }
EasyCAT 0:543d6784d4cc 871 osal_timer_start(&timer, timeout);
EasyCAT 0:543d6784d4cc 872 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 873 do
EasyCAT 0:543d6784d4cc 874 {
EasyCAT 0:543d6784d4cc 875 if (slave < 1)
EasyCAT 0:543d6784d4cc 876 {
EasyCAT 0:543d6784d4cc 877 rval = 0;
EasyCAT 0:543d6784d4cc 878 ecx_BRD(context->port, 0, ECT_REG_ALSTAT, sizeof(rval), &rval , EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 879 rval = etohs(rval);
EasyCAT 0:543d6784d4cc 880 }
EasyCAT 0:543d6784d4cc 881 else
EasyCAT 0:543d6784d4cc 882 {
EasyCAT 0:543d6784d4cc 883 slstat.alstatus = 0;
EasyCAT 0:543d6784d4cc 884 slstat.alstatuscode = 0;
EasyCAT 0:543d6784d4cc 885 ecx_FPRD(context->port, configadr, ECT_REG_ALSTAT, sizeof(slstat), &slstat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 886 rval = etohs(slstat.alstatus);
EasyCAT 0:543d6784d4cc 887 context->slavelist[slave].ALstatuscode = etohs(slstat.alstatuscode);
EasyCAT 0:543d6784d4cc 888 }
EasyCAT 0:543d6784d4cc 889 state = rval & 0x000f; /* read slave status */
EasyCAT 0:543d6784d4cc 890 if (state != reqstate)
EasyCAT 0:543d6784d4cc 891 {
EasyCAT 0:543d6784d4cc 892 osal_usleep(1000);
EasyCAT 0:543d6784d4cc 893 }
EasyCAT 0:543d6784d4cc 894 }
EasyCAT 0:543d6784d4cc 895 while ((state != reqstate) && (osal_timer_is_expired(&timer) == FALSE));
EasyCAT 0:543d6784d4cc 896 context->slavelist[slave].state = rval;
EasyCAT 0:543d6784d4cc 897
EasyCAT 0:543d6784d4cc 898 return state;
EasyCAT 0:543d6784d4cc 899 }
EasyCAT 0:543d6784d4cc 900
EasyCAT 0:543d6784d4cc 901 /** Get index of next mailbox counter value.
EasyCAT 0:543d6784d4cc 902 * Used for Mailbox Link Layer.
EasyCAT 0:543d6784d4cc 903 * @param[in] cnt = Mailbox counter value [0..7]
EasyCAT 0:543d6784d4cc 904 * @return next mailbox counter value
EasyCAT 0:543d6784d4cc 905 */
EasyCAT 0:543d6784d4cc 906 uint8 ec_nextmbxcnt(uint8 cnt)
EasyCAT 0:543d6784d4cc 907 {
EasyCAT 0:543d6784d4cc 908 cnt++;
EasyCAT 0:543d6784d4cc 909 if (cnt > 7)
EasyCAT 0:543d6784d4cc 910 {
EasyCAT 0:543d6784d4cc 911 cnt = 1; /* wrap around to 1, not 0 */
EasyCAT 0:543d6784d4cc 912 }
EasyCAT 0:543d6784d4cc 913
EasyCAT 0:543d6784d4cc 914 return cnt;
EasyCAT 0:543d6784d4cc 915 }
EasyCAT 0:543d6784d4cc 916
EasyCAT 0:543d6784d4cc 917 /** Clear mailbox buffer.
EasyCAT 0:543d6784d4cc 918 * @param[out] Mbx = Mailbox buffer to clear
EasyCAT 0:543d6784d4cc 919 */
EasyCAT 0:543d6784d4cc 920 void ec_clearmbx(ec_mbxbuft *Mbx)
EasyCAT 0:543d6784d4cc 921 {
EasyCAT 0:543d6784d4cc 922 memset(Mbx, 0x00, EC_MAXMBX);
EasyCAT 0:543d6784d4cc 923 }
EasyCAT 0:543d6784d4cc 924
EasyCAT 0:543d6784d4cc 925 /** Check if IN mailbox of slave is empty.
EasyCAT 0:543d6784d4cc 926 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 927 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 928 * @param[in] timeout = Timeout in us
EasyCAT 0:543d6784d4cc 929 * @return >0 is success
EasyCAT 0:543d6784d4cc 930 */
EasyCAT 0:543d6784d4cc 931 int ecx_mbxempty(ecx_contextt *context, uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 932 {
EasyCAT 0:543d6784d4cc 933 uint16 configadr;
EasyCAT 0:543d6784d4cc 934 uint8 SMstat;
EasyCAT 0:543d6784d4cc 935 int wkc;
EasyCAT 0:543d6784d4cc 936 osal_timert timer;
EasyCAT 0:543d6784d4cc 937
EasyCAT 0:543d6784d4cc 938 osal_timer_start(&timer, timeout);
EasyCAT 0:543d6784d4cc 939 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 940 do
EasyCAT 0:543d6784d4cc 941 {
EasyCAT 0:543d6784d4cc 942 SMstat = 0;
EasyCAT 0:543d6784d4cc 943 wkc = ecx_FPRD(context->port, configadr, ECT_REG_SM0STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 944 SMstat = etohs(SMstat);
EasyCAT 0:543d6784d4cc 945 if (((SMstat & 0x08) != 0) && (timeout > EC_LOCALDELAY))
EasyCAT 0:543d6784d4cc 946 {
EasyCAT 0:543d6784d4cc 947 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 948 }
EasyCAT 0:543d6784d4cc 949 }
EasyCAT 0:543d6784d4cc 950 while (((wkc <= 0) || ((SMstat & 0x08) != 0)) && (osal_timer_is_expired(&timer) == FALSE));
EasyCAT 0:543d6784d4cc 951
EasyCAT 0:543d6784d4cc 952 if ((wkc > 0) && ((SMstat & 0x08) == 0))
EasyCAT 0:543d6784d4cc 953 {
EasyCAT 0:543d6784d4cc 954 return 1;
EasyCAT 0:543d6784d4cc 955 }
EasyCAT 0:543d6784d4cc 956
EasyCAT 0:543d6784d4cc 957 return 0;
EasyCAT 0:543d6784d4cc 958 }
EasyCAT 0:543d6784d4cc 959
EasyCAT 0:543d6784d4cc 960 /** Write IN mailbox to slave.
EasyCAT 0:543d6784d4cc 961 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 962 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 963 * @param[out] mbx = Mailbox data
EasyCAT 0:543d6784d4cc 964 * @param[in] timeout = Timeout in us
EasyCAT 0:543d6784d4cc 965 * @return Work counter (>0 is success)
EasyCAT 0:543d6784d4cc 966 */
EasyCAT 0:543d6784d4cc 967 int ecx_mbxsend(ecx_contextt *context, uint16 slave,ec_mbxbuft *mbx, int timeout)
EasyCAT 0:543d6784d4cc 968 {
EasyCAT 0:543d6784d4cc 969 uint16 mbxwo,mbxl,configadr;
EasyCAT 0:543d6784d4cc 970 int wkc;
EasyCAT 0:543d6784d4cc 971
EasyCAT 0:543d6784d4cc 972 wkc = 0;
EasyCAT 0:543d6784d4cc 973 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 974 mbxl = context->slavelist[slave].mbx_l;
EasyCAT 0:543d6784d4cc 975 if ((mbxl > 0) && (mbxl <= EC_MAXMBX))
EasyCAT 0:543d6784d4cc 976 {
EasyCAT 0:543d6784d4cc 977 if (ecx_mbxempty(context, slave, timeout))
EasyCAT 0:543d6784d4cc 978 {
EasyCAT 0:543d6784d4cc 979 mbxwo = context->slavelist[slave].mbx_wo;
EasyCAT 0:543d6784d4cc 980 /* write slave in mailbox */
EasyCAT 0:543d6784d4cc 981 wkc = ecx_FPWR(context->port, configadr, mbxwo, mbxl, mbx, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 982 }
EasyCAT 0:543d6784d4cc 983 else
EasyCAT 0:543d6784d4cc 984 {
EasyCAT 0:543d6784d4cc 985 wkc = 0;
EasyCAT 0:543d6784d4cc 986 }
EasyCAT 0:543d6784d4cc 987 }
EasyCAT 0:543d6784d4cc 988
EasyCAT 0:543d6784d4cc 989 return wkc;
EasyCAT 0:543d6784d4cc 990 }
EasyCAT 0:543d6784d4cc 991
EasyCAT 0:543d6784d4cc 992 /** Read OUT mailbox from slave.
EasyCAT 0:543d6784d4cc 993 * Supports Mailbox Link Layer with repeat requests.
EasyCAT 0:543d6784d4cc 994 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 995 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 996 * @param[out] mbx = Mailbox data
EasyCAT 0:543d6784d4cc 997 * @param[in] timeout = Timeout in us
EasyCAT 0:543d6784d4cc 998 * @return Work counter (>0 is success)
EasyCAT 0:543d6784d4cc 999 */
EasyCAT 0:543d6784d4cc 1000 int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout)
EasyCAT 0:543d6784d4cc 1001 {
EasyCAT 0:543d6784d4cc 1002 uint16 mbxro,mbxl,configadr;
EasyCAT 0:543d6784d4cc 1003 int wkc=0;
EasyCAT 0:543d6784d4cc 1004 int wkc2;
EasyCAT 0:543d6784d4cc 1005 uint16 SMstat;
EasyCAT 0:543d6784d4cc 1006 uint8 SMcontr;
EasyCAT 0:543d6784d4cc 1007 ec_mbxheadert *mbxh;
EasyCAT 0:543d6784d4cc 1008 ec_emcyt *EMp;
EasyCAT 0:543d6784d4cc 1009 ec_mbxerrort *MBXEp;
EasyCAT 0:543d6784d4cc 1010
EasyCAT 0:543d6784d4cc 1011 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1012 mbxl = context->slavelist[slave].mbx_rl;
EasyCAT 0:543d6784d4cc 1013 if ((mbxl > 0) && (mbxl <= EC_MAXMBX))
EasyCAT 0:543d6784d4cc 1014 {
EasyCAT 0:543d6784d4cc 1015 osal_timert timer;
EasyCAT 0:543d6784d4cc 1016
EasyCAT 0:543d6784d4cc 1017 osal_timer_start(&timer, timeout);
EasyCAT 0:543d6784d4cc 1018 wkc = 0;
EasyCAT 0:543d6784d4cc 1019 do /* wait for read mailbox available */
EasyCAT 0:543d6784d4cc 1020 {
EasyCAT 0:543d6784d4cc 1021 SMstat = 0;
EasyCAT 0:543d6784d4cc 1022 wkc = ecx_FPRD(context->port, configadr, ECT_REG_SM1STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1023 SMstat = etohs(SMstat);
EasyCAT 0:543d6784d4cc 1024 if (((SMstat & 0x08) == 0) && (timeout > EC_LOCALDELAY))
EasyCAT 0:543d6784d4cc 1025 {
EasyCAT 0:543d6784d4cc 1026 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 1027 }
EasyCAT 0:543d6784d4cc 1028 }
EasyCAT 0:543d6784d4cc 1029 while (((wkc <= 0) || ((SMstat & 0x08) == 0)) && (osal_timer_is_expired(&timer) == FALSE));
EasyCAT 0:543d6784d4cc 1030
EasyCAT 0:543d6784d4cc 1031 if ((wkc > 0) && ((SMstat & 0x08) > 0)) /* read mailbox available ? */
EasyCAT 0:543d6784d4cc 1032 {
EasyCAT 0:543d6784d4cc 1033 mbxro = context->slavelist[slave].mbx_ro;
EasyCAT 0:543d6784d4cc 1034 mbxh = (ec_mbxheadert *)mbx;
EasyCAT 0:543d6784d4cc 1035 do
EasyCAT 0:543d6784d4cc 1036 {
EasyCAT 0:543d6784d4cc 1037 wkc = ecx_FPRD(context->port, configadr, mbxro, mbxl, mbx, EC_TIMEOUTRET); /* get mailbox */
EasyCAT 0:543d6784d4cc 1038 if ((wkc > 0) && ((mbxh->mbxtype & 0x0f) == 0x00)) /* Mailbox error response? */
EasyCAT 0:543d6784d4cc 1039 {
EasyCAT 0:543d6784d4cc 1040 MBXEp = (ec_mbxerrort *)mbx;
EasyCAT 0:543d6784d4cc 1041 ecx_mbxerror(context, slave, etohs(MBXEp->Detail));
EasyCAT 0:543d6784d4cc 1042 wkc = 0; /* prevent emergency to cascade up, it is already handled. */
EasyCAT 0:543d6784d4cc 1043 }
EasyCAT 0:543d6784d4cc 1044 else if ((wkc > 0) && ((mbxh->mbxtype & 0x0f) == ECT_MBXT_COE)) /* CoE response? */
EasyCAT 0:543d6784d4cc 1045 {
EasyCAT 0:543d6784d4cc 1046 EMp = (ec_emcyt *)mbx;
EasyCAT 0:543d6784d4cc 1047 if ((etohs(EMp->CANOpen) >> 12) == 0x01) /* Emergency request? */
EasyCAT 0:543d6784d4cc 1048 {
EasyCAT 0:543d6784d4cc 1049 ecx_mbxemergencyerror(context, slave, etohs(EMp->ErrorCode), EMp->ErrorReg,
EasyCAT 0:543d6784d4cc 1050 EMp->bData, etohs(EMp->w1), etohs(EMp->w2));
EasyCAT 0:543d6784d4cc 1051 wkc = 0; /* prevent emergency to cascade up, it is already handled. */
EasyCAT 0:543d6784d4cc 1052 }
EasyCAT 0:543d6784d4cc 1053 }
EasyCAT 0:543d6784d4cc 1054 else if ((wkc > 0) && ((mbxh->mbxtype & 0x0f) == ECT_MBXT_EOE)) /* EoE response? */
EasyCAT 0:543d6784d4cc 1055 {
EasyCAT 0:543d6784d4cc 1056 ec_EOEt * eoembx = (ec_EOEt *)mbx;
EasyCAT 0:543d6784d4cc 1057 uint16 frameinfo1 = etohs(eoembx->frameinfo1);
EasyCAT 0:543d6784d4cc 1058 /* All non fragment data frame types are expected to be handled by
EasyCAT 0:543d6784d4cc 1059 * slave send/receive API if the EoE hook is set
EasyCAT 0:543d6784d4cc 1060 */
EasyCAT 0:543d6784d4cc 1061 if (EOE_HDR_FRAME_TYPE_GET(frameinfo1) == EOE_FRAG_DATA)
EasyCAT 0:543d6784d4cc 1062 {
EasyCAT 0:543d6784d4cc 1063 if (context->EOEhook)
EasyCAT 0:543d6784d4cc 1064 {
EasyCAT 0:543d6784d4cc 1065 if (context->EOEhook(context, slave, eoembx) > 0)
EasyCAT 0:543d6784d4cc 1066 {
EasyCAT 0:543d6784d4cc 1067 /* Fragment handled by EoE hook */
EasyCAT 0:543d6784d4cc 1068 wkc = 0;
EasyCAT 0:543d6784d4cc 1069 }
EasyCAT 0:543d6784d4cc 1070 }
EasyCAT 0:543d6784d4cc 1071 }
EasyCAT 0:543d6784d4cc 1072 }
EasyCAT 0:543d6784d4cc 1073 else
EasyCAT 0:543d6784d4cc 1074 {
EasyCAT 0:543d6784d4cc 1075 if (wkc <= 0) /* read mailbox lost */
EasyCAT 0:543d6784d4cc 1076 {
EasyCAT 0:543d6784d4cc 1077 SMstat ^= 0x0200; /* toggle repeat request */
EasyCAT 0:543d6784d4cc 1078 SMstat = htoes(SMstat);
EasyCAT 0:543d6784d4cc 1079 wkc2 = ecx_FPWR(context->port, configadr, ECT_REG_SM1STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1080 SMstat = etohs(SMstat);
EasyCAT 0:543d6784d4cc 1081 do /* wait for toggle ack */
EasyCAT 0:543d6784d4cc 1082 {
EasyCAT 0:543d6784d4cc 1083 wkc2 = ecx_FPRD(context->port, configadr, ECT_REG_SM1CONTR, sizeof(SMcontr), &SMcontr, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1084 } while (((wkc2 <= 0) || ((SMcontr & 0x02) != (HI_BYTE(SMstat) & 0x02))) && (osal_timer_is_expired(&timer) == FALSE));
EasyCAT 0:543d6784d4cc 1085 do /* wait for read mailbox available */
EasyCAT 0:543d6784d4cc 1086 {
EasyCAT 0:543d6784d4cc 1087 wkc2 = ecx_FPRD(context->port, configadr, ECT_REG_SM1STAT, sizeof(SMstat), &SMstat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1088 SMstat = etohs(SMstat);
EasyCAT 0:543d6784d4cc 1089 if (((SMstat & 0x08) == 0) && (timeout > EC_LOCALDELAY))
EasyCAT 0:543d6784d4cc 1090 {
EasyCAT 0:543d6784d4cc 1091 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 1092 }
EasyCAT 0:543d6784d4cc 1093 } while (((wkc2 <= 0) || ((SMstat & 0x08) == 0)) && (osal_timer_is_expired(&timer) == FALSE));
EasyCAT 0:543d6784d4cc 1094 }
EasyCAT 0:543d6784d4cc 1095 }
EasyCAT 0:543d6784d4cc 1096 } while ((wkc <= 0) && (osal_timer_is_expired(&timer) == FALSE)); /* if WKC<=0 repeat */
EasyCAT 0:543d6784d4cc 1097 }
EasyCAT 0:543d6784d4cc 1098 else /* no read mailbox available */
EasyCAT 0:543d6784d4cc 1099 {
EasyCAT 0:543d6784d4cc 1100 wkc = 0;
EasyCAT 0:543d6784d4cc 1101 }
EasyCAT 0:543d6784d4cc 1102 }
EasyCAT 0:543d6784d4cc 1103
EasyCAT 0:543d6784d4cc 1104 return wkc;
EasyCAT 0:543d6784d4cc 1105 }
EasyCAT 0:543d6784d4cc 1106
EasyCAT 0:543d6784d4cc 1107 /** Dump complete EEPROM data from slave in buffer.
EasyCAT 0:543d6784d4cc 1108 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1109 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1110 * @param[out] esibuf = EEPROM data buffer, make sure it is big enough.
EasyCAT 0:543d6784d4cc 1111 */
EasyCAT 0:543d6784d4cc 1112 void ecx_esidump(ecx_contextt *context, uint16 slave, uint8 *esibuf)
EasyCAT 0:543d6784d4cc 1113 {
EasyCAT 0:543d6784d4cc 1114 int address, incr;
EasyCAT 0:543d6784d4cc 1115 uint16 configadr;
EasyCAT 0:543d6784d4cc 1116 uint64 *p64;
EasyCAT 0:543d6784d4cc 1117 uint16 *p16;
EasyCAT 0:543d6784d4cc 1118 uint64 edat;
EasyCAT 0:543d6784d4cc 1119 uint8 eectl = context->slavelist[slave].eep_pdi;
EasyCAT 0:543d6784d4cc 1120
EasyCAT 0:543d6784d4cc 1121 ecx_eeprom2master(context, slave); /* set eeprom control to master */
EasyCAT 0:543d6784d4cc 1122 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1123 address = ECT_SII_START;
EasyCAT 0:543d6784d4cc 1124 p16=(uint16*)esibuf;
EasyCAT 0:543d6784d4cc 1125 if (context->slavelist[slave].eep_8byte)
EasyCAT 0:543d6784d4cc 1126 {
EasyCAT 0:543d6784d4cc 1127 incr = 4;
EasyCAT 0:543d6784d4cc 1128 }
EasyCAT 0:543d6784d4cc 1129 else
EasyCAT 0:543d6784d4cc 1130 {
EasyCAT 0:543d6784d4cc 1131 incr = 2;
EasyCAT 0:543d6784d4cc 1132 }
EasyCAT 0:543d6784d4cc 1133 do
EasyCAT 0:543d6784d4cc 1134 {
EasyCAT 0:543d6784d4cc 1135 edat = ecx_readeepromFP(context, configadr, address, EC_TIMEOUTEEP);
EasyCAT 0:543d6784d4cc 1136 p64 = (uint64*)p16;
EasyCAT 0:543d6784d4cc 1137 *p64 = edat;
EasyCAT 0:543d6784d4cc 1138 p16 += incr;
EasyCAT 0:543d6784d4cc 1139 address += incr;
EasyCAT 0:543d6784d4cc 1140 } while ((address <= (EC_MAXEEPBUF >> 1)) && ((uint32)edat != 0xffffffff));
EasyCAT 0:543d6784d4cc 1141
EasyCAT 0:543d6784d4cc 1142 if (eectl)
EasyCAT 0:543d6784d4cc 1143 {
EasyCAT 0:543d6784d4cc 1144 ecx_eeprom2pdi(context, slave); /* if eeprom control was previously pdi then restore */
EasyCAT 0:543d6784d4cc 1145 }
EasyCAT 0:543d6784d4cc 1146 }
EasyCAT 0:543d6784d4cc 1147
EasyCAT 0:543d6784d4cc 1148 /** Read EEPROM from slave bypassing cache.
EasyCAT 0:543d6784d4cc 1149 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1150 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1151 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1152 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1153 * @return EEPROM data 32bit
EasyCAT 0:543d6784d4cc 1154 */
EasyCAT 0:543d6784d4cc 1155 uint32 ecx_readeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, int timeout)
EasyCAT 0:543d6784d4cc 1156 {
EasyCAT 0:543d6784d4cc 1157 uint16 configadr;
EasyCAT 0:543d6784d4cc 1158
EasyCAT 0:543d6784d4cc 1159 ecx_eeprom2master(context, slave); /* set eeprom control to master */
EasyCAT 0:543d6784d4cc 1160 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1161
EasyCAT 0:543d6784d4cc 1162 return ((uint32)ecx_readeepromFP(context, configadr, eeproma, timeout));
EasyCAT 0:543d6784d4cc 1163 }
EasyCAT 0:543d6784d4cc 1164
EasyCAT 0:543d6784d4cc 1165 /** Write EEPROM to slave bypassing cache.
EasyCAT 0:543d6784d4cc 1166 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1167 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1168 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1169 * @param[in] data = 16bit data
EasyCAT 0:543d6784d4cc 1170 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1171 * @return >0 if OK
EasyCAT 0:543d6784d4cc 1172 */
EasyCAT 0:543d6784d4cc 1173 int ecx_writeeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, uint16 data, int timeout)
EasyCAT 0:543d6784d4cc 1174 {
EasyCAT 0:543d6784d4cc 1175 uint16 configadr;
EasyCAT 0:543d6784d4cc 1176
EasyCAT 0:543d6784d4cc 1177 ecx_eeprom2master(context, slave); /* set eeprom control to master */
EasyCAT 0:543d6784d4cc 1178 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1179 return (ecx_writeeepromFP(context, configadr, eeproma, data, timeout));
EasyCAT 0:543d6784d4cc 1180 }
EasyCAT 0:543d6784d4cc 1181
EasyCAT 0:543d6784d4cc 1182 /** Set eeprom control to master. Only if set to PDI.
EasyCAT 0:543d6784d4cc 1183 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1184 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1185 * @return >0 if OK
EasyCAT 0:543d6784d4cc 1186 */
EasyCAT 0:543d6784d4cc 1187 int ecx_eeprom2master(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 1188 {
EasyCAT 0:543d6784d4cc 1189 int wkc = 1, cnt = 0;
EasyCAT 0:543d6784d4cc 1190 uint16 configadr;
EasyCAT 0:543d6784d4cc 1191 uint8 eepctl;
EasyCAT 0:543d6784d4cc 1192
EasyCAT 0:543d6784d4cc 1193 if ( context->slavelist[slave].eep_pdi )
EasyCAT 0:543d6784d4cc 1194 {
EasyCAT 0:543d6784d4cc 1195 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1196 eepctl = 2;
EasyCAT 0:543d6784d4cc 1197 do
EasyCAT 0:543d6784d4cc 1198 {
EasyCAT 0:543d6784d4cc 1199 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* force Eeprom from PDI */
EasyCAT 0:543d6784d4cc 1200 }
EasyCAT 0:543d6784d4cc 1201 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1202 eepctl = 0;
EasyCAT 0:543d6784d4cc 1203 cnt = 0;
EasyCAT 0:543d6784d4cc 1204 do
EasyCAT 0:543d6784d4cc 1205 {
EasyCAT 0:543d6784d4cc 1206 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to master */
EasyCAT 0:543d6784d4cc 1207 }
EasyCAT 0:543d6784d4cc 1208 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1209 context->slavelist[slave].eep_pdi = 0;
EasyCAT 0:543d6784d4cc 1210 }
EasyCAT 0:543d6784d4cc 1211
EasyCAT 0:543d6784d4cc 1212 return wkc;
EasyCAT 0:543d6784d4cc 1213 }
EasyCAT 0:543d6784d4cc 1214
EasyCAT 0:543d6784d4cc 1215 /** Set eeprom control to PDI. Only if set to master.
EasyCAT 0:543d6784d4cc 1216 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1217 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1218 * @return >0 if OK
EasyCAT 0:543d6784d4cc 1219 */
EasyCAT 0:543d6784d4cc 1220 int ecx_eeprom2pdi(ecx_contextt *context, uint16 slave)
EasyCAT 0:543d6784d4cc 1221 {
EasyCAT 0:543d6784d4cc 1222 int wkc = 1, cnt = 0;
EasyCAT 0:543d6784d4cc 1223 uint16 configadr;
EasyCAT 0:543d6784d4cc 1224 uint8 eepctl;
EasyCAT 0:543d6784d4cc 1225
EasyCAT 0:543d6784d4cc 1226 if ( !context->slavelist[slave].eep_pdi )
EasyCAT 0:543d6784d4cc 1227 {
EasyCAT 0:543d6784d4cc 1228 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1229 eepctl = 1;
EasyCAT 0:543d6784d4cc 1230 do
EasyCAT 0:543d6784d4cc 1231 {
EasyCAT 0:543d6784d4cc 1232 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCFG, sizeof(eepctl), &eepctl , EC_TIMEOUTRET); /* set Eeprom to PDI */
EasyCAT 0:543d6784d4cc 1233 }
EasyCAT 0:543d6784d4cc 1234 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1235 context->slavelist[slave].eep_pdi = 1;
EasyCAT 0:543d6784d4cc 1236 }
EasyCAT 0:543d6784d4cc 1237
EasyCAT 0:543d6784d4cc 1238 return wkc;
EasyCAT 0:543d6784d4cc 1239 }
EasyCAT 0:543d6784d4cc 1240
EasyCAT 0:543d6784d4cc 1241 uint16 ecx_eeprom_waitnotbusyAP(ecx_contextt *context, uint16 aiadr,uint16 *estat, int timeout)
EasyCAT 0:543d6784d4cc 1242 {
EasyCAT 0:543d6784d4cc 1243 int wkc, cnt = 0, retval = 0;
EasyCAT 0:543d6784d4cc 1244 osal_timert timer;
EasyCAT 0:543d6784d4cc 1245
EasyCAT 0:543d6784d4cc 1246 osal_timer_start(&timer, timeout);
EasyCAT 0:543d6784d4cc 1247 do
EasyCAT 0:543d6784d4cc 1248 {
EasyCAT 0:543d6784d4cc 1249 if (cnt++)
EasyCAT 0:543d6784d4cc 1250 {
EasyCAT 0:543d6784d4cc 1251 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 1252 }
EasyCAT 0:543d6784d4cc 1253 *estat = 0;
EasyCAT 0:543d6784d4cc 1254 wkc=ecx_APRD(context->port, aiadr, ECT_REG_EEPSTAT, sizeof(*estat), estat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1255 *estat = etohs(*estat);
EasyCAT 0:543d6784d4cc 1256 }
EasyCAT 0:543d6784d4cc 1257 while (((wkc <= 0) || ((*estat & EC_ESTAT_BUSY) > 0)) && (osal_timer_is_expired(&timer) == FALSE)); /* wait for eeprom ready */
EasyCAT 0:543d6784d4cc 1258 if ((*estat & EC_ESTAT_BUSY) == 0)
EasyCAT 0:543d6784d4cc 1259 {
EasyCAT 0:543d6784d4cc 1260 retval = 1;
EasyCAT 0:543d6784d4cc 1261 }
EasyCAT 0:543d6784d4cc 1262
EasyCAT 0:543d6784d4cc 1263 return retval;
EasyCAT 0:543d6784d4cc 1264 }
EasyCAT 0:543d6784d4cc 1265
EasyCAT 0:543d6784d4cc 1266 /** Read EEPROM from slave bypassing cache. APRD method.
EasyCAT 0:543d6784d4cc 1267 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1268 * @param[in] aiadr = auto increment address of slave
EasyCAT 0:543d6784d4cc 1269 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1270 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1271 * @return EEPROM data 64bit or 32bit
EasyCAT 0:543d6784d4cc 1272 */
EasyCAT 0:543d6784d4cc 1273 uint64 ecx_readeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, int timeout)
EasyCAT 0:543d6784d4cc 1274 {
EasyCAT 0:543d6784d4cc 1275 uint16 estat;
EasyCAT 0:543d6784d4cc 1276 uint32 edat32;
EasyCAT 0:543d6784d4cc 1277 uint64 edat64;
EasyCAT 0:543d6784d4cc 1278 ec_eepromt ed;
EasyCAT 0:543d6784d4cc 1279 int wkc, cnt, nackcnt = 0;
EasyCAT 0:543d6784d4cc 1280
EasyCAT 0:543d6784d4cc 1281 edat64 = 0;
EasyCAT 0:543d6784d4cc 1282 edat32 = 0;
EasyCAT 0:543d6784d4cc 1283 if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1284 {
EasyCAT 0:543d6784d4cc 1285 if (estat & EC_ESTAT_EMASK) /* error bits are set */
EasyCAT 0:543d6784d4cc 1286 {
EasyCAT 0:543d6784d4cc 1287 estat = htoes(EC_ECMD_NOP); /* clear error bits */
EasyCAT 0:543d6784d4cc 1288 wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 1289 }
EasyCAT 0:543d6784d4cc 1290
EasyCAT 0:543d6784d4cc 1291 do
EasyCAT 0:543d6784d4cc 1292 {
EasyCAT 0:543d6784d4cc 1293 ed.comm = htoes(EC_ECMD_READ);
EasyCAT 0:543d6784d4cc 1294 ed.addr = htoes(eeproma);
EasyCAT 0:543d6784d4cc 1295 ed.d2 = 0x0000;
EasyCAT 0:543d6784d4cc 1296 cnt = 0;
EasyCAT 0:543d6784d4cc 1297 do
EasyCAT 0:543d6784d4cc 1298 {
EasyCAT 0:543d6784d4cc 1299 wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1300 }
EasyCAT 0:543d6784d4cc 1301 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1302 if (wkc)
EasyCAT 0:543d6784d4cc 1303 {
EasyCAT 0:543d6784d4cc 1304 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 1305 estat = 0x0000;
EasyCAT 0:543d6784d4cc 1306 if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1307 {
EasyCAT 0:543d6784d4cc 1308 if (estat & EC_ESTAT_NACK)
EasyCAT 0:543d6784d4cc 1309 {
EasyCAT 0:543d6784d4cc 1310 nackcnt++;
EasyCAT 0:543d6784d4cc 1311 osal_usleep(EC_LOCALDELAY * 5);
EasyCAT 0:543d6784d4cc 1312 }
EasyCAT 0:543d6784d4cc 1313 else
EasyCAT 0:543d6784d4cc 1314 {
EasyCAT 0:543d6784d4cc 1315 nackcnt = 0;
EasyCAT 0:543d6784d4cc 1316 if (estat & EC_ESTAT_R64)
EasyCAT 0:543d6784d4cc 1317 {
EasyCAT 0:543d6784d4cc 1318 cnt = 0;
EasyCAT 0:543d6784d4cc 1319 do
EasyCAT 0:543d6784d4cc 1320 {
EasyCAT 0:543d6784d4cc 1321 wkc = ecx_APRD(context->port, aiadr, ECT_REG_EEPDAT, sizeof(edat64), &edat64, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1322 }
EasyCAT 0:543d6784d4cc 1323 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1324 }
EasyCAT 0:543d6784d4cc 1325 else
EasyCAT 0:543d6784d4cc 1326 {
EasyCAT 0:543d6784d4cc 1327 cnt = 0;
EasyCAT 0:543d6784d4cc 1328 do
EasyCAT 0:543d6784d4cc 1329 {
EasyCAT 0:543d6784d4cc 1330 wkc = ecx_APRD(context->port, aiadr, ECT_REG_EEPDAT, sizeof(edat32), &edat32, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1331 }
EasyCAT 0:543d6784d4cc 1332 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1333 edat64=(uint64)edat32;
EasyCAT 0:543d6784d4cc 1334 }
EasyCAT 0:543d6784d4cc 1335 }
EasyCAT 0:543d6784d4cc 1336 }
EasyCAT 0:543d6784d4cc 1337 }
EasyCAT 0:543d6784d4cc 1338 }
EasyCAT 0:543d6784d4cc 1339 while ((nackcnt > 0) && (nackcnt < 3));
EasyCAT 0:543d6784d4cc 1340 }
EasyCAT 0:543d6784d4cc 1341
EasyCAT 0:543d6784d4cc 1342 return edat64;
EasyCAT 0:543d6784d4cc 1343 }
EasyCAT 0:543d6784d4cc 1344
EasyCAT 0:543d6784d4cc 1345 /** Write EEPROM to slave bypassing cache. APWR method.
EasyCAT 0:543d6784d4cc 1346 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1347 * @param[in] aiadr = configured address of slave
EasyCAT 0:543d6784d4cc 1348 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1349 * @param[in] data = 16bit data
EasyCAT 0:543d6784d4cc 1350 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1351 * @return >0 if OK
EasyCAT 0:543d6784d4cc 1352 */
EasyCAT 0:543d6784d4cc 1353 int ecx_writeeepromAP(ecx_contextt *context, uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
EasyCAT 0:543d6784d4cc 1354 {
EasyCAT 0:543d6784d4cc 1355 uint16 estat;
EasyCAT 0:543d6784d4cc 1356 ec_eepromt ed;
EasyCAT 0:543d6784d4cc 1357 int wkc, rval = 0, cnt = 0, nackcnt = 0;
EasyCAT 0:543d6784d4cc 1358
EasyCAT 0:543d6784d4cc 1359 if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1360 {
EasyCAT 0:543d6784d4cc 1361 if (estat & EC_ESTAT_EMASK) /* error bits are set */
EasyCAT 0:543d6784d4cc 1362 {
EasyCAT 0:543d6784d4cc 1363 estat = htoes(EC_ECMD_NOP); /* clear error bits */
EasyCAT 0:543d6784d4cc 1364 wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 1365 }
EasyCAT 0:543d6784d4cc 1366 do
EasyCAT 0:543d6784d4cc 1367 {
EasyCAT 0:543d6784d4cc 1368 cnt = 0;
EasyCAT 0:543d6784d4cc 1369 do
EasyCAT 0:543d6784d4cc 1370 {
EasyCAT 0:543d6784d4cc 1371 wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPDAT, sizeof(data), &data, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1372 }
EasyCAT 0:543d6784d4cc 1373 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1374
EasyCAT 0:543d6784d4cc 1375 ed.comm = EC_ECMD_WRITE;
EasyCAT 0:543d6784d4cc 1376 ed.addr = eeproma;
EasyCAT 0:543d6784d4cc 1377 ed.d2 = 0x0000;
EasyCAT 0:543d6784d4cc 1378 cnt = 0;
EasyCAT 0:543d6784d4cc 1379 do
EasyCAT 0:543d6784d4cc 1380 {
EasyCAT 0:543d6784d4cc 1381 wkc = ecx_APWR(context->port, aiadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1382 }
EasyCAT 0:543d6784d4cc 1383 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1384 if (wkc)
EasyCAT 0:543d6784d4cc 1385 {
EasyCAT 0:543d6784d4cc 1386 osal_usleep(EC_LOCALDELAY * 2);
EasyCAT 0:543d6784d4cc 1387 estat = 0x0000;
EasyCAT 0:543d6784d4cc 1388 if (ecx_eeprom_waitnotbusyAP(context, aiadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1389 {
EasyCAT 0:543d6784d4cc 1390 if (estat & EC_ESTAT_NACK)
EasyCAT 0:543d6784d4cc 1391 {
EasyCAT 0:543d6784d4cc 1392 nackcnt++;
EasyCAT 0:543d6784d4cc 1393 osal_usleep(EC_LOCALDELAY * 5);
EasyCAT 0:543d6784d4cc 1394 }
EasyCAT 0:543d6784d4cc 1395 else
EasyCAT 0:543d6784d4cc 1396 {
EasyCAT 0:543d6784d4cc 1397 nackcnt = 0;
EasyCAT 0:543d6784d4cc 1398 rval = 1;
EasyCAT 0:543d6784d4cc 1399 }
EasyCAT 0:543d6784d4cc 1400 }
EasyCAT 0:543d6784d4cc 1401 }
EasyCAT 0:543d6784d4cc 1402
EasyCAT 0:543d6784d4cc 1403 }
EasyCAT 0:543d6784d4cc 1404 while ((nackcnt > 0) && (nackcnt < 3));
EasyCAT 0:543d6784d4cc 1405 }
EasyCAT 0:543d6784d4cc 1406
EasyCAT 0:543d6784d4cc 1407 return rval;
EasyCAT 0:543d6784d4cc 1408 }
EasyCAT 0:543d6784d4cc 1409
EasyCAT 0:543d6784d4cc 1410 uint16 ecx_eeprom_waitnotbusyFP(ecx_contextt *context, uint16 configadr,uint16 *estat, int timeout)
EasyCAT 0:543d6784d4cc 1411 {
EasyCAT 0:543d6784d4cc 1412 int wkc, cnt = 0, retval = 0;
EasyCAT 0:543d6784d4cc 1413 osal_timert timer;
EasyCAT 0:543d6784d4cc 1414
EasyCAT 0:543d6784d4cc 1415 osal_timer_start(&timer, timeout);
EasyCAT 0:543d6784d4cc 1416 do
EasyCAT 0:543d6784d4cc 1417 {
EasyCAT 0:543d6784d4cc 1418 if (cnt++)
EasyCAT 0:543d6784d4cc 1419 {
EasyCAT 0:543d6784d4cc 1420 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 1421 }
EasyCAT 0:543d6784d4cc 1422 *estat = 0;
EasyCAT 0:543d6784d4cc 1423 wkc=ecx_FPRD(context->port, configadr, ECT_REG_EEPSTAT, sizeof(*estat), estat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1424 *estat = etohs(*estat);
EasyCAT 0:543d6784d4cc 1425 }
EasyCAT 0:543d6784d4cc 1426 while (((wkc <= 0) || ((*estat & EC_ESTAT_BUSY) > 0)) && (osal_timer_is_expired(&timer) == FALSE)); /* wait for eeprom ready */
EasyCAT 0:543d6784d4cc 1427 if ((*estat & EC_ESTAT_BUSY) == 0)
EasyCAT 0:543d6784d4cc 1428 {
EasyCAT 0:543d6784d4cc 1429 retval = 1;
EasyCAT 0:543d6784d4cc 1430 }
EasyCAT 0:543d6784d4cc 1431
EasyCAT 0:543d6784d4cc 1432 return retval;
EasyCAT 0:543d6784d4cc 1433 }
EasyCAT 0:543d6784d4cc 1434
EasyCAT 0:543d6784d4cc 1435 /** Read EEPROM from slave bypassing cache. FPRD method.
EasyCAT 0:543d6784d4cc 1436 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1437 * @param[in] configadr = configured address of slave
EasyCAT 0:543d6784d4cc 1438 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1439 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1440 * @return EEPROM data 64bit or 32bit
EasyCAT 0:543d6784d4cc 1441 */
EasyCAT 0:543d6784d4cc 1442 uint64 ecx_readeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, int timeout)
EasyCAT 0:543d6784d4cc 1443 {
EasyCAT 0:543d6784d4cc 1444 uint16 estat;
EasyCAT 0:543d6784d4cc 1445 uint32 edat32;
EasyCAT 0:543d6784d4cc 1446 uint64 edat64;
EasyCAT 0:543d6784d4cc 1447 ec_eepromt ed;
EasyCAT 0:543d6784d4cc 1448 int wkc, cnt, nackcnt = 0;
EasyCAT 0:543d6784d4cc 1449
EasyCAT 0:543d6784d4cc 1450 edat64 = 0;
EasyCAT 0:543d6784d4cc 1451 edat32 = 0;
EasyCAT 0:543d6784d4cc 1452 if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1453 {
EasyCAT 0:543d6784d4cc 1454 if (estat & EC_ESTAT_EMASK) /* error bits are set */
EasyCAT 0:543d6784d4cc 1455 {
EasyCAT 0:543d6784d4cc 1456 estat = htoes(EC_ECMD_NOP); /* clear error bits */
EasyCAT 0:543d6784d4cc 1457 wkc=ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 1458 }
EasyCAT 0:543d6784d4cc 1459
EasyCAT 0:543d6784d4cc 1460 do
EasyCAT 0:543d6784d4cc 1461 {
EasyCAT 0:543d6784d4cc 1462 ed.comm = htoes(EC_ECMD_READ);
EasyCAT 0:543d6784d4cc 1463 ed.addr = htoes(eeproma);
EasyCAT 0:543d6784d4cc 1464 ed.d2 = 0x0000;
EasyCAT 0:543d6784d4cc 1465 cnt = 0;
EasyCAT 0:543d6784d4cc 1466 do
EasyCAT 0:543d6784d4cc 1467 {
EasyCAT 0:543d6784d4cc 1468 wkc=ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1469 }
EasyCAT 0:543d6784d4cc 1470 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1471 if (wkc)
EasyCAT 0:543d6784d4cc 1472 {
EasyCAT 0:543d6784d4cc 1473 osal_usleep(EC_LOCALDELAY);
EasyCAT 0:543d6784d4cc 1474 estat = 0x0000;
EasyCAT 0:543d6784d4cc 1475 if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1476 {
EasyCAT 0:543d6784d4cc 1477 if (estat & EC_ESTAT_NACK)
EasyCAT 0:543d6784d4cc 1478 {
EasyCAT 0:543d6784d4cc 1479 nackcnt++;
EasyCAT 0:543d6784d4cc 1480 osal_usleep(EC_LOCALDELAY * 5);
EasyCAT 0:543d6784d4cc 1481 }
EasyCAT 0:543d6784d4cc 1482 else
EasyCAT 0:543d6784d4cc 1483 {
EasyCAT 0:543d6784d4cc 1484 nackcnt = 0;
EasyCAT 0:543d6784d4cc 1485 if (estat & EC_ESTAT_R64)
EasyCAT 0:543d6784d4cc 1486 {
EasyCAT 0:543d6784d4cc 1487 cnt = 0;
EasyCAT 0:543d6784d4cc 1488 do
EasyCAT 0:543d6784d4cc 1489 {
EasyCAT 0:543d6784d4cc 1490 wkc=ecx_FPRD(context->port, configadr, ECT_REG_EEPDAT, sizeof(edat64), &edat64, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1491 }
EasyCAT 0:543d6784d4cc 1492 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1493 }
EasyCAT 0:543d6784d4cc 1494 else
EasyCAT 0:543d6784d4cc 1495 {
EasyCAT 0:543d6784d4cc 1496 cnt = 0;
EasyCAT 0:543d6784d4cc 1497 do
EasyCAT 0:543d6784d4cc 1498 {
EasyCAT 0:543d6784d4cc 1499 wkc=ecx_FPRD(context->port, configadr, ECT_REG_EEPDAT, sizeof(edat32), &edat32, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1500 }
EasyCAT 0:543d6784d4cc 1501 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1502 edat64=(uint64)edat32;
EasyCAT 0:543d6784d4cc 1503 }
EasyCAT 0:543d6784d4cc 1504 }
EasyCAT 0:543d6784d4cc 1505 }
EasyCAT 0:543d6784d4cc 1506 }
EasyCAT 0:543d6784d4cc 1507 }
EasyCAT 0:543d6784d4cc 1508 while ((nackcnt > 0) && (nackcnt < 3));
EasyCAT 0:543d6784d4cc 1509 }
EasyCAT 0:543d6784d4cc 1510
EasyCAT 0:543d6784d4cc 1511 return edat64;
EasyCAT 0:543d6784d4cc 1512 }
EasyCAT 0:543d6784d4cc 1513
EasyCAT 0:543d6784d4cc 1514 /** Write EEPROM to slave bypassing cache. FPWR method.
EasyCAT 0:543d6784d4cc 1515 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1516 * @param[in] configadr = configured address of slave
EasyCAT 0:543d6784d4cc 1517 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1518 * @param[in] data = 16bit data
EasyCAT 0:543d6784d4cc 1519 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1520 * @return >0 if OK
EasyCAT 0:543d6784d4cc 1521 */
EasyCAT 0:543d6784d4cc 1522 int ecx_writeeepromFP(ecx_contextt *context, uint16 configadr, uint16 eeproma, uint16 data, int timeout)
EasyCAT 0:543d6784d4cc 1523 {
EasyCAT 0:543d6784d4cc 1524 uint16 estat;
EasyCAT 0:543d6784d4cc 1525 ec_eepromt ed;
EasyCAT 0:543d6784d4cc 1526 int wkc, rval = 0, cnt = 0, nackcnt = 0;
EasyCAT 0:543d6784d4cc 1527
EasyCAT 0:543d6784d4cc 1528 if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1529 {
EasyCAT 0:543d6784d4cc 1530 if (estat & EC_ESTAT_EMASK) /* error bits are set */
EasyCAT 0:543d6784d4cc 1531 {
EasyCAT 0:543d6784d4cc 1532 estat = htoes(EC_ECMD_NOP); /* clear error bits */
EasyCAT 0:543d6784d4cc 1533 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 1534 }
EasyCAT 0:543d6784d4cc 1535 do
EasyCAT 0:543d6784d4cc 1536 {
EasyCAT 0:543d6784d4cc 1537 cnt = 0;
EasyCAT 0:543d6784d4cc 1538 do
EasyCAT 0:543d6784d4cc 1539 {
EasyCAT 0:543d6784d4cc 1540 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPDAT, sizeof(data), &data, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1541 }
EasyCAT 0:543d6784d4cc 1542 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1543 ed.comm = EC_ECMD_WRITE;
EasyCAT 0:543d6784d4cc 1544 ed.addr = eeproma;
EasyCAT 0:543d6784d4cc 1545 ed.d2 = 0x0000;
EasyCAT 0:543d6784d4cc 1546 cnt = 0;
EasyCAT 0:543d6784d4cc 1547 do
EasyCAT 0:543d6784d4cc 1548 {
EasyCAT 0:543d6784d4cc 1549 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1550 }
EasyCAT 0:543d6784d4cc 1551 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1552 if (wkc)
EasyCAT 0:543d6784d4cc 1553 {
EasyCAT 0:543d6784d4cc 1554 osal_usleep(EC_LOCALDELAY * 2);
EasyCAT 0:543d6784d4cc 1555 estat = 0x0000;
EasyCAT 0:543d6784d4cc 1556 if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1557 {
EasyCAT 0:543d6784d4cc 1558 if (estat & EC_ESTAT_NACK)
EasyCAT 0:543d6784d4cc 1559 {
EasyCAT 0:543d6784d4cc 1560 nackcnt++;
EasyCAT 0:543d6784d4cc 1561 osal_usleep(EC_LOCALDELAY * 5);
EasyCAT 0:543d6784d4cc 1562 }
EasyCAT 0:543d6784d4cc 1563 else
EasyCAT 0:543d6784d4cc 1564 {
EasyCAT 0:543d6784d4cc 1565 nackcnt = 0;
EasyCAT 0:543d6784d4cc 1566 rval = 1;
EasyCAT 0:543d6784d4cc 1567 }
EasyCAT 0:543d6784d4cc 1568 }
EasyCAT 0:543d6784d4cc 1569 }
EasyCAT 0:543d6784d4cc 1570 }
EasyCAT 0:543d6784d4cc 1571 while ((nackcnt > 0) && (nackcnt < 3));
EasyCAT 0:543d6784d4cc 1572 }
EasyCAT 0:543d6784d4cc 1573
EasyCAT 0:543d6784d4cc 1574 return rval;
EasyCAT 0:543d6784d4cc 1575 }
EasyCAT 0:543d6784d4cc 1576
EasyCAT 0:543d6784d4cc 1577 /** Read EEPROM from slave bypassing cache.
EasyCAT 0:543d6784d4cc 1578 * Parallel read step 1, make request to slave.
EasyCAT 0:543d6784d4cc 1579 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1580 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1581 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 1582 */
EasyCAT 0:543d6784d4cc 1583 void ecx_readeeprom1(ecx_contextt *context, uint16 slave, uint16 eeproma)
EasyCAT 0:543d6784d4cc 1584 {
EasyCAT 0:543d6784d4cc 1585 uint16 configadr, estat;
EasyCAT 0:543d6784d4cc 1586 ec_eepromt ed;
EasyCAT 0:543d6784d4cc 1587 int wkc, cnt = 0;
EasyCAT 0:543d6784d4cc 1588
EasyCAT 0:543d6784d4cc 1589 ecx_eeprom2master(context, slave); /* set eeprom control to master */
EasyCAT 0:543d6784d4cc 1590 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1591 if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, EC_TIMEOUTEEP))
EasyCAT 0:543d6784d4cc 1592 {
EasyCAT 0:543d6784d4cc 1593 if (estat & EC_ESTAT_EMASK) /* error bits are set */
EasyCAT 0:543d6784d4cc 1594 {
EasyCAT 0:543d6784d4cc 1595 estat = htoes(EC_ECMD_NOP); /* clear error bits */
EasyCAT 0:543d6784d4cc 1596 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(estat), &estat, EC_TIMEOUTRET3);
EasyCAT 0:543d6784d4cc 1597 }
EasyCAT 0:543d6784d4cc 1598 ed.comm = htoes(EC_ECMD_READ);
EasyCAT 0:543d6784d4cc 1599 ed.addr = htoes(eeproma);
EasyCAT 0:543d6784d4cc 1600 ed.d2 = 0x0000;
EasyCAT 0:543d6784d4cc 1601 do
EasyCAT 0:543d6784d4cc 1602 {
EasyCAT 0:543d6784d4cc 1603 wkc = ecx_FPWR(context->port, configadr, ECT_REG_EEPCTL, sizeof(ed), &ed, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1604 }
EasyCAT 0:543d6784d4cc 1605 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1606 }
EasyCAT 0:543d6784d4cc 1607 }
EasyCAT 0:543d6784d4cc 1608
EasyCAT 0:543d6784d4cc 1609 /** Read EEPROM from slave bypassing cache.
EasyCAT 0:543d6784d4cc 1610 * Parallel read step 2, actual read from slave.
EasyCAT 0:543d6784d4cc 1611 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1612 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1613 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1614 * @return EEPROM data 32bit
EasyCAT 0:543d6784d4cc 1615 */
EasyCAT 0:543d6784d4cc 1616 uint32 ecx_readeeprom2(ecx_contextt *context, uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 1617 {
EasyCAT 0:543d6784d4cc 1618 uint16 estat, configadr;
EasyCAT 0:543d6784d4cc 1619 uint32 edat;
EasyCAT 0:543d6784d4cc 1620 int wkc, cnt = 0;
EasyCAT 0:543d6784d4cc 1621
EasyCAT 0:543d6784d4cc 1622 configadr = context->slavelist[slave].configadr;
EasyCAT 0:543d6784d4cc 1623 edat = 0;
EasyCAT 0:543d6784d4cc 1624 estat = 0x0000;
EasyCAT 0:543d6784d4cc 1625 if (ecx_eeprom_waitnotbusyFP(context, configadr, &estat, timeout))
EasyCAT 0:543d6784d4cc 1626 {
EasyCAT 0:543d6784d4cc 1627 do
EasyCAT 0:543d6784d4cc 1628 {
EasyCAT 0:543d6784d4cc 1629 wkc = ecx_FPRD(context->port, configadr, ECT_REG_EEPDAT, sizeof(edat), &edat, EC_TIMEOUTRET);
EasyCAT 0:543d6784d4cc 1630 }
EasyCAT 0:543d6784d4cc 1631 while ((wkc <= 0) && (cnt++ < EC_DEFAULTRETRIES));
EasyCAT 0:543d6784d4cc 1632 }
EasyCAT 0:543d6784d4cc 1633
EasyCAT 0:543d6784d4cc 1634 return edat;
EasyCAT 0:543d6784d4cc 1635 }
EasyCAT 0:543d6784d4cc 1636
EasyCAT 0:543d6784d4cc 1637 /** Push index of segmented LRD/LWR/LRW combination.
EasyCAT 0:543d6784d4cc 1638 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1639 * @param[in] idx = Used datagram index.
EasyCAT 0:543d6784d4cc 1640 * @param[in] data = Pointer to process data segment.
EasyCAT 0:543d6784d4cc 1641 * @param[in] length = Length of data segment in bytes.
EasyCAT 0:543d6784d4cc 1642 */
EasyCAT 0:543d6784d4cc 1643 static void ecx_pushindex(ecx_contextt *context, uint8 idx, void *data, uint16 length)
EasyCAT 0:543d6784d4cc 1644 {
EasyCAT 0:543d6784d4cc 1645 if(context->idxstack->pushed < EC_MAXBUF)
EasyCAT 0:543d6784d4cc 1646 {
EasyCAT 0:543d6784d4cc 1647 context->idxstack->idx[context->idxstack->pushed] = idx;
EasyCAT 0:543d6784d4cc 1648 context->idxstack->data[context->idxstack->pushed] = data;
EasyCAT 0:543d6784d4cc 1649 context->idxstack->length[context->idxstack->pushed] = length;
EasyCAT 0:543d6784d4cc 1650 context->idxstack->pushed++;
EasyCAT 0:543d6784d4cc 1651 }
EasyCAT 0:543d6784d4cc 1652 }
EasyCAT 0:543d6784d4cc 1653
EasyCAT 0:543d6784d4cc 1654 /** Pull index of segmented LRD/LWR/LRW combination.
EasyCAT 0:543d6784d4cc 1655 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1656 * @return Stack location, -1 if stack is empty.
EasyCAT 0:543d6784d4cc 1657 */
EasyCAT 0:543d6784d4cc 1658 static int ecx_pullindex(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 1659 {
EasyCAT 0:543d6784d4cc 1660 int rval = -1;
EasyCAT 0:543d6784d4cc 1661 if(context->idxstack->pulled < context->idxstack->pushed)
EasyCAT 0:543d6784d4cc 1662 {
EasyCAT 0:543d6784d4cc 1663 rval = context->idxstack->pulled;
EasyCAT 0:543d6784d4cc 1664 context->idxstack->pulled++;
EasyCAT 0:543d6784d4cc 1665 }
EasyCAT 0:543d6784d4cc 1666
EasyCAT 0:543d6784d4cc 1667 return rval;
EasyCAT 0:543d6784d4cc 1668 }
EasyCAT 0:543d6784d4cc 1669
EasyCAT 0:543d6784d4cc 1670 /**
EasyCAT 0:543d6784d4cc 1671 * Clear the idx stack.
EasyCAT 0:543d6784d4cc 1672 *
EasyCAT 0:543d6784d4cc 1673 * @param context = context struct
EasyCAT 0:543d6784d4cc 1674 */
EasyCAT 0:543d6784d4cc 1675 static void ecx_clearindex(ecx_contextt *context) {
EasyCAT 0:543d6784d4cc 1676
EasyCAT 0:543d6784d4cc 1677 context->idxstack->pushed = 0;
EasyCAT 0:543d6784d4cc 1678 context->idxstack->pulled = 0;
EasyCAT 0:543d6784d4cc 1679
EasyCAT 0:543d6784d4cc 1680 }
EasyCAT 0:543d6784d4cc 1681
EasyCAT 0:543d6784d4cc 1682 /** Transmit processdata to slaves.
EasyCAT 0:543d6784d4cc 1683 * Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
EasyCAT 0:543d6784d4cc 1684 * Both the input and output processdata are transmitted.
EasyCAT 0:543d6784d4cc 1685 * The outputs with the actual data, the inputs have a placeholder.
EasyCAT 0:543d6784d4cc 1686 * The inputs are gathered with the receive processdata function.
EasyCAT 0:543d6784d4cc 1687 * In contrast to the base LRW function this function is non-blocking.
EasyCAT 0:543d6784d4cc 1688 * If the processdata does not fit in one datagram, multiple are used.
EasyCAT 0:543d6784d4cc 1689 * In order to recombine the slave response, a stack is used.
EasyCAT 0:543d6784d4cc 1690 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1691 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 1692 * @return >0 if processdata is transmitted.
EasyCAT 0:543d6784d4cc 1693 */
EasyCAT 0:543d6784d4cc 1694 static int ecx_main_send_processdata(ecx_contextt *context, uint8 group, boolean use_overlap_io)
EasyCAT 0:543d6784d4cc 1695 {
EasyCAT 0:543d6784d4cc 1696 uint32 LogAdr;
EasyCAT 0:543d6784d4cc 1697 uint16 w1, w2;
EasyCAT 0:543d6784d4cc 1698 int length, sublength;
EasyCAT 0:543d6784d4cc 1699 uint8 idx;
EasyCAT 0:543d6784d4cc 1700 int wkc;
EasyCAT 0:543d6784d4cc 1701 uint8* data;
EasyCAT 0:543d6784d4cc 1702 boolean first=FALSE;
EasyCAT 0:543d6784d4cc 1703 uint16 currentsegment = 0;
EasyCAT 0:543d6784d4cc 1704 uint32 iomapinputoffset;
EasyCAT 0:543d6784d4cc 1705
EasyCAT 0:543d6784d4cc 1706 wkc = 0;
EasyCAT 0:543d6784d4cc 1707 if(context->grouplist[group].hasdc)
EasyCAT 0:543d6784d4cc 1708 {
EasyCAT 0:543d6784d4cc 1709 first = TRUE;
EasyCAT 0:543d6784d4cc 1710 }
EasyCAT 0:543d6784d4cc 1711
EasyCAT 0:543d6784d4cc 1712 /* For overlapping IO map use the biggest */
EasyCAT 0:543d6784d4cc 1713 if(use_overlap_io == TRUE)
EasyCAT 0:543d6784d4cc 1714 {
EasyCAT 0:543d6784d4cc 1715 /* For overlap IOmap make the frame EQ big to biggest part */
EasyCAT 0:543d6784d4cc 1716 length = (context->grouplist[group].Obytes > context->grouplist[group].Ibytes) ?
EasyCAT 0:543d6784d4cc 1717 context->grouplist[group].Obytes : context->grouplist[group].Ibytes;
EasyCAT 0:543d6784d4cc 1718 /* Save the offset used to compensate where to save inputs when frame returns */
EasyCAT 0:543d6784d4cc 1719 iomapinputoffset = context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1720 }
EasyCAT 0:543d6784d4cc 1721 else
EasyCAT 0:543d6784d4cc 1722 {
EasyCAT 0:543d6784d4cc 1723 length = context->grouplist[group].Obytes + context->grouplist[group].Ibytes;
EasyCAT 0:543d6784d4cc 1724 iomapinputoffset = 0;
EasyCAT 0:543d6784d4cc 1725 }
EasyCAT 0:543d6784d4cc 1726
EasyCAT 0:543d6784d4cc 1727 LogAdr = context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1728 if(length)
EasyCAT 0:543d6784d4cc 1729 {
EasyCAT 0:543d6784d4cc 1730
EasyCAT 0:543d6784d4cc 1731 wkc = 1;
EasyCAT 0:543d6784d4cc 1732 /* LRW blocked by one or more slaves ? */
EasyCAT 0:543d6784d4cc 1733 if(context->grouplist[group].blockLRW)
EasyCAT 0:543d6784d4cc 1734 {
EasyCAT 0:543d6784d4cc 1735 /* if inputs available generate LRD */
EasyCAT 0:543d6784d4cc 1736 if(context->grouplist[group].Ibytes)
EasyCAT 0:543d6784d4cc 1737 {
EasyCAT 0:543d6784d4cc 1738 currentsegment = context->grouplist[group].Isegment;
EasyCAT 0:543d6784d4cc 1739 data = context->grouplist[group].inputs;
EasyCAT 0:543d6784d4cc 1740 length = context->grouplist[group].Ibytes;
EasyCAT 0:543d6784d4cc 1741 LogAdr += context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1742 /* segment transfer if needed */
EasyCAT 0:543d6784d4cc 1743 do
EasyCAT 0:543d6784d4cc 1744 {
EasyCAT 0:543d6784d4cc 1745 if(currentsegment == context->grouplist[group].Isegment)
EasyCAT 0:543d6784d4cc 1746 {
EasyCAT 0:543d6784d4cc 1747 sublength = context->grouplist[group].IOsegment[currentsegment++] - context->grouplist[group].Ioffset;
EasyCAT 0:543d6784d4cc 1748 }
EasyCAT 0:543d6784d4cc 1749 else
EasyCAT 0:543d6784d4cc 1750 {
EasyCAT 0:543d6784d4cc 1751 sublength = context->grouplist[group].IOsegment[currentsegment++];
EasyCAT 0:543d6784d4cc 1752 }
EasyCAT 0:543d6784d4cc 1753 /* get new index */
EasyCAT 0:543d6784d4cc 1754 idx = ecx_getindex(context->port);
EasyCAT 0:543d6784d4cc 1755 w1 = LO_WORD(LogAdr);
EasyCAT 0:543d6784d4cc 1756 w2 = HI_WORD(LogAdr);
EasyCAT 0:543d6784d4cc 1757 ecx_setupdatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_LRD, idx, w1, w2, sublength, data);
EasyCAT 0:543d6784d4cc 1758 if(first)
EasyCAT 0:543d6784d4cc 1759 {
EasyCAT 0:543d6784d4cc 1760 context->DCl = sublength;
EasyCAT 0:543d6784d4cc 1761 /* FPRMW in second datagram */
EasyCAT 0:543d6784d4cc 1762 context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE,
EasyCAT 0:543d6784d4cc 1763 context->slavelist[context->grouplist[group].DCnext].configadr,
EasyCAT 0:543d6784d4cc 1764 ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
EasyCAT 0:543d6784d4cc 1765 first = FALSE;
EasyCAT 0:543d6784d4cc 1766 }
EasyCAT 0:543d6784d4cc 1767 /* send frame */
EasyCAT 0:543d6784d4cc 1768 ecx_outframe_red(context->port, idx);
EasyCAT 0:543d6784d4cc 1769 /* push index and data pointer on stack */
EasyCAT 0:543d6784d4cc 1770 ecx_pushindex(context, idx, data, sublength);
EasyCAT 0:543d6784d4cc 1771 length -= sublength;
EasyCAT 0:543d6784d4cc 1772 LogAdr += sublength;
EasyCAT 0:543d6784d4cc 1773 data += sublength;
EasyCAT 0:543d6784d4cc 1774 } while (length && (currentsegment < context->grouplist[group].nsegments));
EasyCAT 0:543d6784d4cc 1775 }
EasyCAT 0:543d6784d4cc 1776 /* if outputs available generate LWR */
EasyCAT 0:543d6784d4cc 1777 if(context->grouplist[group].Obytes)
EasyCAT 0:543d6784d4cc 1778 {
EasyCAT 0:543d6784d4cc 1779 data = context->grouplist[group].outputs;
EasyCAT 0:543d6784d4cc 1780 length = context->grouplist[group].Obytes;
EasyCAT 0:543d6784d4cc 1781 LogAdr = context->grouplist[group].logstartaddr;
EasyCAT 0:543d6784d4cc 1782 currentsegment = 0;
EasyCAT 0:543d6784d4cc 1783 /* segment transfer if needed */
EasyCAT 0:543d6784d4cc 1784 do
EasyCAT 0:543d6784d4cc 1785 {
EasyCAT 0:543d6784d4cc 1786 sublength = context->grouplist[group].IOsegment[currentsegment++];
EasyCAT 0:543d6784d4cc 1787 if((length - sublength) < 0)
EasyCAT 0:543d6784d4cc 1788 {
EasyCAT 0:543d6784d4cc 1789 sublength = length;
EasyCAT 0:543d6784d4cc 1790 }
EasyCAT 0:543d6784d4cc 1791 /* get new index */
EasyCAT 0:543d6784d4cc 1792 idx = ecx_getindex(context->port);
EasyCAT 0:543d6784d4cc 1793 w1 = LO_WORD(LogAdr);
EasyCAT 0:543d6784d4cc 1794 w2 = HI_WORD(LogAdr);
EasyCAT 0:543d6784d4cc 1795 ecx_setupdatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_LWR, idx, w1, w2, sublength, data);
EasyCAT 0:543d6784d4cc 1796 if(first)
EasyCAT 0:543d6784d4cc 1797 {
EasyCAT 0:543d6784d4cc 1798 context->DCl = sublength;
EasyCAT 0:543d6784d4cc 1799 /* FPRMW in second datagram */
EasyCAT 0:543d6784d4cc 1800 context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE,
EasyCAT 0:543d6784d4cc 1801 context->slavelist[context->grouplist[group].DCnext].configadr,
EasyCAT 0:543d6784d4cc 1802 ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
EasyCAT 0:543d6784d4cc 1803 first = FALSE;
EasyCAT 0:543d6784d4cc 1804 }
EasyCAT 0:543d6784d4cc 1805 /* send frame */
EasyCAT 0:543d6784d4cc 1806 ecx_outframe_red(context->port, idx);
EasyCAT 0:543d6784d4cc 1807 /* push index and data pointer on stack */
EasyCAT 0:543d6784d4cc 1808 ecx_pushindex(context, idx, data, sublength);
EasyCAT 0:543d6784d4cc 1809 length -= sublength;
EasyCAT 0:543d6784d4cc 1810 LogAdr += sublength;
EasyCAT 0:543d6784d4cc 1811 data += sublength;
EasyCAT 0:543d6784d4cc 1812 } while (length && (currentsegment < context->grouplist[group].nsegments));
EasyCAT 0:543d6784d4cc 1813 }
EasyCAT 0:543d6784d4cc 1814 }
EasyCAT 0:543d6784d4cc 1815 /* LRW can be used */
EasyCAT 0:543d6784d4cc 1816 else
EasyCAT 0:543d6784d4cc 1817 {
EasyCAT 0:543d6784d4cc 1818 if (context->grouplist[group].Obytes)
EasyCAT 0:543d6784d4cc 1819 {
EasyCAT 0:543d6784d4cc 1820 data = context->grouplist[group].outputs;
EasyCAT 0:543d6784d4cc 1821 }
EasyCAT 0:543d6784d4cc 1822 else
EasyCAT 0:543d6784d4cc 1823 {
EasyCAT 0:543d6784d4cc 1824 data = context->grouplist[group].inputs;
EasyCAT 0:543d6784d4cc 1825 /* Clear offset, don't compensate for overlapping IOmap if we only got inputs */
EasyCAT 0:543d6784d4cc 1826 iomapinputoffset = 0;
EasyCAT 0:543d6784d4cc 1827 }
EasyCAT 0:543d6784d4cc 1828 /* segment transfer if needed */
EasyCAT 0:543d6784d4cc 1829 do
EasyCAT 0:543d6784d4cc 1830 {
EasyCAT 0:543d6784d4cc 1831 sublength = context->grouplist[group].IOsegment[currentsegment++];
EasyCAT 0:543d6784d4cc 1832 /* get new index */
EasyCAT 0:543d6784d4cc 1833 idx = ecx_getindex(context->port);
EasyCAT 0:543d6784d4cc 1834 w1 = LO_WORD(LogAdr);
EasyCAT 0:543d6784d4cc 1835 w2 = HI_WORD(LogAdr);
EasyCAT 0:543d6784d4cc 1836 ecx_setupdatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_LRW, idx, w1, w2, sublength, data);
EasyCAT 0:543d6784d4cc 1837 if(first)
EasyCAT 0:543d6784d4cc 1838 {
EasyCAT 0:543d6784d4cc 1839 context->DCl = sublength;
EasyCAT 0:543d6784d4cc 1840 /* FPRMW in second datagram */
EasyCAT 0:543d6784d4cc 1841 context->DCtO = ecx_adddatagram(context->port, &(context->port->txbuf[idx]), EC_CMD_FRMW, idx, FALSE,
EasyCAT 0:543d6784d4cc 1842 context->slavelist[context->grouplist[group].DCnext].configadr,
EasyCAT 0:543d6784d4cc 1843 ECT_REG_DCSYSTIME, sizeof(int64), context->DCtime);
EasyCAT 0:543d6784d4cc 1844 first = FALSE;
EasyCAT 0:543d6784d4cc 1845 }
EasyCAT 0:543d6784d4cc 1846 /* send frame */
EasyCAT 0:543d6784d4cc 1847 ecx_outframe_red(context->port, idx);
EasyCAT 0:543d6784d4cc 1848 /* push index and data pointer on stack.
EasyCAT 0:543d6784d4cc 1849 * the iomapinputoffset compensate for where the inputs are stored
EasyCAT 0:543d6784d4cc 1850 * in the IOmap if we use an overlapping IOmap. If a regular IOmap
EasyCAT 0:543d6784d4cc 1851 * is used it should always be 0.
EasyCAT 0:543d6784d4cc 1852 */
EasyCAT 0:543d6784d4cc 1853 ecx_pushindex(context, idx, (data + iomapinputoffset), sublength);
EasyCAT 0:543d6784d4cc 1854 length -= sublength;
EasyCAT 0:543d6784d4cc 1855 LogAdr += sublength;
EasyCAT 0:543d6784d4cc 1856 data += sublength;
EasyCAT 0:543d6784d4cc 1857 } while (length && (currentsegment < context->grouplist[group].nsegments));
EasyCAT 0:543d6784d4cc 1858 }
EasyCAT 0:543d6784d4cc 1859 }
EasyCAT 0:543d6784d4cc 1860
EasyCAT 0:543d6784d4cc 1861 return wkc;
EasyCAT 0:543d6784d4cc 1862 }
EasyCAT 0:543d6784d4cc 1863
EasyCAT 0:543d6784d4cc 1864 /** Transmit processdata to slaves.
EasyCAT 0:543d6784d4cc 1865 * Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
EasyCAT 0:543d6784d4cc 1866 * Both the input and output processdata are transmitted in the overlapped IOmap.
EasyCAT 0:543d6784d4cc 1867 * The outputs with the actual data, the inputs replace the output data in the
EasyCAT 0:543d6784d4cc 1868 * returning frame. The inputs are gathered with the receive processdata function.
EasyCAT 0:543d6784d4cc 1869 * In contrast to the base LRW function this function is non-blocking.
EasyCAT 0:543d6784d4cc 1870 * If the processdata does not fit in one datagram, multiple are used.
EasyCAT 0:543d6784d4cc 1871 * In order to recombine the slave response, a stack is used.
EasyCAT 0:543d6784d4cc 1872 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1873 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 1874 * @return >0 if processdata is transmitted.
EasyCAT 0:543d6784d4cc 1875 */
EasyCAT 0:543d6784d4cc 1876 int ecx_send_overlap_processdata_group(ecx_contextt *context, uint8 group)
EasyCAT 0:543d6784d4cc 1877 {
EasyCAT 0:543d6784d4cc 1878 return ecx_main_send_processdata(context, group, TRUE);
EasyCAT 0:543d6784d4cc 1879 }
EasyCAT 0:543d6784d4cc 1880
EasyCAT 0:543d6784d4cc 1881 /** Transmit processdata to slaves.
EasyCAT 0:543d6784d4cc 1882 * Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
EasyCAT 0:543d6784d4cc 1883 * Both the input and output processdata are transmitted.
EasyCAT 0:543d6784d4cc 1884 * The outputs with the actual data, the inputs have a placeholder.
EasyCAT 0:543d6784d4cc 1885 * The inputs are gathered with the receive processdata function.
EasyCAT 0:543d6784d4cc 1886 * In contrast to the base LRW function this function is non-blocking.
EasyCAT 0:543d6784d4cc 1887 * If the processdata does not fit in one datagram, multiple are used.
EasyCAT 0:543d6784d4cc 1888 * In order to recombine the slave response, a stack is used.
EasyCAT 0:543d6784d4cc 1889 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1890 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 1891 * @return >0 if processdata is transmitted.
EasyCAT 0:543d6784d4cc 1892 */
EasyCAT 0:543d6784d4cc 1893 int ecx_send_processdata_group(ecx_contextt *context, uint8 group)
EasyCAT 0:543d6784d4cc 1894 {
EasyCAT 0:543d6784d4cc 1895 return ecx_main_send_processdata(context, group, FALSE);
EasyCAT 0:543d6784d4cc 1896 }
EasyCAT 0:543d6784d4cc 1897
EasyCAT 0:543d6784d4cc 1898 /** Receive processdata from slaves.
EasyCAT 0:543d6784d4cc 1899 * Second part from ec_send_processdata().
EasyCAT 0:543d6784d4cc 1900 * Received datagrams are recombined with the processdata with help from the stack.
EasyCAT 0:543d6784d4cc 1901 * If a datagram contains input processdata it copies it to the processdata structure.
EasyCAT 0:543d6784d4cc 1902 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1903 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 1904 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 1905 * @return Work counter.
EasyCAT 0:543d6784d4cc 1906 */
EasyCAT 0:543d6784d4cc 1907 int ecx_receive_processdata_group(ecx_contextt *context, uint8 group, int timeout)
EasyCAT 0:543d6784d4cc 1908 {
EasyCAT 0:543d6784d4cc 1909 int pos, idx;
EasyCAT 0:543d6784d4cc 1910 int wkc = 0, wkc2;
EasyCAT 0:543d6784d4cc 1911 uint16 le_wkc = 0;
EasyCAT 0:543d6784d4cc 1912 int valid_wkc = 0;
EasyCAT 0:543d6784d4cc 1913 int64 le_DCtime;
EasyCAT 0:543d6784d4cc 1914 boolean first = FALSE;
EasyCAT 0:543d6784d4cc 1915
EasyCAT 0:543d6784d4cc 1916 if(context->grouplist[group].hasdc)
EasyCAT 0:543d6784d4cc 1917 {
EasyCAT 0:543d6784d4cc 1918 first = TRUE;
EasyCAT 0:543d6784d4cc 1919 }
EasyCAT 0:543d6784d4cc 1920 /* get first index */
EasyCAT 0:543d6784d4cc 1921 pos = ecx_pullindex(context);
EasyCAT 0:543d6784d4cc 1922 /* read the same number of frames as send */
EasyCAT 0:543d6784d4cc 1923 while (pos >= 0)
EasyCAT 0:543d6784d4cc 1924 {
EasyCAT 0:543d6784d4cc 1925 idx = context->idxstack->idx[pos];
EasyCAT 0:543d6784d4cc 1926 wkc2 = ecx_waitinframe(context->port, context->idxstack->idx[pos], timeout);
EasyCAT 0:543d6784d4cc 1927 /* check if there is input data in frame */
EasyCAT 0:543d6784d4cc 1928 if (wkc2 > EC_NOFRAME)
EasyCAT 0:543d6784d4cc 1929 {
EasyCAT 0:543d6784d4cc 1930 if((context->port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LRD) || (context->port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LRW))
EasyCAT 0:543d6784d4cc 1931 {
EasyCAT 0:543d6784d4cc 1932 if(first)
EasyCAT 0:543d6784d4cc 1933 {
EasyCAT 0:543d6784d4cc 1934 memcpy(context->idxstack->data[pos], &(context->port->rxbuf[idx][EC_HEADERSIZE]), context->DCl);
EasyCAT 0:543d6784d4cc 1935 memcpy(&le_wkc, &(context->port->rxbuf[idx][EC_HEADERSIZE + context->DCl]), EC_WKCSIZE);
EasyCAT 0:543d6784d4cc 1936 wkc = etohs(le_wkc);
EasyCAT 0:543d6784d4cc 1937 memcpy(&le_DCtime, &(context->port->rxbuf[idx][context->DCtO]), sizeof(le_DCtime));
EasyCAT 0:543d6784d4cc 1938 *(context->DCtime) = etohll(le_DCtime);
EasyCAT 0:543d6784d4cc 1939 first = FALSE;
EasyCAT 0:543d6784d4cc 1940 }
EasyCAT 0:543d6784d4cc 1941 else
EasyCAT 0:543d6784d4cc 1942 {
EasyCAT 0:543d6784d4cc 1943 /* copy input data back to process data buffer */
EasyCAT 0:543d6784d4cc 1944 memcpy(context->idxstack->data[pos], &(context->port->rxbuf[idx][EC_HEADERSIZE]), context->idxstack->length[pos]);
EasyCAT 0:543d6784d4cc 1945 wkc += wkc2;
EasyCAT 0:543d6784d4cc 1946 }
EasyCAT 0:543d6784d4cc 1947 valid_wkc = 1;
EasyCAT 0:543d6784d4cc 1948 }
EasyCAT 0:543d6784d4cc 1949 else if(context->port->rxbuf[idx][EC_CMDOFFSET]==EC_CMD_LWR)
EasyCAT 0:543d6784d4cc 1950 {
EasyCAT 0:543d6784d4cc 1951 if(first)
EasyCAT 0:543d6784d4cc 1952 {
EasyCAT 0:543d6784d4cc 1953 memcpy(&le_wkc, &(context->port->rxbuf[idx][EC_HEADERSIZE + context->DCl]), EC_WKCSIZE);
EasyCAT 0:543d6784d4cc 1954 /* output WKC counts 2 times when using LRW, emulate the same for LWR */
EasyCAT 0:543d6784d4cc 1955 wkc = etohs(le_wkc) * 2;
EasyCAT 0:543d6784d4cc 1956 memcpy(&le_DCtime, &(context->port->rxbuf[idx][context->DCtO]), sizeof(le_DCtime));
EasyCAT 0:543d6784d4cc 1957 *(context->DCtime) = etohll(le_DCtime);
EasyCAT 0:543d6784d4cc 1958 first = FALSE;
EasyCAT 0:543d6784d4cc 1959 }
EasyCAT 0:543d6784d4cc 1960 else
EasyCAT 0:543d6784d4cc 1961 {
EasyCAT 0:543d6784d4cc 1962 /* output WKC counts 2 times when using LRW, emulate the same for LWR */
EasyCAT 0:543d6784d4cc 1963 wkc += wkc2 * 2;
EasyCAT 0:543d6784d4cc 1964 }
EasyCAT 0:543d6784d4cc 1965 valid_wkc = 1;
EasyCAT 0:543d6784d4cc 1966 }
EasyCAT 0:543d6784d4cc 1967 }
EasyCAT 0:543d6784d4cc 1968 /* release buffer */
EasyCAT 0:543d6784d4cc 1969 ecx_setbufstat(context->port, idx, EC_BUF_EMPTY);
EasyCAT 0:543d6784d4cc 1970 /* get next index */
EasyCAT 0:543d6784d4cc 1971 pos = ecx_pullindex(context);
EasyCAT 0:543d6784d4cc 1972 }
EasyCAT 0:543d6784d4cc 1973
EasyCAT 0:543d6784d4cc 1974 ecx_clearindex(context);
EasyCAT 0:543d6784d4cc 1975
EasyCAT 0:543d6784d4cc 1976 /* if no frames has arrived */
EasyCAT 0:543d6784d4cc 1977 if (valid_wkc == 0)
EasyCAT 0:543d6784d4cc 1978 {
EasyCAT 0:543d6784d4cc 1979 return EC_NOFRAME;
EasyCAT 0:543d6784d4cc 1980 }
EasyCAT 0:543d6784d4cc 1981 return wkc;
EasyCAT 0:543d6784d4cc 1982 }
EasyCAT 0:543d6784d4cc 1983
EasyCAT 0:543d6784d4cc 1984
EasyCAT 0:543d6784d4cc 1985 int ecx_send_processdata(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 1986 {
EasyCAT 0:543d6784d4cc 1987 return ecx_send_processdata_group(context, 0);
EasyCAT 0:543d6784d4cc 1988 }
EasyCAT 0:543d6784d4cc 1989
EasyCAT 0:543d6784d4cc 1990 int ecx_send_overlap_processdata(ecx_contextt *context)
EasyCAT 0:543d6784d4cc 1991 {
EasyCAT 0:543d6784d4cc 1992 return ecx_send_overlap_processdata_group(context, 0);
EasyCAT 0:543d6784d4cc 1993 }
EasyCAT 0:543d6784d4cc 1994
EasyCAT 0:543d6784d4cc 1995 int ecx_receive_processdata(ecx_contextt *context, int timeout)
EasyCAT 0:543d6784d4cc 1996 {
EasyCAT 0:543d6784d4cc 1997 return ecx_receive_processdata_group(context, 0, timeout);
EasyCAT 0:543d6784d4cc 1998 }
EasyCAT 0:543d6784d4cc 1999
EasyCAT 0:543d6784d4cc 2000 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 2001 void ec_pusherror(const ec_errort *Ec)
EasyCAT 0:543d6784d4cc 2002 {
EasyCAT 0:543d6784d4cc 2003 ecx_pusherror(&ecx_context, Ec);
EasyCAT 0:543d6784d4cc 2004 }
EasyCAT 0:543d6784d4cc 2005
EasyCAT 0:543d6784d4cc 2006 boolean ec_poperror(ec_errort *Ec)
EasyCAT 0:543d6784d4cc 2007 {
EasyCAT 0:543d6784d4cc 2008 return ecx_poperror(&ecx_context, Ec);
EasyCAT 0:543d6784d4cc 2009 }
EasyCAT 0:543d6784d4cc 2010
EasyCAT 0:543d6784d4cc 2011 boolean ec_iserror(void)
EasyCAT 0:543d6784d4cc 2012 {
EasyCAT 0:543d6784d4cc 2013 return ecx_iserror(&ecx_context);
EasyCAT 0:543d6784d4cc 2014 }
EasyCAT 0:543d6784d4cc 2015
EasyCAT 0:543d6784d4cc 2016 void ec_packeterror(uint16 Slave, uint16 Index, uint8 SubIdx, uint16 ErrorCode)
EasyCAT 0:543d6784d4cc 2017 {
EasyCAT 0:543d6784d4cc 2018 ecx_packeterror(&ecx_context, Slave, Index, SubIdx, ErrorCode);
EasyCAT 0:543d6784d4cc 2019 }
EasyCAT 0:543d6784d4cc 2020
EasyCAT 0:543d6784d4cc 2021 /** Initialise lib in single NIC mode
EasyCAT 0:543d6784d4cc 2022 * @param[in] ifname = Dev name, f.e. "eth0"
EasyCAT 0:543d6784d4cc 2023 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2024 * @see ecx_init
EasyCAT 0:543d6784d4cc 2025 */
EasyCAT 0:543d6784d4cc 2026 int ec_init(const char * ifname)
EasyCAT 0:543d6784d4cc 2027 {
EasyCAT 0:543d6784d4cc 2028 return ecx_init(&ecx_context, ifname);
EasyCAT 0:543d6784d4cc 2029 }
EasyCAT 0:543d6784d4cc 2030
EasyCAT 0:543d6784d4cc 2031 /** Initialise lib in redundant NIC mode
EasyCAT 0:543d6784d4cc 2032 * @param[in] ifname = Primary Dev name, f.e. "eth0"
EasyCAT 0:543d6784d4cc 2033 * @param[in] if2name = Secondary Dev name, f.e. "eth1"
EasyCAT 0:543d6784d4cc 2034 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2035 * @see ecx_init_redundant
EasyCAT 0:543d6784d4cc 2036 */
EasyCAT 0:543d6784d4cc 2037 int ec_init_redundant(const char *ifname, char *if2name)
EasyCAT 0:543d6784d4cc 2038 {
EasyCAT 0:543d6784d4cc 2039 return ecx_init_redundant (&ecx_context, &ecx_redport, ifname, if2name);
EasyCAT 0:543d6784d4cc 2040 }
EasyCAT 0:543d6784d4cc 2041
EasyCAT 0:543d6784d4cc 2042 /** Close lib.
EasyCAT 0:543d6784d4cc 2043 * @see ecx_close
EasyCAT 0:543d6784d4cc 2044 */
EasyCAT 0:543d6784d4cc 2045 void ec_close(void)
EasyCAT 0:543d6784d4cc 2046 {
EasyCAT 0:543d6784d4cc 2047 ecx_close(&ecx_context);
EasyCAT 0:543d6784d4cc 2048 };
EasyCAT 0:543d6784d4cc 2049
EasyCAT 0:543d6784d4cc 2050 /** Read one byte from slave EEPROM via cache.
EasyCAT 0:543d6784d4cc 2051 * If the cache location is empty then a read request is made to the slave.
EasyCAT 0:543d6784d4cc 2052 * Depending on the slave capabillities the request is 4 or 8 bytes.
EasyCAT 0:543d6784d4cc 2053 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2054 * @param[in] address = eeprom address in bytes (slave uses words)
EasyCAT 0:543d6784d4cc 2055 * @return requested byte, if not available then 0xff
EasyCAT 0:543d6784d4cc 2056 * @see ecx_siigetbyte
EasyCAT 0:543d6784d4cc 2057 */
EasyCAT 0:543d6784d4cc 2058 uint8 ec_siigetbyte(uint16 slave, uint16 address)
EasyCAT 0:543d6784d4cc 2059 {
EasyCAT 0:543d6784d4cc 2060 return ecx_siigetbyte (&ecx_context, slave, address);
EasyCAT 0:543d6784d4cc 2061 }
EasyCAT 0:543d6784d4cc 2062
EasyCAT 0:543d6784d4cc 2063 /** Find SII section header in slave EEPROM.
EasyCAT 0:543d6784d4cc 2064 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2065 * @param[in] cat = section category
EasyCAT 0:543d6784d4cc 2066 * @return byte address of section at section length entry, if not available then 0
EasyCAT 0:543d6784d4cc 2067 * @see ecx_siifind
EasyCAT 0:543d6784d4cc 2068 */
EasyCAT 0:543d6784d4cc 2069 int16 ec_siifind(uint16 slave, uint16 cat)
EasyCAT 0:543d6784d4cc 2070 {
EasyCAT 0:543d6784d4cc 2071 return ecx_siifind (&ecx_context, slave, cat);
EasyCAT 0:543d6784d4cc 2072 }
EasyCAT 0:543d6784d4cc 2073
EasyCAT 0:543d6784d4cc 2074 /** Get string from SII string section in slave EEPROM.
EasyCAT 0:543d6784d4cc 2075 * @param[out] str = requested string, 0x00 if not found
EasyCAT 0:543d6784d4cc 2076 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2077 * @param[in] Sn = string number
EasyCAT 0:543d6784d4cc 2078 * @see ecx_siistring
EasyCAT 0:543d6784d4cc 2079 */
EasyCAT 0:543d6784d4cc 2080 void ec_siistring(char *str, uint16 slave, uint16 Sn)
EasyCAT 0:543d6784d4cc 2081 {
EasyCAT 0:543d6784d4cc 2082 ecx_siistring(&ecx_context, str, slave, Sn);
EasyCAT 0:543d6784d4cc 2083 }
EasyCAT 0:543d6784d4cc 2084
EasyCAT 0:543d6784d4cc 2085 /** Get FMMU data from SII FMMU section in slave EEPROM.
EasyCAT 0:543d6784d4cc 2086 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2087 * @param[out] FMMU = FMMU struct from SII, max. 4 FMMU's
EasyCAT 0:543d6784d4cc 2088 * @return number of FMMU's defined in section
EasyCAT 0:543d6784d4cc 2089 * @see ecx_siiFMMU
EasyCAT 0:543d6784d4cc 2090 */
EasyCAT 0:543d6784d4cc 2091 uint16 ec_siiFMMU(uint16 slave, ec_eepromFMMUt* FMMU)
EasyCAT 0:543d6784d4cc 2092 {
EasyCAT 0:543d6784d4cc 2093 return ecx_siiFMMU (&ecx_context, slave, FMMU);
EasyCAT 0:543d6784d4cc 2094 }
EasyCAT 0:543d6784d4cc 2095
EasyCAT 0:543d6784d4cc 2096 /** Get SM data from SII SM section in slave EEPROM.
EasyCAT 0:543d6784d4cc 2097 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2098 * @param[out] SM = first SM struct from SII
EasyCAT 0:543d6784d4cc 2099 * @return number of SM's defined in section
EasyCAT 0:543d6784d4cc 2100 * @see ecx_siiSM
EasyCAT 0:543d6784d4cc 2101 */
EasyCAT 0:543d6784d4cc 2102 uint16 ec_siiSM(uint16 slave, ec_eepromSMt* SM)
EasyCAT 0:543d6784d4cc 2103 {
EasyCAT 0:543d6784d4cc 2104 return ecx_siiSM (&ecx_context, slave, SM);
EasyCAT 0:543d6784d4cc 2105 }
EasyCAT 0:543d6784d4cc 2106
EasyCAT 0:543d6784d4cc 2107 /** Get next SM data from SII SM section in slave EEPROM.
EasyCAT 0:543d6784d4cc 2108 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2109 * @param[out] SM = first SM struct from SII
EasyCAT 0:543d6784d4cc 2110 * @param[in] n = SM number
EasyCAT 0:543d6784d4cc 2111 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2112 * @see ecx_siiSMnext
EasyCAT 0:543d6784d4cc 2113 */
EasyCAT 0:543d6784d4cc 2114 uint16 ec_siiSMnext(uint16 slave, ec_eepromSMt* SM, uint16 n)
EasyCAT 0:543d6784d4cc 2115 {
EasyCAT 0:543d6784d4cc 2116 return ecx_siiSMnext (&ecx_context, slave, SM, n);
EasyCAT 0:543d6784d4cc 2117 }
EasyCAT 0:543d6784d4cc 2118
EasyCAT 0:543d6784d4cc 2119 /** Get PDO data from SII PDO section in slave EEPROM.
EasyCAT 0:543d6784d4cc 2120 * @param[in] slave = slave number
EasyCAT 0:543d6784d4cc 2121 * @param[out] PDO = PDO struct from SII
EasyCAT 0:543d6784d4cc 2122 * @param[in] t = 0=RXPDO 1=TXPDO
EasyCAT 0:543d6784d4cc 2123 * @return mapping size in bits of PDO
EasyCAT 0:543d6784d4cc 2124 * @see ecx_siiPDO
EasyCAT 0:543d6784d4cc 2125 */
EasyCAT 0:543d6784d4cc 2126 int ec_siiPDO(uint16 slave, ec_eepromPDOt* PDO, uint8 t)
EasyCAT 0:543d6784d4cc 2127 {
EasyCAT 0:543d6784d4cc 2128 return ecx_siiPDO (&ecx_context, slave, PDO, t);
EasyCAT 0:543d6784d4cc 2129 }
EasyCAT 0:543d6784d4cc 2130
EasyCAT 0:543d6784d4cc 2131 /** Read all slave states in ec_slave.
EasyCAT 0:543d6784d4cc 2132 * @return lowest state found
EasyCAT 0:543d6784d4cc 2133 * @see ecx_readstate
EasyCAT 0:543d6784d4cc 2134 */
EasyCAT 0:543d6784d4cc 2135 int ec_readstate(void)
EasyCAT 0:543d6784d4cc 2136 {
EasyCAT 0:543d6784d4cc 2137 return ecx_readstate (&ecx_context);
EasyCAT 0:543d6784d4cc 2138 }
EasyCAT 0:543d6784d4cc 2139
EasyCAT 0:543d6784d4cc 2140 /** Write slave state, if slave = 0 then write to all slaves.
EasyCAT 0:543d6784d4cc 2141 * The function does not check if the actual state is changed.
EasyCAT 0:543d6784d4cc 2142 * @param[in] slave = Slave number, 0 = master
EasyCAT 0:543d6784d4cc 2143 * @return 0
EasyCAT 0:543d6784d4cc 2144 * @see ecx_writestate
EasyCAT 0:543d6784d4cc 2145 */
EasyCAT 0:543d6784d4cc 2146 int ec_writestate(uint16 slave)
EasyCAT 0:543d6784d4cc 2147 {
EasyCAT 0:543d6784d4cc 2148 return ecx_writestate(&ecx_context, slave);
EasyCAT 0:543d6784d4cc 2149 }
EasyCAT 0:543d6784d4cc 2150
EasyCAT 0:543d6784d4cc 2151 /** Check actual slave state.
EasyCAT 0:543d6784d4cc 2152 * This is a blocking function.
EasyCAT 0:543d6784d4cc 2153 * @param[in] slave = Slave number, 0 = all slaves
EasyCAT 0:543d6784d4cc 2154 * @param[in] reqstate = Requested state
EasyCAT 0:543d6784d4cc 2155 * @param[in] timeout = Timeout value in us
EasyCAT 0:543d6784d4cc 2156 * @return Requested state, or found state after timeout.
EasyCAT 0:543d6784d4cc 2157 * @see ecx_statecheck
EasyCAT 0:543d6784d4cc 2158 */
EasyCAT 0:543d6784d4cc 2159 uint16 ec_statecheck(uint16 slave, uint16 reqstate, int timeout)
EasyCAT 0:543d6784d4cc 2160 {
EasyCAT 0:543d6784d4cc 2161 return ecx_statecheck (&ecx_context, slave, reqstate, timeout);
EasyCAT 0:543d6784d4cc 2162 }
EasyCAT 0:543d6784d4cc 2163
EasyCAT 0:543d6784d4cc 2164 /** Check if IN mailbox of slave is empty.
EasyCAT 0:543d6784d4cc 2165 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2166 * @param[in] timeout = Timeout in us
EasyCAT 0:543d6784d4cc 2167 * @return >0 is success
EasyCAT 0:543d6784d4cc 2168 * @see ecx_mbxempty
EasyCAT 0:543d6784d4cc 2169 */
EasyCAT 0:543d6784d4cc 2170 int ec_mbxempty(uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 2171 {
EasyCAT 0:543d6784d4cc 2172 return ecx_mbxempty (&ecx_context, slave, timeout);
EasyCAT 0:543d6784d4cc 2173 }
EasyCAT 0:543d6784d4cc 2174
EasyCAT 0:543d6784d4cc 2175 /** Write IN mailbox to slave.
EasyCAT 0:543d6784d4cc 2176 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2177 * @param[out] mbx = Mailbox data
EasyCAT 0:543d6784d4cc 2178 * @param[in] timeout = Timeout in us
EasyCAT 0:543d6784d4cc 2179 * @return Work counter (>0 is success)
EasyCAT 0:543d6784d4cc 2180 * @see ecx_mbxsend
EasyCAT 0:543d6784d4cc 2181 */
EasyCAT 0:543d6784d4cc 2182 int ec_mbxsend(uint16 slave,ec_mbxbuft *mbx, int timeout)
EasyCAT 0:543d6784d4cc 2183 {
EasyCAT 0:543d6784d4cc 2184 return ecx_mbxsend (&ecx_context, slave, mbx, timeout);
EasyCAT 0:543d6784d4cc 2185 }
EasyCAT 0:543d6784d4cc 2186
EasyCAT 0:543d6784d4cc 2187 /** Read OUT mailbox from slave.
EasyCAT 0:543d6784d4cc 2188 * Supports Mailbox Link Layer with repeat requests.
EasyCAT 0:543d6784d4cc 2189 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2190 * @param[out] mbx = Mailbox data
EasyCAT 0:543d6784d4cc 2191 * @param[in] timeout = Timeout in us
EasyCAT 0:543d6784d4cc 2192 * @return Work counter (>0 is success)
EasyCAT 0:543d6784d4cc 2193 * @see ecx_mbxreceive
EasyCAT 0:543d6784d4cc 2194 */
EasyCAT 0:543d6784d4cc 2195 int ec_mbxreceive(uint16 slave, ec_mbxbuft *mbx, int timeout)
EasyCAT 0:543d6784d4cc 2196 {
EasyCAT 0:543d6784d4cc 2197 return ecx_mbxreceive (&ecx_context, slave, mbx, timeout);
EasyCAT 0:543d6784d4cc 2198 }
EasyCAT 0:543d6784d4cc 2199
EasyCAT 0:543d6784d4cc 2200 /** Dump complete EEPROM data from slave in buffer.
EasyCAT 0:543d6784d4cc 2201 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2202 * @param[out] esibuf = EEPROM data buffer, make sure it is big enough.
EasyCAT 0:543d6784d4cc 2203 * @see ecx_esidump
EasyCAT 0:543d6784d4cc 2204 */
EasyCAT 0:543d6784d4cc 2205 void ec_esidump(uint16 slave, uint8 *esibuf)
EasyCAT 0:543d6784d4cc 2206 {
EasyCAT 0:543d6784d4cc 2207 ecx_esidump (&ecx_context, slave, esibuf);
EasyCAT 0:543d6784d4cc 2208 }
EasyCAT 0:543d6784d4cc 2209
EasyCAT 0:543d6784d4cc 2210 /** Read EEPROM from slave bypassing cache.
EasyCAT 0:543d6784d4cc 2211 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2212 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2213 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2214 * @return EEPROM data 32bit
EasyCAT 0:543d6784d4cc 2215 * @see ecx_readeeprom
EasyCAT 0:543d6784d4cc 2216 */
EasyCAT 0:543d6784d4cc 2217 uint32 ec_readeeprom(uint16 slave, uint16 eeproma, int timeout)
EasyCAT 0:543d6784d4cc 2218 {
EasyCAT 0:543d6784d4cc 2219 return ecx_readeeprom (&ecx_context, slave, eeproma, timeout);
EasyCAT 0:543d6784d4cc 2220 }
EasyCAT 0:543d6784d4cc 2221
EasyCAT 0:543d6784d4cc 2222 /** Write EEPROM to slave bypassing cache.
EasyCAT 0:543d6784d4cc 2223 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2224 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2225 * @param[in] data = 16bit data
EasyCAT 0:543d6784d4cc 2226 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2227 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2228 * @see ecx_writeeeprom
EasyCAT 0:543d6784d4cc 2229 */
EasyCAT 0:543d6784d4cc 2230 int ec_writeeeprom(uint16 slave, uint16 eeproma, uint16 data, int timeout)
EasyCAT 0:543d6784d4cc 2231 {
EasyCAT 0:543d6784d4cc 2232 return ecx_writeeeprom (&ecx_context, slave, eeproma, data, timeout);
EasyCAT 0:543d6784d4cc 2233 }
EasyCAT 0:543d6784d4cc 2234
EasyCAT 0:543d6784d4cc 2235 /** Set eeprom control to master. Only if set to PDI.
EasyCAT 0:543d6784d4cc 2236 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2237 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2238 * @see ecx_eeprom2master
EasyCAT 0:543d6784d4cc 2239 */
EasyCAT 0:543d6784d4cc 2240 int ec_eeprom2master(uint16 slave)
EasyCAT 0:543d6784d4cc 2241 {
EasyCAT 0:543d6784d4cc 2242 return ecx_eeprom2master(&ecx_context, slave);
EasyCAT 0:543d6784d4cc 2243 }
EasyCAT 0:543d6784d4cc 2244
EasyCAT 0:543d6784d4cc 2245 int ec_eeprom2pdi(uint16 slave)
EasyCAT 0:543d6784d4cc 2246 {
EasyCAT 0:543d6784d4cc 2247 return ecx_eeprom2pdi(&ecx_context, slave);
EasyCAT 0:543d6784d4cc 2248 }
EasyCAT 0:543d6784d4cc 2249
EasyCAT 0:543d6784d4cc 2250 uint16 ec_eeprom_waitnotbusyAP(uint16 aiadr,uint16 *estat, int timeout)
EasyCAT 0:543d6784d4cc 2251 {
EasyCAT 0:543d6784d4cc 2252 return ecx_eeprom_waitnotbusyAP (&ecx_context, aiadr, estat, timeout);
EasyCAT 0:543d6784d4cc 2253 }
EasyCAT 0:543d6784d4cc 2254
EasyCAT 0:543d6784d4cc 2255 /** Read EEPROM from slave bypassing cache. APRD method.
EasyCAT 0:543d6784d4cc 2256 * @param[in] aiadr = auto increment address of slave
EasyCAT 0:543d6784d4cc 2257 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2258 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2259 * @return EEPROM data 64bit or 32bit
EasyCAT 0:543d6784d4cc 2260 */
EasyCAT 0:543d6784d4cc 2261 uint64 ec_readeepromAP(uint16 aiadr, uint16 eeproma, int timeout)
EasyCAT 0:543d6784d4cc 2262 {
EasyCAT 0:543d6784d4cc 2263 return ecx_readeepromAP (&ecx_context, aiadr, eeproma, timeout);
EasyCAT 0:543d6784d4cc 2264 }
EasyCAT 0:543d6784d4cc 2265
EasyCAT 0:543d6784d4cc 2266 /** Write EEPROM to slave bypassing cache. APWR method.
EasyCAT 0:543d6784d4cc 2267 * @param[in] aiadr = configured address of slave
EasyCAT 0:543d6784d4cc 2268 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2269 * @param[in] data = 16bit data
EasyCAT 0:543d6784d4cc 2270 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2271 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2272 * @see ecx_writeeepromAP
EasyCAT 0:543d6784d4cc 2273 */
EasyCAT 0:543d6784d4cc 2274 int ec_writeeepromAP(uint16 aiadr, uint16 eeproma, uint16 data, int timeout)
EasyCAT 0:543d6784d4cc 2275 {
EasyCAT 0:543d6784d4cc 2276 return ecx_writeeepromAP (&ecx_context, aiadr, eeproma, data, timeout);
EasyCAT 0:543d6784d4cc 2277 }
EasyCAT 0:543d6784d4cc 2278
EasyCAT 0:543d6784d4cc 2279 uint16 ec_eeprom_waitnotbusyFP(uint16 configadr,uint16 *estat, int timeout)
EasyCAT 0:543d6784d4cc 2280 {
EasyCAT 0:543d6784d4cc 2281 return ecx_eeprom_waitnotbusyFP (&ecx_context, configadr, estat, timeout);
EasyCAT 0:543d6784d4cc 2282 }
EasyCAT 0:543d6784d4cc 2283
EasyCAT 0:543d6784d4cc 2284 /** Read EEPROM from slave bypassing cache. FPRD method.
EasyCAT 0:543d6784d4cc 2285 * @param[in] configadr = configured address of slave
EasyCAT 0:543d6784d4cc 2286 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2287 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2288 * @return EEPROM data 64bit or 32bit
EasyCAT 0:543d6784d4cc 2289 * @see ecx_readeepromFP
EasyCAT 0:543d6784d4cc 2290 */
EasyCAT 0:543d6784d4cc 2291 uint64 ec_readeepromFP(uint16 configadr, uint16 eeproma, int timeout)
EasyCAT 0:543d6784d4cc 2292 {
EasyCAT 0:543d6784d4cc 2293 return ecx_readeepromFP (&ecx_context, configadr, eeproma, timeout);
EasyCAT 0:543d6784d4cc 2294 }
EasyCAT 0:543d6784d4cc 2295
EasyCAT 0:543d6784d4cc 2296 /** Write EEPROM to slave bypassing cache. FPWR method.
EasyCAT 0:543d6784d4cc 2297 * @param[in] configadr = configured address of slave
EasyCAT 0:543d6784d4cc 2298 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2299 * @param[in] data = 16bit data
EasyCAT 0:543d6784d4cc 2300 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2301 * @return >0 if OK
EasyCAT 0:543d6784d4cc 2302 * @see ecx_writeeepromFP
EasyCAT 0:543d6784d4cc 2303 */
EasyCAT 0:543d6784d4cc 2304 int ec_writeeepromFP(uint16 configadr, uint16 eeproma, uint16 data, int timeout)
EasyCAT 0:543d6784d4cc 2305 {
EasyCAT 0:543d6784d4cc 2306 return ecx_writeeepromFP (&ecx_context, configadr, eeproma, data, timeout);
EasyCAT 0:543d6784d4cc 2307 }
EasyCAT 0:543d6784d4cc 2308
EasyCAT 0:543d6784d4cc 2309 /** Read EEPROM from slave bypassing cache.
EasyCAT 0:543d6784d4cc 2310 * Parallel read step 1, make request to slave.
EasyCAT 0:543d6784d4cc 2311 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2312 * @param[in] eeproma = (WORD) Address in the EEPROM
EasyCAT 0:543d6784d4cc 2313 * @see ecx_readeeprom1
EasyCAT 0:543d6784d4cc 2314 */
EasyCAT 0:543d6784d4cc 2315 void ec_readeeprom1(uint16 slave, uint16 eeproma)
EasyCAT 0:543d6784d4cc 2316 {
EasyCAT 0:543d6784d4cc 2317 ecx_readeeprom1 (&ecx_context, slave, eeproma);
EasyCAT 0:543d6784d4cc 2318 }
EasyCAT 0:543d6784d4cc 2319
EasyCAT 0:543d6784d4cc 2320 /** Read EEPROM from slave bypassing cache.
EasyCAT 0:543d6784d4cc 2321 * Parallel read step 2, actual read from slave.
EasyCAT 0:543d6784d4cc 2322 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 2323 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2324 * @return EEPROM data 32bit
EasyCAT 0:543d6784d4cc 2325 * @see ecx_readeeprom2
EasyCAT 0:543d6784d4cc 2326 */
EasyCAT 0:543d6784d4cc 2327 uint32 ec_readeeprom2(uint16 slave, int timeout)
EasyCAT 0:543d6784d4cc 2328 {
EasyCAT 0:543d6784d4cc 2329 return ecx_readeeprom2 (&ecx_context, slave, timeout);
EasyCAT 0:543d6784d4cc 2330 }
EasyCAT 0:543d6784d4cc 2331
EasyCAT 0:543d6784d4cc 2332 /** Transmit processdata to slaves.
EasyCAT 0:543d6784d4cc 2333 * Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
EasyCAT 0:543d6784d4cc 2334 * Both the input and output processdata are transmitted.
EasyCAT 0:543d6784d4cc 2335 * The outputs with the actual data, the inputs have a placeholder.
EasyCAT 0:543d6784d4cc 2336 * The inputs are gathered with the receive processdata function.
EasyCAT 0:543d6784d4cc 2337 * In contrast to the base LRW function this function is non-blocking.
EasyCAT 0:543d6784d4cc 2338 * If the processdata does not fit in one datagram, multiple are used.
EasyCAT 0:543d6784d4cc 2339 * In order to recombine the slave response, a stack is used.
EasyCAT 0:543d6784d4cc 2340 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 2341 * @return >0 if processdata is transmitted.
EasyCAT 0:543d6784d4cc 2342 * @see ecx_send_processdata_group
EasyCAT 0:543d6784d4cc 2343 */
EasyCAT 0:543d6784d4cc 2344 int ec_send_processdata_group(uint8 group)
EasyCAT 0:543d6784d4cc 2345 {
EasyCAT 0:543d6784d4cc 2346 return ecx_send_processdata_group (&ecx_context, group);
EasyCAT 0:543d6784d4cc 2347 }
EasyCAT 0:543d6784d4cc 2348
EasyCAT 0:543d6784d4cc 2349 /** Transmit processdata to slaves.
EasyCAT 0:543d6784d4cc 2350 * Uses LRW, or LRD/LWR if LRW is not allowed (blockLRW).
EasyCAT 0:543d6784d4cc 2351 * Both the input and output processdata are transmitted in the overlapped IOmap.
EasyCAT 0:543d6784d4cc 2352 * The outputs with the actual data, the inputs replace the output data in the
EasyCAT 0:543d6784d4cc 2353 * returning frame. The inputs are gathered with the receive processdata function.
EasyCAT 0:543d6784d4cc 2354 * In contrast to the base LRW function this function is non-blocking.
EasyCAT 0:543d6784d4cc 2355 * If the processdata does not fit in one datagram, multiple are used.
EasyCAT 0:543d6784d4cc 2356 * In order to recombine the slave response, a stack is used.
EasyCAT 0:543d6784d4cc 2357 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 2358 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 2359 * @return >0 if processdata is transmitted.
EasyCAT 0:543d6784d4cc 2360 * @see ecx_send_overlap_processdata_group
EasyCAT 0:543d6784d4cc 2361 */
EasyCAT 0:543d6784d4cc 2362 int ec_send_overlap_processdata_group(uint8 group)
EasyCAT 0:543d6784d4cc 2363 {
EasyCAT 0:543d6784d4cc 2364 return ecx_send_overlap_processdata_group(&ecx_context, group);
EasyCAT 0:543d6784d4cc 2365 }
EasyCAT 0:543d6784d4cc 2366
EasyCAT 0:543d6784d4cc 2367 /** Receive processdata from slaves.
EasyCAT 0:543d6784d4cc 2368 * Second part from ec_send_processdata().
EasyCAT 0:543d6784d4cc 2369 * Received datagrams are recombined with the processdata with help from the stack.
EasyCAT 0:543d6784d4cc 2370 * If a datagram contains input processdata it copies it to the processdata structure.
EasyCAT 0:543d6784d4cc 2371 * @param[in] group = group number
EasyCAT 0:543d6784d4cc 2372 * @param[in] timeout = Timeout in us.
EasyCAT 0:543d6784d4cc 2373 * @return Work counter.
EasyCAT 0:543d6784d4cc 2374 * @see ecx_receive_processdata_group
EasyCAT 0:543d6784d4cc 2375 */
EasyCAT 0:543d6784d4cc 2376 int ec_receive_processdata_group(uint8 group, int timeout)
EasyCAT 0:543d6784d4cc 2377 {
EasyCAT 0:543d6784d4cc 2378 return ecx_receive_processdata_group (&ecx_context, group, timeout);
EasyCAT 0:543d6784d4cc 2379 }
EasyCAT 0:543d6784d4cc 2380
EasyCAT 0:543d6784d4cc 2381 int ec_send_processdata(void)
EasyCAT 0:543d6784d4cc 2382 {
EasyCAT 0:543d6784d4cc 2383 return ec_send_processdata_group(0);
EasyCAT 0:543d6784d4cc 2384 }
EasyCAT 0:543d6784d4cc 2385
EasyCAT 0:543d6784d4cc 2386 int ec_send_overlap_processdata(void)
EasyCAT 0:543d6784d4cc 2387 {
EasyCAT 0:543d6784d4cc 2388 return ec_send_overlap_processdata_group(0);
EasyCAT 0:543d6784d4cc 2389 }
EasyCAT 0:543d6784d4cc 2390
EasyCAT 0:543d6784d4cc 2391 int ec_receive_processdata(int timeout)
EasyCAT 0:543d6784d4cc 2392 {
EasyCAT 0:543d6784d4cc 2393 return ec_receive_processdata_group(0, timeout);
EasyCAT 0:543d6784d4cc 2394 }
EasyCAT 0:543d6784d4cc 2395 #endif