SOEM EtherCAT Master library for STM Nucleo F767ZI

Dependents:   EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB

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

Warning

/media/uploads/EasyCAT/easycat_lab.jpg

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
EasyCAT 0:543d6784d4cc 1 /*
EasyCAT 0:543d6784d4cc 2 * Licensed under the GNU General Public License version 2 with exceptions. See
EasyCAT 0:543d6784d4cc 3 * LICENSE file in the project root for full license information
EasyCAT 0:543d6784d4cc 4 */
EasyCAT 0:543d6784d4cc 5
EasyCAT 0:543d6784d4cc 6 /** \file
EasyCAT 0:543d6784d4cc 7 * \brief
EasyCAT 0:543d6784d4cc 8 * CAN over EtherCAT (CoE) module.
EasyCAT 0:543d6784d4cc 9 *
EasyCAT 0:543d6784d4cc 10 * SDO read / write and SDO service functions
EasyCAT 0:543d6784d4cc 11 */
EasyCAT 0:543d6784d4cc 12
EasyCAT 0:543d6784d4cc 13 #include <stdio.h>
EasyCAT 0:543d6784d4cc 14 #include <string.h>
EasyCAT 0:543d6784d4cc 15 #include "osal.h"
EasyCAT 0:543d6784d4cc 16 #include "oshw.h"
EasyCAT 0:543d6784d4cc 17 #include "ethercattype.h"
EasyCAT 0:543d6784d4cc 18 #include "ethercatbase.h"
EasyCAT 0:543d6784d4cc 19 #include "ethercatmain.h"
EasyCAT 0:543d6784d4cc 20 #include "ethercatcoe.h"
EasyCAT 0:543d6784d4cc 21
EasyCAT 0:543d6784d4cc 22 /** SDO structure, not to be confused with EcSDOserviceT */
EasyCAT 0:543d6784d4cc 23 PACKED_BEGIN
EasyCAT 0:543d6784d4cc 24 typedef struct PACKED
EasyCAT 0:543d6784d4cc 25 {
EasyCAT 0:543d6784d4cc 26 ec_mbxheadert MbxHeader;
EasyCAT 0:543d6784d4cc 27 uint16 CANOpen;
EasyCAT 0:543d6784d4cc 28 uint8 Command;
EasyCAT 0:543d6784d4cc 29 uint16 Index;
EasyCAT 0:543d6784d4cc 30 uint8 SubIndex;
EasyCAT 0:543d6784d4cc 31 union
EasyCAT 0:543d6784d4cc 32 {
EasyCAT 0:543d6784d4cc 33 uint8 bdata[0x200]; /* variants for easy data access */
EasyCAT 0:543d6784d4cc 34 uint16 wdata[0x100];
EasyCAT 0:543d6784d4cc 35 uint32 ldata[0x80];
EasyCAT 0:543d6784d4cc 36 };
EasyCAT 0:543d6784d4cc 37 } ec_SDOt;
EasyCAT 0:543d6784d4cc 38 PACKED_END
EasyCAT 0:543d6784d4cc 39
EasyCAT 0:543d6784d4cc 40 /** SDO service structure */
EasyCAT 0:543d6784d4cc 41 PACKED_BEGIN
EasyCAT 0:543d6784d4cc 42 typedef struct PACKED
EasyCAT 0:543d6784d4cc 43 {
EasyCAT 0:543d6784d4cc 44 ec_mbxheadert MbxHeader;
EasyCAT 0:543d6784d4cc 45 uint16 CANOpen;
EasyCAT 0:543d6784d4cc 46 uint8 Opcode;
EasyCAT 0:543d6784d4cc 47 uint8 Reserved;
EasyCAT 0:543d6784d4cc 48 uint16 Fragments;
EasyCAT 0:543d6784d4cc 49 union
EasyCAT 0:543d6784d4cc 50 {
EasyCAT 0:543d6784d4cc 51 uint8 bdata[0x200]; /* variants for easy data access */
EasyCAT 0:543d6784d4cc 52 uint16 wdata[0x100];
EasyCAT 0:543d6784d4cc 53 uint32 ldata[0x80];
EasyCAT 0:543d6784d4cc 54 };
EasyCAT 0:543d6784d4cc 55 } ec_SDOservicet;
EasyCAT 0:543d6784d4cc 56 PACKED_END
EasyCAT 0:543d6784d4cc 57
EasyCAT 0:543d6784d4cc 58 /** Report SDO error.
EasyCAT 0:543d6784d4cc 59 *
EasyCAT 0:543d6784d4cc 60 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 61 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 62 * @param[in] Index = Index that generated error
EasyCAT 0:543d6784d4cc 63 * @param[in] SubIdx = Subindex that generated error
EasyCAT 0:543d6784d4cc 64 * @param[in] AbortCode = Abortcode, see EtherCAT documentation for list
EasyCAT 0:543d6784d4cc 65 */
EasyCAT 0:543d6784d4cc 66 void ecx_SDOerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
EasyCAT 0:543d6784d4cc 67 {
EasyCAT 0:543d6784d4cc 68 ec_errort Ec;
EasyCAT 0:543d6784d4cc 69
EasyCAT 0:543d6784d4cc 70 memset(&Ec, 0, sizeof(Ec));
EasyCAT 0:543d6784d4cc 71 Ec.Time = osal_current_time();
EasyCAT 0:543d6784d4cc 72 Ec.Slave = Slave;
EasyCAT 0:543d6784d4cc 73 Ec.Index = Index;
EasyCAT 0:543d6784d4cc 74 Ec.SubIdx = SubIdx;
EasyCAT 0:543d6784d4cc 75 *(context->ecaterror) = TRUE;
EasyCAT 0:543d6784d4cc 76 Ec.Etype = EC_ERR_TYPE_SDO_ERROR;
EasyCAT 0:543d6784d4cc 77 Ec.AbortCode = AbortCode;
EasyCAT 0:543d6784d4cc 78 ecx_pusherror(context, &Ec);
EasyCAT 0:543d6784d4cc 79 }
EasyCAT 0:543d6784d4cc 80
EasyCAT 0:543d6784d4cc 81 /** Report SDO info error
EasyCAT 0:543d6784d4cc 82 *
EasyCAT 0:543d6784d4cc 83 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 84 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 85 * @param[in] Index = Index that generated error
EasyCAT 0:543d6784d4cc 86 * @param[in] SubIdx = Subindex that generated error
EasyCAT 0:543d6784d4cc 87 * @param[in] AbortCode = Abortcode, see EtherCAT documentation for list
EasyCAT 0:543d6784d4cc 88 */
EasyCAT 0:543d6784d4cc 89 static void ecx_SDOinfoerror(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
EasyCAT 0:543d6784d4cc 90 {
EasyCAT 0:543d6784d4cc 91 ec_errort Ec;
EasyCAT 0:543d6784d4cc 92
EasyCAT 0:543d6784d4cc 93 memset(&Ec, 0, sizeof(Ec));
EasyCAT 0:543d6784d4cc 94 Ec.Slave = Slave;
EasyCAT 0:543d6784d4cc 95 Ec.Index = Index;
EasyCAT 0:543d6784d4cc 96 Ec.SubIdx = SubIdx;
EasyCAT 0:543d6784d4cc 97 *(context->ecaterror) = TRUE;
EasyCAT 0:543d6784d4cc 98 Ec.Etype = EC_ERR_TYPE_SDOINFO_ERROR;
EasyCAT 0:543d6784d4cc 99 Ec.AbortCode = AbortCode;
EasyCAT 0:543d6784d4cc 100 ecx_pusherror(context, &Ec);
EasyCAT 0:543d6784d4cc 101 }
EasyCAT 0:543d6784d4cc 102
EasyCAT 0:543d6784d4cc 103 /** CoE SDO read, blocking. Single subindex or Complete Access.
EasyCAT 0:543d6784d4cc 104 *
EasyCAT 0:543d6784d4cc 105 * Only a "normal" upload request is issued. If the requested parameter is <= 4bytes
EasyCAT 0:543d6784d4cc 106 * then a "expedited" response is returned, otherwise a "normal" response. If a "normal"
EasyCAT 0:543d6784d4cc 107 * response is larger than the mailbox size then the response is segmented. The function
EasyCAT 0:543d6784d4cc 108 * will combine all segments and copy them to the parameter buffer.
EasyCAT 0:543d6784d4cc 109 *
EasyCAT 0:543d6784d4cc 110 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 111 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 112 * @param[in] index = Index to read
EasyCAT 0:543d6784d4cc 113 * @param[in] subindex = Subindex to read, must be 0 or 1 if CA is used.
EasyCAT 0:543d6784d4cc 114 * @param[in] CA = FALSE = single subindex. TRUE = Complete Access, all subindexes read.
EasyCAT 0:543d6784d4cc 115 * @param[in,out] psize = Size in bytes of parameter buffer, returns bytes read from SDO.
EasyCAT 0:543d6784d4cc 116 * @param[out] p = Pointer to parameter buffer
EasyCAT 0:543d6784d4cc 117 * @param[in] timeout = Timeout in us, standard is EC_TIMEOUTRXM
EasyCAT 0:543d6784d4cc 118 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 119 */
EasyCAT 0:543d6784d4cc 120 int ecx_SDOread(ecx_contextt *context, uint16 slave, uint16 index, uint8 subindex,
EasyCAT 0:543d6784d4cc 121 boolean CA, int *psize, void *p, int timeout)
EasyCAT 0:543d6784d4cc 122 {
EasyCAT 0:543d6784d4cc 123 ec_SDOt *SDOp, *aSDOp;
EasyCAT 0:543d6784d4cc 124 uint16 bytesize, Framedatasize;
EasyCAT 0:543d6784d4cc 125 int wkc;
EasyCAT 0:543d6784d4cc 126 int32 SDOlen;
EasyCAT 0:543d6784d4cc 127 uint8 *bp;
EasyCAT 0:543d6784d4cc 128 uint8 *hp;
EasyCAT 0:543d6784d4cc 129 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 130 uint8 cnt, toggle;
EasyCAT 0:543d6784d4cc 131 boolean NotLast;
EasyCAT 0:543d6784d4cc 132
EasyCAT 0:543d6784d4cc 133 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 134 /* Empty slave out mailbox if something is in. Timeout set to 0 */
EasyCAT 0:543d6784d4cc 135 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
EasyCAT 0:543d6784d4cc 136 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 137 aSDOp = (ec_SDOt *)&MbxIn;
EasyCAT 0:543d6784d4cc 138 SDOp = (ec_SDOt *)&MbxOut;
EasyCAT 0:543d6784d4cc 139 SDOp->MbxHeader.length = htoes(0x000a);
EasyCAT 0:543d6784d4cc 140 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 141 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 142 /* get new mailbox count value, used as session handle */
EasyCAT 0:543d6784d4cc 143 cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 144 context->slavelist[slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 145 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 146 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
EasyCAT 0:543d6784d4cc 147 if (CA)
EasyCAT 0:543d6784d4cc 148 {
EasyCAT 0:543d6784d4cc 149 SDOp->Command = ECT_SDO_UP_REQ_CA; /* upload request complete access */
EasyCAT 0:543d6784d4cc 150 }
EasyCAT 0:543d6784d4cc 151 else
EasyCAT 0:543d6784d4cc 152 {
EasyCAT 0:543d6784d4cc 153 SDOp->Command = ECT_SDO_UP_REQ; /* upload request normal */
EasyCAT 0:543d6784d4cc 154 }
EasyCAT 0:543d6784d4cc 155 SDOp->Index = htoes(index);
EasyCAT 0:543d6784d4cc 156 if (CA && (subindex > 1))
EasyCAT 0:543d6784d4cc 157 {
EasyCAT 0:543d6784d4cc 158 subindex = 1;
EasyCAT 0:543d6784d4cc 159 }
EasyCAT 0:543d6784d4cc 160 SDOp->SubIndex = subindex;
EasyCAT 0:543d6784d4cc 161 SDOp->ldata[0] = 0;
EasyCAT 0:543d6784d4cc 162 /* send CoE request to slave */
EasyCAT 0:543d6784d4cc 163 wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 164 if (wkc > 0) /* succeeded to place mailbox in slave ? */
EasyCAT 0:543d6784d4cc 165 {
EasyCAT 0:543d6784d4cc 166 /* clean mailboxbuffer */
EasyCAT 0:543d6784d4cc 167 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 168 /* read slave response */
EasyCAT 0:543d6784d4cc 169 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
EasyCAT 0:543d6784d4cc 170 if (wkc > 0) /* succeeded to read slave response ? */
EasyCAT 0:543d6784d4cc 171 {
EasyCAT 0:543d6784d4cc 172 /* slave response should be CoE, SDO response and the correct index */
EasyCAT 0:543d6784d4cc 173 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 174 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
EasyCAT 0:543d6784d4cc 175 (aSDOp->Index == SDOp->Index))
EasyCAT 0:543d6784d4cc 176 {
EasyCAT 0:543d6784d4cc 177 if ((aSDOp->Command & 0x02) > 0)
EasyCAT 0:543d6784d4cc 178 {
EasyCAT 0:543d6784d4cc 179 /* expedited frame response */
EasyCAT 0:543d6784d4cc 180 bytesize = 4 - ((aSDOp->Command >> 2) & 0x03);
EasyCAT 0:543d6784d4cc 181 if (*psize >= bytesize) /* parameter buffer big enough ? */
EasyCAT 0:543d6784d4cc 182 {
EasyCAT 0:543d6784d4cc 183 /* copy parameter in parameter buffer */
EasyCAT 0:543d6784d4cc 184 memcpy(p, &aSDOp->ldata[0], bytesize);
EasyCAT 0:543d6784d4cc 185 /* return the real parameter size */
EasyCAT 0:543d6784d4cc 186 *psize = bytesize;
EasyCAT 0:543d6784d4cc 187 }
EasyCAT 0:543d6784d4cc 188 else
EasyCAT 0:543d6784d4cc 189 {
EasyCAT 0:543d6784d4cc 190 wkc = 0;
EasyCAT 0:543d6784d4cc 191 ecx_packeterror(context, slave, index, subindex, 3); /* data container too small for type */
EasyCAT 0:543d6784d4cc 192 }
EasyCAT 0:543d6784d4cc 193 }
EasyCAT 0:543d6784d4cc 194 else
EasyCAT 0:543d6784d4cc 195 { /* normal frame response */
EasyCAT 0:543d6784d4cc 196 SDOlen = etohl(aSDOp->ldata[0]);
EasyCAT 0:543d6784d4cc 197 /* Does parameter fit in parameter buffer ? */
EasyCAT 0:543d6784d4cc 198 if (SDOlen <= *psize)
EasyCAT 0:543d6784d4cc 199 {
EasyCAT 0:543d6784d4cc 200 bp = p;
EasyCAT 0:543d6784d4cc 201 hp = p;
EasyCAT 0:543d6784d4cc 202 /* calculate mailbox transfer size */
EasyCAT 0:543d6784d4cc 203 Framedatasize = (etohs(aSDOp->MbxHeader.length) - 10);
EasyCAT 0:543d6784d4cc 204 if (Framedatasize < SDOlen) /* transfer in segments? */
EasyCAT 0:543d6784d4cc 205 {
EasyCAT 0:543d6784d4cc 206 /* copy parameter data in parameter buffer */
EasyCAT 0:543d6784d4cc 207 memcpy(hp, &aSDOp->ldata[1], Framedatasize);
EasyCAT 0:543d6784d4cc 208 /* increment buffer pointer */
EasyCAT 0:543d6784d4cc 209 hp += Framedatasize;
EasyCAT 0:543d6784d4cc 210 *psize = Framedatasize;
EasyCAT 0:543d6784d4cc 211 NotLast = TRUE;
EasyCAT 0:543d6784d4cc 212 toggle= 0x00;
EasyCAT 0:543d6784d4cc 213 while (NotLast) /* segmented transfer */
EasyCAT 0:543d6784d4cc 214 {
EasyCAT 0:543d6784d4cc 215 SDOp = (ec_SDOt *)&MbxOut;
EasyCAT 0:543d6784d4cc 216 SDOp->MbxHeader.length = htoes(0x000a);
EasyCAT 0:543d6784d4cc 217 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 218 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 219 cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 220 context->slavelist[slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 221 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 222 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
EasyCAT 0:543d6784d4cc 223 SDOp->Command = ECT_SDO_SEG_UP_REQ + toggle; /* segment upload request */
EasyCAT 0:543d6784d4cc 224 SDOp->Index = htoes(index);
EasyCAT 0:543d6784d4cc 225 SDOp->SubIndex = subindex;
EasyCAT 0:543d6784d4cc 226 SDOp->ldata[0] = 0;
EasyCAT 0:543d6784d4cc 227 /* send segmented upload request to slave */
EasyCAT 0:543d6784d4cc 228 wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 229 /* is mailbox transferred to slave ? */
EasyCAT 0:543d6784d4cc 230 if (wkc > 0)
EasyCAT 0:543d6784d4cc 231 {
EasyCAT 0:543d6784d4cc 232 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 233 /* read slave response */
EasyCAT 0:543d6784d4cc 234 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
EasyCAT 0:543d6784d4cc 235 /* has slave responded ? */
EasyCAT 0:543d6784d4cc 236 if (wkc > 0)
EasyCAT 0:543d6784d4cc 237 {
EasyCAT 0:543d6784d4cc 238 /* slave response should be CoE, SDO response */
EasyCAT 0:543d6784d4cc 239 if ((((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 240 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
EasyCAT 0:543d6784d4cc 241 ((aSDOp->Command & 0xe0) == 0x00)))
EasyCAT 0:543d6784d4cc 242 {
EasyCAT 0:543d6784d4cc 243 /* calculate mailbox transfer size */
EasyCAT 0:543d6784d4cc 244 Framedatasize = etohs(aSDOp->MbxHeader.length) - 3;
EasyCAT 0:543d6784d4cc 245 if ((aSDOp->Command & 0x01) > 0)
EasyCAT 0:543d6784d4cc 246 { /* last segment */
EasyCAT 0:543d6784d4cc 247 NotLast = FALSE;
EasyCAT 0:543d6784d4cc 248 if (Framedatasize == 7)
EasyCAT 0:543d6784d4cc 249 /* subtract unused bytes from frame */
EasyCAT 0:543d6784d4cc 250 Framedatasize = Framedatasize - ((aSDOp->Command & 0x0e) >> 1);
EasyCAT 0:543d6784d4cc 251 /* copy to parameter buffer */
EasyCAT 0:543d6784d4cc 252 memcpy(hp, &(aSDOp->Index), Framedatasize);
EasyCAT 0:543d6784d4cc 253 }
EasyCAT 0:543d6784d4cc 254 else /* segments follow */
EasyCAT 0:543d6784d4cc 255 {
EasyCAT 0:543d6784d4cc 256 /* copy to parameter buffer */
EasyCAT 0:543d6784d4cc 257 memcpy(hp, &(aSDOp->Index), Framedatasize);
EasyCAT 0:543d6784d4cc 258 /* increment buffer pointer */
EasyCAT 0:543d6784d4cc 259 hp += Framedatasize;
EasyCAT 0:543d6784d4cc 260 }
EasyCAT 0:543d6784d4cc 261 /* update parameter size */
EasyCAT 0:543d6784d4cc 262 *psize += Framedatasize;
EasyCAT 0:543d6784d4cc 263 }
EasyCAT 0:543d6784d4cc 264 /* unexpected frame returned from slave */
EasyCAT 0:543d6784d4cc 265 else
EasyCAT 0:543d6784d4cc 266 {
EasyCAT 0:543d6784d4cc 267 NotLast = FALSE;
EasyCAT 0:543d6784d4cc 268 if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
EasyCAT 0:543d6784d4cc 269 ecx_SDOerror(context, slave, index, subindex, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 270 else
EasyCAT 0:543d6784d4cc 271 ecx_packeterror(context, slave, index, subindex, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 272 wkc = 0;
EasyCAT 0:543d6784d4cc 273 }
EasyCAT 0:543d6784d4cc 274 }
EasyCAT 0:543d6784d4cc 275 }
EasyCAT 0:543d6784d4cc 276 toggle = toggle ^ 0x10; /* toggle bit for segment request */
EasyCAT 0:543d6784d4cc 277 }
EasyCAT 0:543d6784d4cc 278 }
EasyCAT 0:543d6784d4cc 279 /* non segmented transfer */
EasyCAT 0:543d6784d4cc 280 else
EasyCAT 0:543d6784d4cc 281 {
EasyCAT 0:543d6784d4cc 282 /* copy to parameter buffer */
EasyCAT 0:543d6784d4cc 283 memcpy(bp, &aSDOp->ldata[1], SDOlen);
EasyCAT 0:543d6784d4cc 284 *psize = SDOlen;
EasyCAT 0:543d6784d4cc 285 }
EasyCAT 0:543d6784d4cc 286 }
EasyCAT 0:543d6784d4cc 287 /* parameter buffer too small */
EasyCAT 0:543d6784d4cc 288 else
EasyCAT 0:543d6784d4cc 289 {
EasyCAT 0:543d6784d4cc 290 wkc = 0;
EasyCAT 0:543d6784d4cc 291 ecx_packeterror(context, slave, index, subindex, 3); /* data container too small for type */
EasyCAT 0:543d6784d4cc 292 }
EasyCAT 0:543d6784d4cc 293 }
EasyCAT 0:543d6784d4cc 294 }
EasyCAT 0:543d6784d4cc 295 /* other slave response */
EasyCAT 0:543d6784d4cc 296 else
EasyCAT 0:543d6784d4cc 297 {
EasyCAT 0:543d6784d4cc 298 if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
EasyCAT 0:543d6784d4cc 299 {
EasyCAT 0:543d6784d4cc 300 ecx_SDOerror(context, slave, index, subindex, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 301 }
EasyCAT 0:543d6784d4cc 302 else
EasyCAT 0:543d6784d4cc 303 {
EasyCAT 0:543d6784d4cc 304 ecx_packeterror(context, slave, index, subindex, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 305 }
EasyCAT 0:543d6784d4cc 306 wkc = 0;
EasyCAT 0:543d6784d4cc 307 }
EasyCAT 0:543d6784d4cc 308 }
EasyCAT 0:543d6784d4cc 309 }
EasyCAT 0:543d6784d4cc 310 return wkc;
EasyCAT 0:543d6784d4cc 311 }
EasyCAT 0:543d6784d4cc 312
EasyCAT 0:543d6784d4cc 313 /** CoE SDO write, blocking. Single subindex or Complete Access.
EasyCAT 0:543d6784d4cc 314 *
EasyCAT 0:543d6784d4cc 315 * A "normal" download request is issued, unless we have
EasyCAT 0:543d6784d4cc 316 * small data, then a "expedited" transfer is used. If the parameter is larger than
EasyCAT 0:543d6784d4cc 317 * the mailbox size then the download is segmented. The function will split the
EasyCAT 0:543d6784d4cc 318 * parameter data in segments and send them to the slave one by one.
EasyCAT 0:543d6784d4cc 319 *
EasyCAT 0:543d6784d4cc 320 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 321 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 322 * @param[in] Index = Index to write
EasyCAT 0:543d6784d4cc 323 * @param[in] SubIndex = Subindex to write, must be 0 or 1 if CA is used.
EasyCAT 0:543d6784d4cc 324 * @param[in] CA = FALSE = single subindex. TRUE = Complete Access, all subindexes written.
EasyCAT 0:543d6784d4cc 325 * @param[in] psize = Size in bytes of parameter buffer.
EasyCAT 0:543d6784d4cc 326 * @param[out] p = Pointer to parameter buffer
EasyCAT 0:543d6784d4cc 327 * @param[in] Timeout = Timeout in us, standard is EC_TIMEOUTRXM
EasyCAT 0:543d6784d4cc 328 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 329 */
EasyCAT 0:543d6784d4cc 330 int ecx_SDOwrite(ecx_contextt *context, uint16 Slave, uint16 Index, uint8 SubIndex,
EasyCAT 0:543d6784d4cc 331 boolean CA, int psize, void *p, int Timeout)
EasyCAT 0:543d6784d4cc 332 {
EasyCAT 0:543d6784d4cc 333 ec_SDOt *SDOp, *aSDOp;
EasyCAT 0:543d6784d4cc 334 int wkc, maxdata;
EasyCAT 0:543d6784d4cc 335 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 336 uint8 cnt, toggle;
EasyCAT 0:543d6784d4cc 337 uint16 framedatasize;
EasyCAT 0:543d6784d4cc 338 boolean NotLast;
EasyCAT 0:543d6784d4cc 339 uint8 *hp;
EasyCAT 0:543d6784d4cc 340
EasyCAT 0:543d6784d4cc 341 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 342 /* Empty slave out mailbox if something is in. Timeout set to 0 */
EasyCAT 0:543d6784d4cc 343 wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, 0);
EasyCAT 0:543d6784d4cc 344 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 345 aSDOp = (ec_SDOt *)&MbxIn;
EasyCAT 0:543d6784d4cc 346 SDOp = (ec_SDOt *)&MbxOut;
EasyCAT 0:543d6784d4cc 347 maxdata = context->slavelist[Slave].mbx_l - 0x10; /* data section=mailbox size - 6 mbx - 2 CoE - 8 sdo req */
EasyCAT 0:543d6784d4cc 348 /* if small data use expedited transfer */
EasyCAT 0:543d6784d4cc 349 if ((psize <= 4) && !CA)
EasyCAT 0:543d6784d4cc 350 {
EasyCAT 0:543d6784d4cc 351 SDOp->MbxHeader.length = htoes(0x000a);
EasyCAT 0:543d6784d4cc 352 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 353 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 354 /* get new mailbox counter, used for session handle */
EasyCAT 0:543d6784d4cc 355 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 356 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 357 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 358 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 359 SDOp->Command = ECT_SDO_DOWN_EXP | (((4 - psize) << 2) & 0x0c); /* expedited SDO download transfer */
EasyCAT 0:543d6784d4cc 360 SDOp->Index = htoes(Index);
EasyCAT 0:543d6784d4cc 361 SDOp->SubIndex = SubIndex;
EasyCAT 0:543d6784d4cc 362 hp = p;
EasyCAT 0:543d6784d4cc 363 /* copy parameter data to mailbox */
EasyCAT 0:543d6784d4cc 364 memcpy(&SDOp->ldata[0], hp, psize);
EasyCAT 0:543d6784d4cc 365 /* send mailbox SDO download request to slave */
EasyCAT 0:543d6784d4cc 366 wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 367 if (wkc > 0)
EasyCAT 0:543d6784d4cc 368 {
EasyCAT 0:543d6784d4cc 369 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 370 /* read slave response */
EasyCAT 0:543d6784d4cc 371 wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
EasyCAT 0:543d6784d4cc 372 if (wkc > 0)
EasyCAT 0:543d6784d4cc 373 {
EasyCAT 0:543d6784d4cc 374 /* response should be CoE, SDO response, correct index and subindex */
EasyCAT 0:543d6784d4cc 375 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 376 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
EasyCAT 0:543d6784d4cc 377 (aSDOp->Index == SDOp->Index) &&
EasyCAT 0:543d6784d4cc 378 (aSDOp->SubIndex == SDOp->SubIndex))
EasyCAT 0:543d6784d4cc 379 {
EasyCAT 0:543d6784d4cc 380 /* all OK */
EasyCAT 0:543d6784d4cc 381 }
EasyCAT 0:543d6784d4cc 382 /* unexpected response from slave */
EasyCAT 0:543d6784d4cc 383 else
EasyCAT 0:543d6784d4cc 384 {
EasyCAT 0:543d6784d4cc 385 if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
EasyCAT 0:543d6784d4cc 386 {
EasyCAT 0:543d6784d4cc 387 ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 388 }
EasyCAT 0:543d6784d4cc 389 else
EasyCAT 0:543d6784d4cc 390 {
EasyCAT 0:543d6784d4cc 391 ecx_packeterror(context, Slave, Index, SubIndex, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 392 }
EasyCAT 0:543d6784d4cc 393 wkc = 0;
EasyCAT 0:543d6784d4cc 394 }
EasyCAT 0:543d6784d4cc 395 }
EasyCAT 0:543d6784d4cc 396 }
EasyCAT 0:543d6784d4cc 397 }
EasyCAT 0:543d6784d4cc 398 else
EasyCAT 0:543d6784d4cc 399 {
EasyCAT 0:543d6784d4cc 400 framedatasize = psize;
EasyCAT 0:543d6784d4cc 401 NotLast = FALSE;
EasyCAT 0:543d6784d4cc 402 if (framedatasize > maxdata)
EasyCAT 0:543d6784d4cc 403 {
EasyCAT 0:543d6784d4cc 404 framedatasize = maxdata; /* segmented transfer needed */
EasyCAT 0:543d6784d4cc 405 NotLast = TRUE;
EasyCAT 0:543d6784d4cc 406 }
EasyCAT 0:543d6784d4cc 407 SDOp->MbxHeader.length = htoes(0x0a + framedatasize);
EasyCAT 0:543d6784d4cc 408 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 409 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 410 /* get new mailbox counter, used for session handle */
EasyCAT 0:543d6784d4cc 411 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 412 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 413 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 414 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 415 if (CA)
EasyCAT 0:543d6784d4cc 416 {
EasyCAT 0:543d6784d4cc 417 SDOp->Command = ECT_SDO_DOWN_INIT_CA; /* Complete Access, normal SDO init download transfer */
EasyCAT 0:543d6784d4cc 418 }
EasyCAT 0:543d6784d4cc 419 else
EasyCAT 0:543d6784d4cc 420 {
EasyCAT 0:543d6784d4cc 421 SDOp->Command = ECT_SDO_DOWN_INIT; /* normal SDO init download transfer */
EasyCAT 0:543d6784d4cc 422 }
EasyCAT 0:543d6784d4cc 423 SDOp->Index = htoes(Index);
EasyCAT 0:543d6784d4cc 424 SDOp->SubIndex = SubIndex;
EasyCAT 0:543d6784d4cc 425 if (CA && (SubIndex > 1))
EasyCAT 0:543d6784d4cc 426 {
EasyCAT 0:543d6784d4cc 427 SDOp->SubIndex = 1;
EasyCAT 0:543d6784d4cc 428 }
EasyCAT 0:543d6784d4cc 429 SDOp->ldata[0] = htoel(psize);
EasyCAT 0:543d6784d4cc 430 hp = p;
EasyCAT 0:543d6784d4cc 431 /* copy parameter data to mailbox */
EasyCAT 0:543d6784d4cc 432 memcpy(&SDOp->ldata[1], hp, framedatasize);
EasyCAT 0:543d6784d4cc 433 hp += framedatasize;
EasyCAT 0:543d6784d4cc 434 psize -= framedatasize;
EasyCAT 0:543d6784d4cc 435 /* send mailbox SDO download request to slave */
EasyCAT 0:543d6784d4cc 436 wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 437 if (wkc > 0)
EasyCAT 0:543d6784d4cc 438 {
EasyCAT 0:543d6784d4cc 439 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 440 /* read slave response */
EasyCAT 0:543d6784d4cc 441 wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
EasyCAT 0:543d6784d4cc 442 if (wkc > 0)
EasyCAT 0:543d6784d4cc 443 {
EasyCAT 0:543d6784d4cc 444 /* response should be CoE, SDO response, correct index and subindex */
EasyCAT 0:543d6784d4cc 445 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 446 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
EasyCAT 0:543d6784d4cc 447 (aSDOp->Index == SDOp->Index) &&
EasyCAT 0:543d6784d4cc 448 (aSDOp->SubIndex == SDOp->SubIndex))
EasyCAT 0:543d6784d4cc 449 {
EasyCAT 0:543d6784d4cc 450 /* all ok */
EasyCAT 0:543d6784d4cc 451 maxdata += 7;
EasyCAT 0:543d6784d4cc 452 toggle = 0;
EasyCAT 0:543d6784d4cc 453 /* repeat while segments left */
EasyCAT 0:543d6784d4cc 454 while (NotLast)
EasyCAT 0:543d6784d4cc 455 {
EasyCAT 0:543d6784d4cc 456 SDOp = (ec_SDOt *)&MbxOut;
EasyCAT 0:543d6784d4cc 457 framedatasize = psize;
EasyCAT 0:543d6784d4cc 458 NotLast = FALSE;
EasyCAT 0:543d6784d4cc 459 SDOp->Command = 0x01; /* last segment */
EasyCAT 0:543d6784d4cc 460 if (framedatasize > maxdata)
EasyCAT 0:543d6784d4cc 461 {
EasyCAT 0:543d6784d4cc 462 framedatasize = maxdata; /* more segments needed */
EasyCAT 0:543d6784d4cc 463 NotLast = TRUE;
EasyCAT 0:543d6784d4cc 464 SDOp->Command = 0x00; /* segments follow */
EasyCAT 0:543d6784d4cc 465 }
EasyCAT 0:543d6784d4cc 466 if (!NotLast && (framedatasize < 7))
EasyCAT 0:543d6784d4cc 467 {
EasyCAT 0:543d6784d4cc 468 SDOp->MbxHeader.length = htoes(0x0a); /* minimum size */
EasyCAT 0:543d6784d4cc 469 SDOp->Command = 0x01 + ((7 - framedatasize) << 1); /* last segment reduced octets */
EasyCAT 0:543d6784d4cc 470 }
EasyCAT 0:543d6784d4cc 471 else
EasyCAT 0:543d6784d4cc 472 {
EasyCAT 0:543d6784d4cc 473 SDOp->MbxHeader.length = htoes(framedatasize + 3); /* data + 2 CoE + 1 SDO */
EasyCAT 0:543d6784d4cc 474 }
EasyCAT 0:543d6784d4cc 475 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 476 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 477 /* get new mailbox counter value */
EasyCAT 0:543d6784d4cc 478 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 479 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 480 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 481 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOREQ << 12)); /* number 9bits service upper 4 bits (SDO request) */
EasyCAT 0:543d6784d4cc 482 SDOp->Command = SDOp->Command + toggle; /* add toggle bit to command byte */
EasyCAT 0:543d6784d4cc 483 /* copy parameter data to mailbox */
EasyCAT 0:543d6784d4cc 484 memcpy(&SDOp->Index, hp, framedatasize);
EasyCAT 0:543d6784d4cc 485 /* update parameter buffer pointer */
EasyCAT 0:543d6784d4cc 486 hp += framedatasize;
EasyCAT 0:543d6784d4cc 487 psize -= framedatasize;
EasyCAT 0:543d6784d4cc 488 /* send SDO download request */
EasyCAT 0:543d6784d4cc 489 wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 490 if (wkc > 0)
EasyCAT 0:543d6784d4cc 491 {
EasyCAT 0:543d6784d4cc 492 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 493 /* read slave response */
EasyCAT 0:543d6784d4cc 494 wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, Timeout);
EasyCAT 0:543d6784d4cc 495 if (wkc > 0)
EasyCAT 0:543d6784d4cc 496 {
EasyCAT 0:543d6784d4cc 497 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 498 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_SDORES) &&
EasyCAT 0:543d6784d4cc 499 ((aSDOp->Command & 0xe0) == 0x20))
EasyCAT 0:543d6784d4cc 500 {
EasyCAT 0:543d6784d4cc 501 /* all OK, nothing to do */
EasyCAT 0:543d6784d4cc 502 }
EasyCAT 0:543d6784d4cc 503 else
EasyCAT 0:543d6784d4cc 504 {
EasyCAT 0:543d6784d4cc 505 if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
EasyCAT 0:543d6784d4cc 506 {
EasyCAT 0:543d6784d4cc 507 ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 508 }
EasyCAT 0:543d6784d4cc 509 else
EasyCAT 0:543d6784d4cc 510 {
EasyCAT 0:543d6784d4cc 511 ecx_packeterror(context, Slave, Index, SubIndex, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 512 }
EasyCAT 0:543d6784d4cc 513 wkc = 0;
EasyCAT 0:543d6784d4cc 514 NotLast = FALSE;
EasyCAT 0:543d6784d4cc 515 }
EasyCAT 0:543d6784d4cc 516 }
EasyCAT 0:543d6784d4cc 517 }
EasyCAT 0:543d6784d4cc 518 toggle = toggle ^ 0x10; /* toggle bit for segment request */
EasyCAT 0:543d6784d4cc 519 }
EasyCAT 0:543d6784d4cc 520 }
EasyCAT 0:543d6784d4cc 521 /* unexpected response from slave */
EasyCAT 0:543d6784d4cc 522 else
EasyCAT 0:543d6784d4cc 523 {
EasyCAT 0:543d6784d4cc 524 if (aSDOp->Command == ECT_SDO_ABORT) /* SDO abort frame received */
EasyCAT 0:543d6784d4cc 525 {
EasyCAT 0:543d6784d4cc 526 ecx_SDOerror(context, Slave, Index, SubIndex, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 527 }
EasyCAT 0:543d6784d4cc 528 else
EasyCAT 0:543d6784d4cc 529 {
EasyCAT 0:543d6784d4cc 530 ecx_packeterror(context, Slave, Index, SubIndex, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 531 }
EasyCAT 0:543d6784d4cc 532 wkc = 0;
EasyCAT 0:543d6784d4cc 533 }
EasyCAT 0:543d6784d4cc 534 }
EasyCAT 0:543d6784d4cc 535 }
EasyCAT 0:543d6784d4cc 536 }
EasyCAT 0:543d6784d4cc 537
EasyCAT 0:543d6784d4cc 538 return wkc;
EasyCAT 0:543d6784d4cc 539 }
EasyCAT 0:543d6784d4cc 540
EasyCAT 0:543d6784d4cc 541 /** CoE RxPDO write, blocking.
EasyCAT 0:543d6784d4cc 542 *
EasyCAT 0:543d6784d4cc 543 * A RxPDO download request is issued.
EasyCAT 0:543d6784d4cc 544 *
EasyCAT 0:543d6784d4cc 545 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 546 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 547 * @param[in] RxPDOnumber = Related RxPDO number
EasyCAT 0:543d6784d4cc 548 * @param[in] psize = Size in bytes of PDO buffer.
EasyCAT 0:543d6784d4cc 549 * @param[out] p = Pointer to PDO buffer
EasyCAT 0:543d6784d4cc 550 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 551 */
EasyCAT 0:543d6784d4cc 552 int ecx_RxPDO(ecx_contextt *context, uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
EasyCAT 0:543d6784d4cc 553 {
EasyCAT 0:543d6784d4cc 554 ec_SDOt *SDOp;
EasyCAT 0:543d6784d4cc 555 int wkc, maxdata;
EasyCAT 0:543d6784d4cc 556 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 557 uint8 cnt;
EasyCAT 0:543d6784d4cc 558 uint16 framedatasize;
EasyCAT 0:543d6784d4cc 559
EasyCAT 0:543d6784d4cc 560 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 561 /* Empty slave out mailbox if something is in. Timeout set to 0 */
EasyCAT 0:543d6784d4cc 562 wkc = ecx_mbxreceive(context, Slave, (ec_mbxbuft *)&MbxIn, 0);
EasyCAT 0:543d6784d4cc 563 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 564 SDOp = (ec_SDOt *)&MbxOut;
EasyCAT 0:543d6784d4cc 565 maxdata = context->slavelist[Slave].mbx_l - 0x08; /* data section=mailbox size - 6 mbx - 2 CoE */
EasyCAT 0:543d6784d4cc 566 framedatasize = psize;
EasyCAT 0:543d6784d4cc 567 if (framedatasize > maxdata)
EasyCAT 0:543d6784d4cc 568 {
EasyCAT 0:543d6784d4cc 569 framedatasize = maxdata; /* limit transfer */
EasyCAT 0:543d6784d4cc 570 }
EasyCAT 0:543d6784d4cc 571 SDOp->MbxHeader.length = htoes(0x02 + framedatasize);
EasyCAT 0:543d6784d4cc 572 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 573 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 574 /* get new mailbox counter, used for session handle */
EasyCAT 0:543d6784d4cc 575 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 576 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 577 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 578 SDOp->CANOpen = htoes((RxPDOnumber & 0x01ff) + (ECT_COES_RXPDO << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 579 /* copy PDO data to mailbox */
EasyCAT 0:543d6784d4cc 580 memcpy(&SDOp->Command, p, framedatasize);
EasyCAT 0:543d6784d4cc 581 /* send mailbox RxPDO request to slave */
EasyCAT 0:543d6784d4cc 582 wkc = ecx_mbxsend(context, Slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 583
EasyCAT 0:543d6784d4cc 584 return wkc;
EasyCAT 0:543d6784d4cc 585 }
EasyCAT 0:543d6784d4cc 586
EasyCAT 0:543d6784d4cc 587 /** CoE TxPDO read remote request, blocking.
EasyCAT 0:543d6784d4cc 588 *
EasyCAT 0:543d6784d4cc 589 * A RxPDO download request is issued.
EasyCAT 0:543d6784d4cc 590 *
EasyCAT 0:543d6784d4cc 591 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 592 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 593 * @param[in] TxPDOnumber = Related TxPDO number
EasyCAT 0:543d6784d4cc 594 * @param[in,out] psize = Size in bytes of PDO buffer, returns bytes read from PDO.
EasyCAT 0:543d6784d4cc 595 * @param[out] p = Pointer to PDO buffer
EasyCAT 0:543d6784d4cc 596 * @param[in] timeout = Timeout in us, standard is EC_TIMEOUTRXM
EasyCAT 0:543d6784d4cc 597 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 598 */
EasyCAT 0:543d6784d4cc 599 int ecx_TxPDO(ecx_contextt *context, uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
EasyCAT 0:543d6784d4cc 600 {
EasyCAT 0:543d6784d4cc 601 ec_SDOt *SDOp, *aSDOp;
EasyCAT 0:543d6784d4cc 602 int wkc;
EasyCAT 0:543d6784d4cc 603 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 604 uint8 cnt;
EasyCAT 0:543d6784d4cc 605 uint16 framedatasize;
EasyCAT 0:543d6784d4cc 606
EasyCAT 0:543d6784d4cc 607 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 608 /* Empty slave out mailbox if something is in. Timeout set to 0 */
EasyCAT 0:543d6784d4cc 609 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0);
EasyCAT 0:543d6784d4cc 610 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 611 aSDOp = (ec_SDOt *)&MbxIn;
EasyCAT 0:543d6784d4cc 612 SDOp = (ec_SDOt *)&MbxOut;
EasyCAT 0:543d6784d4cc 613 SDOp->MbxHeader.length = htoes(0x02);
EasyCAT 0:543d6784d4cc 614 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 615 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 616 /* get new mailbox counter, used for session handle */
EasyCAT 0:543d6784d4cc 617 cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 618 context->slavelist[slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 619 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 620 SDOp->CANOpen = htoes((TxPDOnumber & 0x01ff) + (ECT_COES_TXPDO_RR << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 621 wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 622 if (wkc > 0)
EasyCAT 0:543d6784d4cc 623 {
EasyCAT 0:543d6784d4cc 624 /* clean mailboxbuffer */
EasyCAT 0:543d6784d4cc 625 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 626 /* read slave response */
EasyCAT 0:543d6784d4cc 627 wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout);
EasyCAT 0:543d6784d4cc 628 if (wkc > 0) /* succeeded to read slave response ? */
EasyCAT 0:543d6784d4cc 629 {
EasyCAT 0:543d6784d4cc 630 /* slave response should be CoE, TxPDO */
EasyCAT 0:543d6784d4cc 631 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 632 ((etohs(aSDOp->CANOpen) >> 12) == ECT_COES_TXPDO))
EasyCAT 0:543d6784d4cc 633 {
EasyCAT 0:543d6784d4cc 634 /* TxPDO response */
EasyCAT 0:543d6784d4cc 635 framedatasize = (aSDOp->MbxHeader.length - 2);
EasyCAT 0:543d6784d4cc 636 if (*psize >= framedatasize) /* parameter buffer big enough ? */
EasyCAT 0:543d6784d4cc 637 {
EasyCAT 0:543d6784d4cc 638 /* copy parameter in parameter buffer */
EasyCAT 0:543d6784d4cc 639 memcpy(p, &aSDOp->Command, framedatasize);
EasyCAT 0:543d6784d4cc 640 /* return the real parameter size */
EasyCAT 0:543d6784d4cc 641 *psize = framedatasize;
EasyCAT 0:543d6784d4cc 642 }
EasyCAT 0:543d6784d4cc 643 /* parameter buffer too small */
EasyCAT 0:543d6784d4cc 644 else
EasyCAT 0:543d6784d4cc 645 {
EasyCAT 0:543d6784d4cc 646 wkc = 0;
EasyCAT 0:543d6784d4cc 647 ecx_packeterror(context, slave, 0, 0, 3); /* data container too small for type */
EasyCAT 0:543d6784d4cc 648 }
EasyCAT 0:543d6784d4cc 649 }
EasyCAT 0:543d6784d4cc 650 /* other slave response */
EasyCAT 0:543d6784d4cc 651 else
EasyCAT 0:543d6784d4cc 652 {
EasyCAT 0:543d6784d4cc 653 if ((aSDOp->Command) == ECT_SDO_ABORT) /* SDO abort frame received */
EasyCAT 0:543d6784d4cc 654 {
EasyCAT 0:543d6784d4cc 655 ecx_SDOerror(context, slave, 0, 0, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 656 }
EasyCAT 0:543d6784d4cc 657 else
EasyCAT 0:543d6784d4cc 658 {
EasyCAT 0:543d6784d4cc 659 ecx_packeterror(context, slave, 0, 0, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 660 }
EasyCAT 0:543d6784d4cc 661 wkc = 0;
EasyCAT 0:543d6784d4cc 662 }
EasyCAT 0:543d6784d4cc 663 }
EasyCAT 0:543d6784d4cc 664 }
EasyCAT 0:543d6784d4cc 665
EasyCAT 0:543d6784d4cc 666 return wkc;
EasyCAT 0:543d6784d4cc 667 }
EasyCAT 0:543d6784d4cc 668
EasyCAT 0:543d6784d4cc 669 /** Read PDO assign structure
EasyCAT 0:543d6784d4cc 670 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 671 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 672 * @param[in] PDOassign = PDO assign object
EasyCAT 0:543d6784d4cc 673 * @return total bitlength of PDO assign
EasyCAT 0:543d6784d4cc 674 */
EasyCAT 0:543d6784d4cc 675 int ecx_readPDOassign(ecx_contextt *context, uint16 Slave, uint16 PDOassign)
EasyCAT 0:543d6784d4cc 676 {
EasyCAT 0:543d6784d4cc 677 uint16 idxloop, nidx, subidxloop, rdat, idx, subidx;
EasyCAT 0:543d6784d4cc 678 uint8 subcnt;
EasyCAT 0:543d6784d4cc 679 int wkc, bsize = 0, rdl;
EasyCAT 0:543d6784d4cc 680 int32 rdat2;
EasyCAT 0:543d6784d4cc 681
EasyCAT 0:543d6784d4cc 682 rdl = sizeof(rdat); rdat = 0;
EasyCAT 0:543d6784d4cc 683 /* read PDO assign subindex 0 ( = number of PDO's) */
EasyCAT 0:543d6784d4cc 684 wkc = ecx_SDOread(context, Slave, PDOassign, 0x00, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 685 rdat = etohs(rdat);
EasyCAT 0:543d6784d4cc 686 /* positive result from slave ? */
EasyCAT 0:543d6784d4cc 687 if ((wkc > 0) && (rdat > 0))
EasyCAT 0:543d6784d4cc 688 {
EasyCAT 0:543d6784d4cc 689 /* number of available sub indexes */
EasyCAT 0:543d6784d4cc 690 nidx = rdat;
EasyCAT 0:543d6784d4cc 691 bsize = 0;
EasyCAT 0:543d6784d4cc 692 /* read all PDO's */
EasyCAT 0:543d6784d4cc 693 for (idxloop = 1; idxloop <= nidx; idxloop++)
EasyCAT 0:543d6784d4cc 694 {
EasyCAT 0:543d6784d4cc 695 rdl = sizeof(rdat); rdat = 0;
EasyCAT 0:543d6784d4cc 696 /* read PDO assign */
EasyCAT 0:543d6784d4cc 697 wkc = ecx_SDOread(context, Slave, PDOassign, (uint8)idxloop, FALSE, &rdl, &rdat, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 698 /* result is index of PDO */
EasyCAT 0:543d6784d4cc 699 idx = etohs(rdat);
EasyCAT 0:543d6784d4cc 700 if (idx > 0)
EasyCAT 0:543d6784d4cc 701 {
EasyCAT 0:543d6784d4cc 702 rdl = sizeof(subcnt); subcnt = 0;
EasyCAT 0:543d6784d4cc 703 /* read number of subindexes of PDO */
EasyCAT 0:543d6784d4cc 704 wkc = ecx_SDOread(context, Slave,idx, 0x00, FALSE, &rdl, &subcnt, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 705 subidx = subcnt;
EasyCAT 0:543d6784d4cc 706 /* for each subindex */
EasyCAT 0:543d6784d4cc 707 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
EasyCAT 0:543d6784d4cc 708 {
EasyCAT 0:543d6784d4cc 709 rdl = sizeof(rdat2); rdat2 = 0;
EasyCAT 0:543d6784d4cc 710 /* read SDO that is mapped in PDO */
EasyCAT 0:543d6784d4cc 711 wkc = ecx_SDOread(context, Slave, idx, (uint8)subidxloop, FALSE, &rdl, &rdat2, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 712 rdat2 = etohl(rdat2);
EasyCAT 0:543d6784d4cc 713 /* extract bitlength of SDO */
EasyCAT 0:543d6784d4cc 714 if (LO_BYTE(rdat2) < 0xff)
EasyCAT 0:543d6784d4cc 715 {
EasyCAT 0:543d6784d4cc 716 bsize += LO_BYTE(rdat2);
EasyCAT 0:543d6784d4cc 717 }
EasyCAT 0:543d6784d4cc 718 else
EasyCAT 0:543d6784d4cc 719 {
EasyCAT 0:543d6784d4cc 720 rdl = sizeof(rdat); rdat = htoes(0xff);
EasyCAT 0:543d6784d4cc 721 /* read Object Entry in Object database */
EasyCAT 0:543d6784d4cc 722 // wkc = ec_readOEsingle(idx, (uint8)SubCount, pODlist, pOElist);
EasyCAT 0:543d6784d4cc 723 bsize += etohs(rdat);
EasyCAT 0:543d6784d4cc 724 }
EasyCAT 0:543d6784d4cc 725 }
EasyCAT 0:543d6784d4cc 726 }
EasyCAT 0:543d6784d4cc 727 }
EasyCAT 0:543d6784d4cc 728 }
EasyCAT 0:543d6784d4cc 729 /* return total found bitlength (PDO) */
EasyCAT 0:543d6784d4cc 730 return bsize;
EasyCAT 0:543d6784d4cc 731 }
EasyCAT 0:543d6784d4cc 732
EasyCAT 0:543d6784d4cc 733 /** Read PDO assign structure in Complete Access mode
EasyCAT 0:543d6784d4cc 734 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 735 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 736 * @param[in] Thread_n = Calling thread index
EasyCAT 0:543d6784d4cc 737 * @param[in] PDOassign = PDO assign object
EasyCAT 0:543d6784d4cc 738 * @return total bitlength of PDO assign
EasyCAT 0:543d6784d4cc 739 */
EasyCAT 0:543d6784d4cc 740 int ecx_readPDOassignCA(ecx_contextt *context, uint16 Slave, int Thread_n,
EasyCAT 0:543d6784d4cc 741 uint16 PDOassign)
EasyCAT 0:543d6784d4cc 742 {
EasyCAT 0:543d6784d4cc 743 uint16 idxloop, nidx, subidxloop, idx, subidx;
EasyCAT 0:543d6784d4cc 744 int wkc, bsize = 0, rdl;
EasyCAT 0:543d6784d4cc 745
EasyCAT 0:543d6784d4cc 746 /* find maximum size of PDOassign buffer */
EasyCAT 0:543d6784d4cc 747 rdl = sizeof(ec_PDOassignt);
EasyCAT 0:543d6784d4cc 748 context->PDOassign[Thread_n].n=0;
EasyCAT 0:543d6784d4cc 749 /* read rxPDOassign in CA mode, all subindexes are read in one struct */
EasyCAT 0:543d6784d4cc 750 wkc = ecx_SDOread(context, Slave, PDOassign, 0x00, TRUE, &rdl,
EasyCAT 0:543d6784d4cc 751 &(context->PDOassign[Thread_n]), EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 752 /* positive result from slave ? */
EasyCAT 0:543d6784d4cc 753 if ((wkc > 0) && (context->PDOassign[Thread_n].n > 0))
EasyCAT 0:543d6784d4cc 754 {
EasyCAT 0:543d6784d4cc 755 nidx = context->PDOassign[Thread_n].n;
EasyCAT 0:543d6784d4cc 756 bsize = 0;
EasyCAT 0:543d6784d4cc 757 /* for each PDO do */
EasyCAT 0:543d6784d4cc 758 for (idxloop = 1; idxloop <= nidx; idxloop++)
EasyCAT 0:543d6784d4cc 759 {
EasyCAT 0:543d6784d4cc 760 /* get index from PDOassign struct */
EasyCAT 0:543d6784d4cc 761 idx = etohs(context->PDOassign[Thread_n].index[idxloop - 1]);
EasyCAT 0:543d6784d4cc 762 if (idx > 0)
EasyCAT 0:543d6784d4cc 763 {
EasyCAT 0:543d6784d4cc 764 rdl = sizeof(ec_PDOdesct); context->PDOdesc[Thread_n].n = 0;
EasyCAT 0:543d6784d4cc 765 /* read SDO's that are mapped in PDO, CA mode */
EasyCAT 0:543d6784d4cc 766 wkc = ecx_SDOread(context, Slave,idx, 0x00, TRUE, &rdl,
EasyCAT 0:543d6784d4cc 767 &(context->PDOdesc[Thread_n]), EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 768 subidx = context->PDOdesc[Thread_n].n;
EasyCAT 0:543d6784d4cc 769 /* extract all bitlengths of SDO's */
EasyCAT 0:543d6784d4cc 770 for (subidxloop = 1; subidxloop <= subidx; subidxloop++)
EasyCAT 0:543d6784d4cc 771 {
EasyCAT 0:543d6784d4cc 772 bsize += LO_BYTE(etohl(context->PDOdesc[Thread_n].PDO[subidxloop -1]));
EasyCAT 0:543d6784d4cc 773 }
EasyCAT 0:543d6784d4cc 774 }
EasyCAT 0:543d6784d4cc 775 }
EasyCAT 0:543d6784d4cc 776 }
EasyCAT 0:543d6784d4cc 777
EasyCAT 0:543d6784d4cc 778 /* return total found bitlength (PDO) */
EasyCAT 0:543d6784d4cc 779 return bsize;
EasyCAT 0:543d6784d4cc 780 }
EasyCAT 0:543d6784d4cc 781
EasyCAT 0:543d6784d4cc 782 /** CoE read PDO mapping.
EasyCAT 0:543d6784d4cc 783 *
EasyCAT 0:543d6784d4cc 784 * CANopen has standard indexes defined for PDO mapping. This function
EasyCAT 0:543d6784d4cc 785 * tries to read them and collect a full input and output mapping size
EasyCAT 0:543d6784d4cc 786 * of designated slave.
EasyCAT 0:543d6784d4cc 787 *
EasyCAT 0:543d6784d4cc 788 * Principal structure in slave:\n
EasyCAT 0:543d6784d4cc 789 * 1C00:00 is number of SM defined\n
EasyCAT 0:543d6784d4cc 790 * 1C00:01 SM0 type -> 1C10\n
EasyCAT 0:543d6784d4cc 791 * 1C00:02 SM1 type -> 1C11\n
EasyCAT 0:543d6784d4cc 792 * 1C00:03 SM2 type -> 1C12\n
EasyCAT 0:543d6784d4cc 793 * 1C00:04 SM3 type -> 1C13\n
EasyCAT 0:543d6784d4cc 794 * Type 0 = unused, 1 = mailbox in, 2 = mailbox out,
EasyCAT 0:543d6784d4cc 795 * 3 = outputs (RxPDO), 4 = inputs (TxPDO).
EasyCAT 0:543d6784d4cc 796 *
EasyCAT 0:543d6784d4cc 797 * 1C12:00 is number of PDO's defined for SM2\n
EasyCAT 0:543d6784d4cc 798 * 1C12:01 PDO assign SDO #1 -> f.e. 1A00\n
EasyCAT 0:543d6784d4cc 799 * 1C12:02 PDO assign SDO #2 -> f.e. 1A04\
EasyCAT 0:543d6784d4cc 800 *
EasyCAT 0:543d6784d4cc 801 * 1A00:00 is number of object defined for this PDO\n
EasyCAT 0:543d6784d4cc 802 * 1A00:01 object mapping #1, f.e. 60100710 (SDO 6010 SI 07 bitlength 0x10)
EasyCAT 0:543d6784d4cc 803 *
EasyCAT 0:543d6784d4cc 804 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 805 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 806 * @param[out] Osize = Size in bits of output mapping (rxPDO) found
EasyCAT 0:543d6784d4cc 807 * @param[out] Isize = Size in bits of input mapping (txPDO) found
EasyCAT 0:543d6784d4cc 808 * @return >0 if mapping successful.
EasyCAT 0:543d6784d4cc 809 */
EasyCAT 0:543d6784d4cc 810 int ecx_readPDOmap(ecx_contextt *context, uint16 Slave, int *Osize, int *Isize)
EasyCAT 0:543d6784d4cc 811 {
EasyCAT 0:543d6784d4cc 812 int wkc, rdl;
EasyCAT 0:543d6784d4cc 813 int retVal = 0;
EasyCAT 0:543d6784d4cc 814 uint8 nSM, iSM, tSM;
EasyCAT 0:543d6784d4cc 815 int Tsize;
EasyCAT 0:543d6784d4cc 816 uint8 SMt_bug_add;
EasyCAT 0:543d6784d4cc 817
EasyCAT 0:543d6784d4cc 818 *Isize = 0;
EasyCAT 0:543d6784d4cc 819 *Osize = 0;
EasyCAT 0:543d6784d4cc 820 SMt_bug_add = 0;
EasyCAT 0:543d6784d4cc 821 rdl = sizeof(nSM); nSM = 0;
EasyCAT 0:543d6784d4cc 822 /* read SyncManager Communication Type object count */
EasyCAT 0:543d6784d4cc 823 wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, 0x00, FALSE, &rdl, &nSM, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 824 /* positive result from slave ? */
EasyCAT 0:543d6784d4cc 825 if ((wkc > 0) && (nSM > 2))
EasyCAT 0:543d6784d4cc 826 {
EasyCAT 0:543d6784d4cc 827 /* limit to maximum number of SM defined, if true the slave can't be configured */
EasyCAT 0:543d6784d4cc 828 if (nSM > EC_MAXSM)
EasyCAT 0:543d6784d4cc 829 nSM = EC_MAXSM;
EasyCAT 0:543d6784d4cc 830 /* iterate for every SM type defined */
EasyCAT 0:543d6784d4cc 831 for (iSM = 2 ; iSM < nSM ; iSM++)
EasyCAT 0:543d6784d4cc 832 {
EasyCAT 0:543d6784d4cc 833 rdl = sizeof(tSM); tSM = 0;
EasyCAT 0:543d6784d4cc 834 /* read SyncManager Communication Type */
EasyCAT 0:543d6784d4cc 835 wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, iSM + 1, FALSE, &rdl, &tSM, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 836 if (wkc > 0)
EasyCAT 0:543d6784d4cc 837 {
EasyCAT 0:543d6784d4cc 838 // start slave bug prevention code, remove if possible
EasyCAT 0:543d6784d4cc 839 if((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave!
EasyCAT 0:543d6784d4cc 840 {
EasyCAT 0:543d6784d4cc 841 SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
EasyCAT 0:543d6784d4cc 842 }
EasyCAT 0:543d6784d4cc 843 if(tSM)
EasyCAT 0:543d6784d4cc 844 {
EasyCAT 0:543d6784d4cc 845 tSM += SMt_bug_add; // only add if SMt > 0
EasyCAT 0:543d6784d4cc 846 }
EasyCAT 0:543d6784d4cc 847 if((iSM == 2) && (tSM == 0)) // SM2 has type 0, this is a bug in the slave!
EasyCAT 0:543d6784d4cc 848 {
EasyCAT 0:543d6784d4cc 849 tSM = 3;
EasyCAT 0:543d6784d4cc 850 }
EasyCAT 0:543d6784d4cc 851 if((iSM == 3) && (tSM == 0)) // SM3 has type 0, this is a bug in the slave!
EasyCAT 0:543d6784d4cc 852 {
EasyCAT 0:543d6784d4cc 853 tSM = 4;
EasyCAT 0:543d6784d4cc 854 }
EasyCAT 0:543d6784d4cc 855 // end slave bug prevention code
EasyCAT 0:543d6784d4cc 856
EasyCAT 0:543d6784d4cc 857 context->slavelist[Slave].SMtype[iSM] = tSM;
EasyCAT 0:543d6784d4cc 858 /* check if SM is unused -> clear enable flag */
EasyCAT 0:543d6784d4cc 859 if (tSM == 0)
EasyCAT 0:543d6784d4cc 860 {
EasyCAT 0:543d6784d4cc 861 context->slavelist[Slave].SM[iSM].SMflags =
EasyCAT 0:543d6784d4cc 862 htoel( etohl(context->slavelist[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
EasyCAT 0:543d6784d4cc 863 }
EasyCAT 0:543d6784d4cc 864 if ((tSM == 3) || (tSM == 4))
EasyCAT 0:543d6784d4cc 865 {
EasyCAT 0:543d6784d4cc 866 /* read the assign PDO */
EasyCAT 0:543d6784d4cc 867 Tsize = ecx_readPDOassign(context, Slave, ECT_SDO_PDOASSIGN + iSM );
EasyCAT 0:543d6784d4cc 868 /* if a mapping is found */
EasyCAT 0:543d6784d4cc 869 if (Tsize)
EasyCAT 0:543d6784d4cc 870 {
EasyCAT 0:543d6784d4cc 871 context->slavelist[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
EasyCAT 0:543d6784d4cc 872 if (tSM == 3)
EasyCAT 0:543d6784d4cc 873 {
EasyCAT 0:543d6784d4cc 874 /* we are doing outputs */
EasyCAT 0:543d6784d4cc 875 *Osize += Tsize;
EasyCAT 0:543d6784d4cc 876 }
EasyCAT 0:543d6784d4cc 877 else
EasyCAT 0:543d6784d4cc 878 {
EasyCAT 0:543d6784d4cc 879 /* we are doing inputs */
EasyCAT 0:543d6784d4cc 880 *Isize += Tsize;
EasyCAT 0:543d6784d4cc 881 }
EasyCAT 0:543d6784d4cc 882 }
EasyCAT 0:543d6784d4cc 883 }
EasyCAT 0:543d6784d4cc 884 }
EasyCAT 0:543d6784d4cc 885 }
EasyCAT 0:543d6784d4cc 886 }
EasyCAT 0:543d6784d4cc 887
EasyCAT 0:543d6784d4cc 888 /* found some I/O bits ? */
EasyCAT 0:543d6784d4cc 889 if ((*Isize > 0) || (*Osize > 0))
EasyCAT 0:543d6784d4cc 890 {
EasyCAT 0:543d6784d4cc 891 retVal = 1;
EasyCAT 0:543d6784d4cc 892 }
EasyCAT 0:543d6784d4cc 893
EasyCAT 0:543d6784d4cc 894 return retVal;
EasyCAT 0:543d6784d4cc 895 }
EasyCAT 0:543d6784d4cc 896
EasyCAT 0:543d6784d4cc 897 /** CoE read PDO mapping in Complete Access mode (CA).
EasyCAT 0:543d6784d4cc 898 *
EasyCAT 0:543d6784d4cc 899 * CANopen has standard indexes defined for PDO mapping. This function
EasyCAT 0:543d6784d4cc 900 * tries to read them and collect a full input and output mapping size
EasyCAT 0:543d6784d4cc 901 * of designated slave. Slave has to support CA, otherwise use ec_readPDOmap().
EasyCAT 0:543d6784d4cc 902 *
EasyCAT 0:543d6784d4cc 903 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 904 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 905 * @param[in] Thread_n = Calling thread index
EasyCAT 0:543d6784d4cc 906 * @param[out] Osize = Size in bits of output mapping (rxPDO) found
EasyCAT 0:543d6784d4cc 907 * @param[out] Isize = Size in bits of input mapping (txPDO) found
EasyCAT 0:543d6784d4cc 908 * @return >0 if mapping successful.
EasyCAT 0:543d6784d4cc 909 */
EasyCAT 0:543d6784d4cc 910 int ecx_readPDOmapCA(ecx_contextt *context, uint16 Slave, int Thread_n, int *Osize, int *Isize)
EasyCAT 0:543d6784d4cc 911 {
EasyCAT 0:543d6784d4cc 912 int wkc, rdl;
EasyCAT 0:543d6784d4cc 913 int retVal = 0;
EasyCAT 0:543d6784d4cc 914 uint8 nSM, iSM, tSM;
EasyCAT 0:543d6784d4cc 915 int Tsize;
EasyCAT 0:543d6784d4cc 916 uint8 SMt_bug_add;
EasyCAT 0:543d6784d4cc 917
EasyCAT 0:543d6784d4cc 918 *Isize = 0;
EasyCAT 0:543d6784d4cc 919 *Osize = 0;
EasyCAT 0:543d6784d4cc 920 SMt_bug_add = 0;
EasyCAT 0:543d6784d4cc 921 rdl = sizeof(ec_SMcommtypet);
EasyCAT 0:543d6784d4cc 922 context->SMcommtype[Thread_n].n = 0;
EasyCAT 0:543d6784d4cc 923 /* read SyncManager Communication Type object count Complete Access*/
EasyCAT 0:543d6784d4cc 924 wkc = ecx_SDOread(context, Slave, ECT_SDO_SMCOMMTYPE, 0x00, TRUE, &rdl,
EasyCAT 0:543d6784d4cc 925 &(context->SMcommtype[Thread_n]), EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 926 /* positive result from slave ? */
EasyCAT 0:543d6784d4cc 927 if ((wkc > 0) && (context->SMcommtype[Thread_n].n > 2))
EasyCAT 0:543d6784d4cc 928 {
EasyCAT 0:543d6784d4cc 929 nSM = context->SMcommtype[Thread_n].n;
EasyCAT 0:543d6784d4cc 930 /* limit to maximum number of SM defined, if true the slave can't be configured */
EasyCAT 0:543d6784d4cc 931 if (nSM > EC_MAXSM)
EasyCAT 0:543d6784d4cc 932 {
EasyCAT 0:543d6784d4cc 933 nSM = EC_MAXSM;
EasyCAT 0:543d6784d4cc 934 ecx_packeterror(context, Slave, 0, 0, 10); /* #SM larger than EC_MAXSM */
EasyCAT 0:543d6784d4cc 935 }
EasyCAT 0:543d6784d4cc 936 /* iterate for every SM type defined */
EasyCAT 0:543d6784d4cc 937 for (iSM = 2 ; iSM < nSM ; iSM++)
EasyCAT 0:543d6784d4cc 938 {
EasyCAT 0:543d6784d4cc 939 tSM = context->SMcommtype[Thread_n].SMtype[iSM];
EasyCAT 0:543d6784d4cc 940
EasyCAT 0:543d6784d4cc 941 // start slave bug prevention code, remove if possible
EasyCAT 0:543d6784d4cc 942 if((iSM == 2) && (tSM == 2)) // SM2 has type 2 == mailbox out, this is a bug in the slave!
EasyCAT 0:543d6784d4cc 943 {
EasyCAT 0:543d6784d4cc 944 SMt_bug_add = 1; // try to correct, this works if the types are 0 1 2 3 and should be 1 2 3 4
EasyCAT 0:543d6784d4cc 945 }
EasyCAT 0:543d6784d4cc 946 if(tSM)
EasyCAT 0:543d6784d4cc 947 {
EasyCAT 0:543d6784d4cc 948 tSM += SMt_bug_add; // only add if SMt > 0
EasyCAT 0:543d6784d4cc 949 }
EasyCAT 0:543d6784d4cc 950 // end slave bug prevention code
EasyCAT 0:543d6784d4cc 951
EasyCAT 0:543d6784d4cc 952 context->slavelist[Slave].SMtype[iSM] = tSM;
EasyCAT 0:543d6784d4cc 953 /* check if SM is unused -> clear enable flag */
EasyCAT 0:543d6784d4cc 954 if (tSM == 0)
EasyCAT 0:543d6784d4cc 955 {
EasyCAT 0:543d6784d4cc 956 context->slavelist[Slave].SM[iSM].SMflags =
EasyCAT 0:543d6784d4cc 957 htoel( etohl(context->slavelist[Slave].SM[iSM].SMflags) & EC_SMENABLEMASK);
EasyCAT 0:543d6784d4cc 958 }
EasyCAT 0:543d6784d4cc 959 if ((tSM == 3) || (tSM == 4))
EasyCAT 0:543d6784d4cc 960 {
EasyCAT 0:543d6784d4cc 961 /* read the assign PDO */
EasyCAT 0:543d6784d4cc 962 Tsize = ecx_readPDOassignCA(context, Slave, Thread_n,
EasyCAT 0:543d6784d4cc 963 ECT_SDO_PDOASSIGN + iSM );
EasyCAT 0:543d6784d4cc 964 /* if a mapping is found */
EasyCAT 0:543d6784d4cc 965 if (Tsize)
EasyCAT 0:543d6784d4cc 966 {
EasyCAT 0:543d6784d4cc 967 context->slavelist[Slave].SM[iSM].SMlength = htoes((Tsize + 7) / 8);
EasyCAT 0:543d6784d4cc 968 if (tSM == 3)
EasyCAT 0:543d6784d4cc 969 {
EasyCAT 0:543d6784d4cc 970 /* we are doing outputs */
EasyCAT 0:543d6784d4cc 971 *Osize += Tsize;
EasyCAT 0:543d6784d4cc 972 }
EasyCAT 0:543d6784d4cc 973 else
EasyCAT 0:543d6784d4cc 974 {
EasyCAT 0:543d6784d4cc 975 /* we are doing inputs */
EasyCAT 0:543d6784d4cc 976 *Isize += Tsize;
EasyCAT 0:543d6784d4cc 977 }
EasyCAT 0:543d6784d4cc 978 }
EasyCAT 0:543d6784d4cc 979 }
EasyCAT 0:543d6784d4cc 980 }
EasyCAT 0:543d6784d4cc 981 }
EasyCAT 0:543d6784d4cc 982
EasyCAT 0:543d6784d4cc 983 /* found some I/O bits ? */
EasyCAT 0:543d6784d4cc 984 if ((*Isize > 0) || (*Osize > 0))
EasyCAT 0:543d6784d4cc 985 {
EasyCAT 0:543d6784d4cc 986 retVal = 1;
EasyCAT 0:543d6784d4cc 987 }
EasyCAT 0:543d6784d4cc 988 return retVal;
EasyCAT 0:543d6784d4cc 989 }
EasyCAT 0:543d6784d4cc 990
EasyCAT 0:543d6784d4cc 991 /** CoE read Object Description List.
EasyCAT 0:543d6784d4cc 992 *
EasyCAT 0:543d6784d4cc 993 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 994 * @param[in] Slave = Slave number.
EasyCAT 0:543d6784d4cc 995 * @param[out] pODlist = resulting Object Description list.
EasyCAT 0:543d6784d4cc 996 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 997 */
EasyCAT 0:543d6784d4cc 998 int ecx_readODlist(ecx_contextt *context, uint16 Slave, ec_ODlistt *pODlist)
EasyCAT 0:543d6784d4cc 999 {
EasyCAT 0:543d6784d4cc 1000 ec_SDOservicet *SDOp, *aSDOp;
EasyCAT 0:543d6784d4cc 1001 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 1002 int wkc;
EasyCAT 0:543d6784d4cc 1003 uint16 x, n, i, sp, offset;
EasyCAT 0:543d6784d4cc 1004 boolean stop;
EasyCAT 0:543d6784d4cc 1005 uint8 cnt;
EasyCAT 0:543d6784d4cc 1006 boolean First;
EasyCAT 0:543d6784d4cc 1007
EasyCAT 0:543d6784d4cc 1008 pODlist->Slave = Slave;
EasyCAT 0:543d6784d4cc 1009 pODlist->Entries = 0;
EasyCAT 0:543d6784d4cc 1010 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 1011 /* clear pending out mailbox in slave if available. Timeout is set to 0 */
EasyCAT 0:543d6784d4cc 1012 wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
EasyCAT 0:543d6784d4cc 1013 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 1014 aSDOp = (ec_SDOservicet*)&MbxIn;
EasyCAT 0:543d6784d4cc 1015 SDOp = (ec_SDOservicet*)&MbxOut;
EasyCAT 0:543d6784d4cc 1016 SDOp->MbxHeader.length = htoes(0x0008);
EasyCAT 0:543d6784d4cc 1017 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 1018 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 1019 /* Get new mailbox counter value */
EasyCAT 0:543d6784d4cc 1020 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 1021 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 1022 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 1023 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 1024 SDOp->Opcode = ECT_GET_ODLIST_REQ; /* get object description list request */
EasyCAT 0:543d6784d4cc 1025 SDOp->Reserved = 0;
EasyCAT 0:543d6784d4cc 1026 SDOp->Fragments = 0; /* fragments left */
EasyCAT 0:543d6784d4cc 1027 SDOp->wdata[0] = htoes(0x01); /* all objects */
EasyCAT 0:543d6784d4cc 1028 /* send get object description list request to slave */
EasyCAT 0:543d6784d4cc 1029 wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 1030 /* mailbox placed in slave ? */
EasyCAT 0:543d6784d4cc 1031 if (wkc > 0)
EasyCAT 0:543d6784d4cc 1032 {
EasyCAT 0:543d6784d4cc 1033 x = 0;
EasyCAT 0:543d6784d4cc 1034 sp = 0;
EasyCAT 0:543d6784d4cc 1035 First = TRUE;
EasyCAT 0:543d6784d4cc 1036 offset = 1; /* offset to skip info header in first frame, otherwise set to 0 */
EasyCAT 0:543d6784d4cc 1037 do
EasyCAT 0:543d6784d4cc 1038 {
EasyCAT 0:543d6784d4cc 1039 stop = TRUE; /* assume this is last iteration */
EasyCAT 0:543d6784d4cc 1040 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 1041 /* read slave response */
EasyCAT 0:543d6784d4cc 1042 wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 1043 /* got response ? */
EasyCAT 0:543d6784d4cc 1044 if (wkc > 0)
EasyCAT 0:543d6784d4cc 1045 {
EasyCAT 0:543d6784d4cc 1046 /* response should be CoE and "get object description list response" */
EasyCAT 0:543d6784d4cc 1047 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 1048 ((aSDOp->Opcode & 0x7f) == ECT_GET_ODLIST_RES))
EasyCAT 0:543d6784d4cc 1049 {
EasyCAT 0:543d6784d4cc 1050 if (First)
EasyCAT 0:543d6784d4cc 1051 {
EasyCAT 0:543d6784d4cc 1052 /* extract number of indexes from mailbox data size */
EasyCAT 0:543d6784d4cc 1053 n = (etohs(aSDOp->MbxHeader.length) - (6 + 2)) / 2;
EasyCAT 0:543d6784d4cc 1054 }
EasyCAT 0:543d6784d4cc 1055 else
EasyCAT 0:543d6784d4cc 1056 {
EasyCAT 0:543d6784d4cc 1057 /* extract number of indexes from mailbox data size */
EasyCAT 0:543d6784d4cc 1058 n = (etohs(aSDOp->MbxHeader.length) - 6) / 2;
EasyCAT 0:543d6784d4cc 1059 }
EasyCAT 0:543d6784d4cc 1060 /* check if indexes fit in buffer structure */
EasyCAT 0:543d6784d4cc 1061 if ((sp + n) > EC_MAXODLIST)
EasyCAT 0:543d6784d4cc 1062 {
EasyCAT 0:543d6784d4cc 1063 n = EC_MAXODLIST + 1 - sp;
EasyCAT 0:543d6784d4cc 1064 ecx_SDOinfoerror(context, Slave, 0, 0, 0xf000000); /* Too many entries for master buffer */
EasyCAT 0:543d6784d4cc 1065 stop = TRUE;
EasyCAT 0:543d6784d4cc 1066 }
EasyCAT 0:543d6784d4cc 1067 /* trim to maximum number of ODlist entries defined */
EasyCAT 0:543d6784d4cc 1068 if ((pODlist->Entries + n) > EC_MAXODLIST)
EasyCAT 0:543d6784d4cc 1069 {
EasyCAT 0:543d6784d4cc 1070 n = EC_MAXODLIST - pODlist->Entries;
EasyCAT 0:543d6784d4cc 1071 }
EasyCAT 0:543d6784d4cc 1072 pODlist->Entries += n;
EasyCAT 0:543d6784d4cc 1073 /* extract indexes one by one */
EasyCAT 0:543d6784d4cc 1074 for (i = 0; i < n; i++)
EasyCAT 0:543d6784d4cc 1075 {
EasyCAT 0:543d6784d4cc 1076 pODlist->Index[sp + i] = etohs(aSDOp->wdata[i + offset]);
EasyCAT 0:543d6784d4cc 1077 }
EasyCAT 0:543d6784d4cc 1078 sp += n;
EasyCAT 0:543d6784d4cc 1079 /* check if more fragments will follow */
EasyCAT 0:543d6784d4cc 1080 if (aSDOp->Fragments > 0)
EasyCAT 0:543d6784d4cc 1081 {
EasyCAT 0:543d6784d4cc 1082 stop = FALSE;
EasyCAT 0:543d6784d4cc 1083 }
EasyCAT 0:543d6784d4cc 1084 First = FALSE;
EasyCAT 0:543d6784d4cc 1085 offset = 0;
EasyCAT 0:543d6784d4cc 1086 }
EasyCAT 0:543d6784d4cc 1087 /* got unexpected response from slave */
EasyCAT 0:543d6784d4cc 1088 else
EasyCAT 0:543d6784d4cc 1089 {
EasyCAT 0:543d6784d4cc 1090 if ((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR) /* SDO info error received */
EasyCAT 0:543d6784d4cc 1091 {
EasyCAT 0:543d6784d4cc 1092 ecx_SDOinfoerror(context, Slave, 0, 0, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 1093 stop = TRUE;
EasyCAT 0:543d6784d4cc 1094 }
EasyCAT 0:543d6784d4cc 1095 else
EasyCAT 0:543d6784d4cc 1096 {
EasyCAT 0:543d6784d4cc 1097 ecx_packeterror(context, Slave, 0, 0, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 1098 }
EasyCAT 0:543d6784d4cc 1099 wkc = 0;
EasyCAT 0:543d6784d4cc 1100 x += 20;
EasyCAT 0:543d6784d4cc 1101 }
EasyCAT 0:543d6784d4cc 1102 }
EasyCAT 0:543d6784d4cc 1103 x++;
EasyCAT 0:543d6784d4cc 1104 }
EasyCAT 0:543d6784d4cc 1105 while ((x <= 128) && !stop);
EasyCAT 0:543d6784d4cc 1106 }
EasyCAT 0:543d6784d4cc 1107 return wkc;
EasyCAT 0:543d6784d4cc 1108 }
EasyCAT 0:543d6784d4cc 1109
EasyCAT 0:543d6784d4cc 1110 /** CoE read Object Description. Adds textual description to object indexes.
EasyCAT 0:543d6784d4cc 1111 *
EasyCAT 0:543d6784d4cc 1112 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1113 * @param[in] Item = Item number in ODlist.
EasyCAT 0:543d6784d4cc 1114 * @param[in,out] pODlist = referencing Object Description list.
EasyCAT 0:543d6784d4cc 1115 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 1116 */
EasyCAT 0:543d6784d4cc 1117 int ecx_readODdescription(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist)
EasyCAT 0:543d6784d4cc 1118 {
EasyCAT 0:543d6784d4cc 1119 ec_SDOservicet *SDOp, *aSDOp;
EasyCAT 0:543d6784d4cc 1120 int wkc;
EasyCAT 0:543d6784d4cc 1121 uint16 n, Slave;
EasyCAT 0:543d6784d4cc 1122 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 1123 uint8 cnt;
EasyCAT 0:543d6784d4cc 1124
EasyCAT 0:543d6784d4cc 1125 Slave = pODlist->Slave;
EasyCAT 0:543d6784d4cc 1126 pODlist->DataType[Item] = 0;
EasyCAT 0:543d6784d4cc 1127 pODlist->ObjectCode[Item] = 0;
EasyCAT 0:543d6784d4cc 1128 pODlist->MaxSub[Item] = 0;
EasyCAT 0:543d6784d4cc 1129 pODlist->Name[Item][0] = 0;
EasyCAT 0:543d6784d4cc 1130 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 1131 /* clear pending out mailbox in slave if available. Timeout is set to 0 */
EasyCAT 0:543d6784d4cc 1132 wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
EasyCAT 0:543d6784d4cc 1133 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 1134 aSDOp = (ec_SDOservicet*)&MbxIn;
EasyCAT 0:543d6784d4cc 1135 SDOp = (ec_SDOservicet*)&MbxOut;
EasyCAT 0:543d6784d4cc 1136 SDOp->MbxHeader.length = htoes(0x0008);
EasyCAT 0:543d6784d4cc 1137 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 1138 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 1139 /* Get new mailbox counter value */
EasyCAT 0:543d6784d4cc 1140 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 1141 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 1142 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 1143 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 1144 SDOp->Opcode = ECT_GET_OD_REQ; /* get object description request */
EasyCAT 0:543d6784d4cc 1145 SDOp->Reserved = 0;
EasyCAT 0:543d6784d4cc 1146 SDOp->Fragments = 0; /* fragments left */
EasyCAT 0:543d6784d4cc 1147 SDOp->wdata[0] = htoes(pODlist->Index[Item]); /* Data of Index */
EasyCAT 0:543d6784d4cc 1148 /* send get object description request to slave */
EasyCAT 0:543d6784d4cc 1149 wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 1150 /* mailbox placed in slave ? */
EasyCAT 0:543d6784d4cc 1151 if (wkc > 0)
EasyCAT 0:543d6784d4cc 1152 {
EasyCAT 0:543d6784d4cc 1153 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 1154 /* read slave response */
EasyCAT 0:543d6784d4cc 1155 wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 1156 /* got response ? */
EasyCAT 0:543d6784d4cc 1157 if (wkc > 0)
EasyCAT 0:543d6784d4cc 1158 {
EasyCAT 0:543d6784d4cc 1159 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 1160 ((aSDOp->Opcode & 0x7f) == ECT_GET_OD_RES))
EasyCAT 0:543d6784d4cc 1161 {
EasyCAT 0:543d6784d4cc 1162 n = (etohs(aSDOp->MbxHeader.length) - 12); /* length of string(name of object) */
EasyCAT 0:543d6784d4cc 1163 if (n > EC_MAXNAME)
EasyCAT 0:543d6784d4cc 1164 {
EasyCAT 0:543d6784d4cc 1165 n = EC_MAXNAME; /* max chars */
EasyCAT 0:543d6784d4cc 1166 }
EasyCAT 0:543d6784d4cc 1167 pODlist->DataType[Item] = etohs(aSDOp->wdata[1]);
EasyCAT 0:543d6784d4cc 1168 pODlist->ObjectCode[Item] = aSDOp->bdata[5];
EasyCAT 0:543d6784d4cc 1169 pODlist->MaxSub[Item] = aSDOp->bdata[4];
EasyCAT 0:543d6784d4cc 1170
EasyCAT 0:543d6784d4cc 1171 strncpy(pODlist->Name[Item] , (char *)&aSDOp->bdata[6], n);
EasyCAT 0:543d6784d4cc 1172 pODlist->Name[Item][n] = 0x00; /* String terminator */
EasyCAT 0:543d6784d4cc 1173 }
EasyCAT 0:543d6784d4cc 1174 /* got unexpected response from slave */
EasyCAT 0:543d6784d4cc 1175 else
EasyCAT 0:543d6784d4cc 1176 {
EasyCAT 0:543d6784d4cc 1177 if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)) /* SDO info error received */
EasyCAT 0:543d6784d4cc 1178 {
EasyCAT 0:543d6784d4cc 1179 ecx_SDOinfoerror(context, Slave,pODlist->Index[Item], 0, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 1180 }
EasyCAT 0:543d6784d4cc 1181 else
EasyCAT 0:543d6784d4cc 1182 {
EasyCAT 0:543d6784d4cc 1183 ecx_packeterror(context, Slave,pODlist->Index[Item], 0, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 1184 }
EasyCAT 0:543d6784d4cc 1185 wkc = 0;
EasyCAT 0:543d6784d4cc 1186 }
EasyCAT 0:543d6784d4cc 1187 }
EasyCAT 0:543d6784d4cc 1188 }
EasyCAT 0:543d6784d4cc 1189
EasyCAT 0:543d6784d4cc 1190 return wkc;
EasyCAT 0:543d6784d4cc 1191 }
EasyCAT 0:543d6784d4cc 1192
EasyCAT 0:543d6784d4cc 1193 /** CoE read SDO service object entry, single subindex.
EasyCAT 0:543d6784d4cc 1194 * Used in ec_readOE().
EasyCAT 0:543d6784d4cc 1195 *
EasyCAT 0:543d6784d4cc 1196 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1197 * @param[in] Item = Item in ODlist.
EasyCAT 0:543d6784d4cc 1198 * @param[in] SubI = Subindex of item in ODlist.
EasyCAT 0:543d6784d4cc 1199 * @param[in] pODlist = Object description list for reference.
EasyCAT 0:543d6784d4cc 1200 * @param[out] pOElist = resulting object entry structure.
EasyCAT 0:543d6784d4cc 1201 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 1202 */
EasyCAT 0:543d6784d4cc 1203 int ecx_readOEsingle(ecx_contextt *context, uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
EasyCAT 0:543d6784d4cc 1204 {
EasyCAT 0:543d6784d4cc 1205 ec_SDOservicet *SDOp, *aSDOp;
EasyCAT 0:543d6784d4cc 1206 int wkc;
EasyCAT 0:543d6784d4cc 1207 uint16 Index, Slave;
EasyCAT 0:543d6784d4cc 1208 int16 n;
EasyCAT 0:543d6784d4cc 1209 ec_mbxbuft MbxIn, MbxOut;
EasyCAT 0:543d6784d4cc 1210 uint8 cnt;
EasyCAT 0:543d6784d4cc 1211
EasyCAT 0:543d6784d4cc 1212 wkc = 0;
EasyCAT 0:543d6784d4cc 1213 Slave = pODlist->Slave;
EasyCAT 0:543d6784d4cc 1214 Index = pODlist->Index[Item];
EasyCAT 0:543d6784d4cc 1215 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 1216 /* clear pending out mailbox in slave if available. Timeout is set to 0 */
EasyCAT 0:543d6784d4cc 1217 wkc = ecx_mbxreceive(context, Slave, &MbxIn, 0);
EasyCAT 0:543d6784d4cc 1218 ec_clearmbx(&MbxOut);
EasyCAT 0:543d6784d4cc 1219 aSDOp = (ec_SDOservicet*)&MbxIn;
EasyCAT 0:543d6784d4cc 1220 SDOp = (ec_SDOservicet*)&MbxOut;
EasyCAT 0:543d6784d4cc 1221 SDOp->MbxHeader.length = htoes(0x000a);
EasyCAT 0:543d6784d4cc 1222 SDOp->MbxHeader.address = htoes(0x0000);
EasyCAT 0:543d6784d4cc 1223 SDOp->MbxHeader.priority = 0x00;
EasyCAT 0:543d6784d4cc 1224 /* Get new mailbox counter value */
EasyCAT 0:543d6784d4cc 1225 cnt = ec_nextmbxcnt(context->slavelist[Slave].mbx_cnt);
EasyCAT 0:543d6784d4cc 1226 context->slavelist[Slave].mbx_cnt = cnt;
EasyCAT 0:543d6784d4cc 1227 SDOp->MbxHeader.mbxtype = ECT_MBXT_COE + (cnt << 4); /* CoE */
EasyCAT 0:543d6784d4cc 1228 SDOp->CANOpen = htoes(0x000 + (ECT_COES_SDOINFO << 12)); /* number 9bits service upper 4 bits */
EasyCAT 0:543d6784d4cc 1229 SDOp->Opcode = ECT_GET_OE_REQ; /* get object entry description request */
EasyCAT 0:543d6784d4cc 1230 SDOp->Reserved = 0;
EasyCAT 0:543d6784d4cc 1231 SDOp->Fragments = 0; /* fragments left */
EasyCAT 0:543d6784d4cc 1232 SDOp->wdata[0] = htoes(Index); /* Index */
EasyCAT 0:543d6784d4cc 1233 SDOp->bdata[2] = SubI; /* SubIndex */
EasyCAT 0:543d6784d4cc 1234 SDOp->bdata[3] = 1 + 2 + 4; /* get access rights, object category, PDO */
EasyCAT 0:543d6784d4cc 1235 /* send get object entry description request to slave */
EasyCAT 0:543d6784d4cc 1236 wkc = ecx_mbxsend(context, Slave, &MbxOut, EC_TIMEOUTTXM);
EasyCAT 0:543d6784d4cc 1237 /* mailbox placed in slave ? */
EasyCAT 0:543d6784d4cc 1238 if (wkc > 0)
EasyCAT 0:543d6784d4cc 1239 {
EasyCAT 0:543d6784d4cc 1240 ec_clearmbx(&MbxIn);
EasyCAT 0:543d6784d4cc 1241 /* read slave response */
EasyCAT 0:543d6784d4cc 1242 wkc = ecx_mbxreceive(context, Slave, &MbxIn, EC_TIMEOUTRXM);
EasyCAT 0:543d6784d4cc 1243 /* got response ? */
EasyCAT 0:543d6784d4cc 1244 if (wkc > 0)
EasyCAT 0:543d6784d4cc 1245 {
EasyCAT 0:543d6784d4cc 1246 if (((aSDOp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_COE) &&
EasyCAT 0:543d6784d4cc 1247 ((aSDOp->Opcode & 0x7f) == ECT_GET_OE_RES))
EasyCAT 0:543d6784d4cc 1248 {
EasyCAT 0:543d6784d4cc 1249 pOElist->Entries++;
EasyCAT 0:543d6784d4cc 1250 n = (etohs(aSDOp->MbxHeader.length) - 16); /* length of string(name of object) */
EasyCAT 0:543d6784d4cc 1251 if (n > EC_MAXNAME)
EasyCAT 0:543d6784d4cc 1252 {
EasyCAT 0:543d6784d4cc 1253 n = EC_MAXNAME; /* max string length */
EasyCAT 0:543d6784d4cc 1254 }
EasyCAT 0:543d6784d4cc 1255 if (n < 0 )
EasyCAT 0:543d6784d4cc 1256 {
EasyCAT 0:543d6784d4cc 1257 n = 0;
EasyCAT 0:543d6784d4cc 1258 }
EasyCAT 0:543d6784d4cc 1259 pOElist->ValueInfo[SubI] = aSDOp->bdata[3];
EasyCAT 0:543d6784d4cc 1260 pOElist->DataType[SubI] = etohs(aSDOp->wdata[2]);
EasyCAT 0:543d6784d4cc 1261 pOElist->BitLength[SubI] = etohs(aSDOp->wdata[3]);
EasyCAT 0:543d6784d4cc 1262 pOElist->ObjAccess[SubI] = etohs(aSDOp->wdata[4]);
EasyCAT 0:543d6784d4cc 1263
EasyCAT 0:543d6784d4cc 1264 strncpy(pOElist->Name[SubI] , (char *)&aSDOp->wdata[5], n);
EasyCAT 0:543d6784d4cc 1265 pOElist->Name[SubI][n] = 0x00; /* string terminator */
EasyCAT 0:543d6784d4cc 1266 }
EasyCAT 0:543d6784d4cc 1267 /* got unexpected response from slave */
EasyCAT 0:543d6784d4cc 1268 else
EasyCAT 0:543d6784d4cc 1269 {
EasyCAT 0:543d6784d4cc 1270 if (((aSDOp->Opcode & 0x7f) == ECT_SDOINFO_ERROR)) /* SDO info error received */
EasyCAT 0:543d6784d4cc 1271 {
EasyCAT 0:543d6784d4cc 1272 ecx_SDOinfoerror(context, Slave, Index, SubI, etohl(aSDOp->ldata[0]));
EasyCAT 0:543d6784d4cc 1273 }
EasyCAT 0:543d6784d4cc 1274 else
EasyCAT 0:543d6784d4cc 1275 {
EasyCAT 0:543d6784d4cc 1276 ecx_packeterror(context, Slave, Index, SubI, 1); /* Unexpected frame returned */
EasyCAT 0:543d6784d4cc 1277 }
EasyCAT 0:543d6784d4cc 1278 wkc = 0;
EasyCAT 0:543d6784d4cc 1279 }
EasyCAT 0:543d6784d4cc 1280 }
EasyCAT 0:543d6784d4cc 1281 }
EasyCAT 0:543d6784d4cc 1282
EasyCAT 0:543d6784d4cc 1283 return wkc;
EasyCAT 0:543d6784d4cc 1284 }
EasyCAT 0:543d6784d4cc 1285
EasyCAT 0:543d6784d4cc 1286 /** CoE read SDO service object entry.
EasyCAT 0:543d6784d4cc 1287 *
EasyCAT 0:543d6784d4cc 1288 * @param[in] context = context struct
EasyCAT 0:543d6784d4cc 1289 * @param[in] Item = Item in ODlist.
EasyCAT 0:543d6784d4cc 1290 * @param[in] pODlist = Object description list for reference.
EasyCAT 0:543d6784d4cc 1291 * @param[out] pOElist = resulting object entry structure.
EasyCAT 0:543d6784d4cc 1292 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 1293 */
EasyCAT 0:543d6784d4cc 1294 int ecx_readOE(ecx_contextt *context, uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
EasyCAT 0:543d6784d4cc 1295 {
EasyCAT 0:543d6784d4cc 1296 uint16 SubCount;
EasyCAT 0:543d6784d4cc 1297 int wkc;
EasyCAT 0:543d6784d4cc 1298 uint8 SubI;
EasyCAT 0:543d6784d4cc 1299
EasyCAT 0:543d6784d4cc 1300 wkc = 0;
EasyCAT 0:543d6784d4cc 1301 pOElist->Entries = 0;
EasyCAT 0:543d6784d4cc 1302 SubI = pODlist->MaxSub[Item];
EasyCAT 0:543d6784d4cc 1303 /* for each entry found in ODlist */
EasyCAT 0:543d6784d4cc 1304 for (SubCount = 0; SubCount <= SubI; SubCount++)
EasyCAT 0:543d6784d4cc 1305 {
EasyCAT 0:543d6784d4cc 1306 /* read subindex of entry */
EasyCAT 0:543d6784d4cc 1307 wkc = ecx_readOEsingle(context, Item, (uint8)SubCount, pODlist, pOElist);
EasyCAT 0:543d6784d4cc 1308 }
EasyCAT 0:543d6784d4cc 1309
EasyCAT 0:543d6784d4cc 1310 return wkc;
EasyCAT 0:543d6784d4cc 1311 }
EasyCAT 0:543d6784d4cc 1312
EasyCAT 0:543d6784d4cc 1313 #ifdef EC_VER1
EasyCAT 0:543d6784d4cc 1314 /** Report SDO error.
EasyCAT 0:543d6784d4cc 1315 *
EasyCAT 0:543d6784d4cc 1316 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1317 * @param[in] Index = Index that generated error
EasyCAT 0:543d6784d4cc 1318 * @param[in] SubIdx = Subindex that generated error
EasyCAT 0:543d6784d4cc 1319 * @param[in] AbortCode = Abortcode, see EtherCAT documentation for list
EasyCAT 0:543d6784d4cc 1320 * @see ecx_SDOerror
EasyCAT 0:543d6784d4cc 1321 */
EasyCAT 0:543d6784d4cc 1322 void ec_SDOerror(uint16 Slave, uint16 Index, uint8 SubIdx, int32 AbortCode)
EasyCAT 0:543d6784d4cc 1323 {
EasyCAT 0:543d6784d4cc 1324 ecx_SDOerror(&ecx_context, Slave, Index, SubIdx, AbortCode);
EasyCAT 0:543d6784d4cc 1325 }
EasyCAT 0:543d6784d4cc 1326
EasyCAT 0:543d6784d4cc 1327 /** CoE SDO read, blocking. Single subindex or Complete Access.
EasyCAT 0:543d6784d4cc 1328 *
EasyCAT 0:543d6784d4cc 1329 * Only a "normal" upload request is issued. If the requested parameter is <= 4bytes
EasyCAT 0:543d6784d4cc 1330 * then a "expedited" response is returned, otherwise a "normal" response. If a "normal"
EasyCAT 0:543d6784d4cc 1331 * response is larger than the mailbox size then the response is segmented. The function
EasyCAT 0:543d6784d4cc 1332 * will combine all segments and copy them to the parameter buffer.
EasyCAT 0:543d6784d4cc 1333 *
EasyCAT 0:543d6784d4cc 1334 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1335 * @param[in] index = Index to read
EasyCAT 0:543d6784d4cc 1336 * @param[in] subindex = Subindex to read, must be 0 or 1 if CA is used.
EasyCAT 0:543d6784d4cc 1337 * @param[in] CA = FALSE = single subindex. TRUE = Complete Access, all subindexes read.
EasyCAT 0:543d6784d4cc 1338 * @param[in,out] psize = Size in bytes of parameter buffer, returns bytes read from SDO.
EasyCAT 0:543d6784d4cc 1339 * @param[out] p = Pointer to parameter buffer
EasyCAT 0:543d6784d4cc 1340 * @param[in] timeout = Timeout in us, standard is EC_TIMEOUTRXM
EasyCAT 0:543d6784d4cc 1341 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 1342 * @see ecx_SDOread
EasyCAT 0:543d6784d4cc 1343 */
EasyCAT 0:543d6784d4cc 1344 int ec_SDOread(uint16 slave, uint16 index, uint8 subindex,
EasyCAT 0:543d6784d4cc 1345 boolean CA, int *psize, void *p, int timeout)
EasyCAT 0:543d6784d4cc 1346 {
EasyCAT 0:543d6784d4cc 1347 return ecx_SDOread(&ecx_context, slave, index, subindex, CA, psize, p, timeout);
EasyCAT 0:543d6784d4cc 1348 }
EasyCAT 0:543d6784d4cc 1349
EasyCAT 0:543d6784d4cc 1350 /** CoE SDO write, blocking. Single subindex or Complete Access.
EasyCAT 0:543d6784d4cc 1351 *
EasyCAT 0:543d6784d4cc 1352 * A "normal" download request is issued, unless we have
EasyCAT 0:543d6784d4cc 1353 * small data, then a "expedited" transfer is used. If the parameter is larger than
EasyCAT 0:543d6784d4cc 1354 * the mailbox size then the download is segmented. The function will split the
EasyCAT 0:543d6784d4cc 1355 * parameter data in segments and send them to the slave one by one.
EasyCAT 0:543d6784d4cc 1356 *
EasyCAT 0:543d6784d4cc 1357 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1358 * @param[in] Index = Index to write
EasyCAT 0:543d6784d4cc 1359 * @param[in] SubIndex = Subindex to write, must be 0 or 1 if CA is used.
EasyCAT 0:543d6784d4cc 1360 * @param[in] CA = FALSE = single subindex. TRUE = Complete Access, all subindexes written.
EasyCAT 0:543d6784d4cc 1361 * @param[in] psize = Size in bytes of parameter buffer.
EasyCAT 0:543d6784d4cc 1362 * @param[out] p = Pointer to parameter buffer
EasyCAT 0:543d6784d4cc 1363 * @param[in] Timeout = Timeout in us, standard is EC_TIMEOUTRXM
EasyCAT 0:543d6784d4cc 1364 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 1365 * @see ecx_SDOwrite
EasyCAT 0:543d6784d4cc 1366 */
EasyCAT 0:543d6784d4cc 1367 int ec_SDOwrite(uint16 Slave, uint16 Index, uint8 SubIndex,
EasyCAT 0:543d6784d4cc 1368 boolean CA, int psize, void *p, int Timeout)
EasyCAT 0:543d6784d4cc 1369 {
EasyCAT 0:543d6784d4cc 1370 return ecx_SDOwrite(&ecx_context, Slave, Index, SubIndex, CA, psize, p, Timeout);
EasyCAT 0:543d6784d4cc 1371 }
EasyCAT 0:543d6784d4cc 1372
EasyCAT 0:543d6784d4cc 1373 /** CoE RxPDO write, blocking.
EasyCAT 0:543d6784d4cc 1374 *
EasyCAT 0:543d6784d4cc 1375 * A RxPDO download request is issued.
EasyCAT 0:543d6784d4cc 1376 *
EasyCAT 0:543d6784d4cc 1377 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1378 * @param[in] RxPDOnumber = Related RxPDO number
EasyCAT 0:543d6784d4cc 1379 * @param[in] psize = Size in bytes of PDO buffer.
EasyCAT 0:543d6784d4cc 1380 * @param[out] p = Pointer to PDO buffer
EasyCAT 0:543d6784d4cc 1381 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 1382 * @see ecx_RxPDO
EasyCAT 0:543d6784d4cc 1383 */
EasyCAT 0:543d6784d4cc 1384 int ec_RxPDO(uint16 Slave, uint16 RxPDOnumber, int psize, void *p)
EasyCAT 0:543d6784d4cc 1385 {
EasyCAT 0:543d6784d4cc 1386 return ecx_RxPDO(&ecx_context, Slave, RxPDOnumber, psize, p);
EasyCAT 0:543d6784d4cc 1387 }
EasyCAT 0:543d6784d4cc 1388
EasyCAT 0:543d6784d4cc 1389 /** CoE TxPDO read remote request, blocking.
EasyCAT 0:543d6784d4cc 1390 *
EasyCAT 0:543d6784d4cc 1391 * A RxPDO download request is issued.
EasyCAT 0:543d6784d4cc 1392 *
EasyCAT 0:543d6784d4cc 1393 * @param[in] slave = Slave number
EasyCAT 0:543d6784d4cc 1394 * @param[in] TxPDOnumber = Related TxPDO number
EasyCAT 0:543d6784d4cc 1395 * @param[in,out] psize = Size in bytes of PDO buffer, returns bytes read from PDO.
EasyCAT 0:543d6784d4cc 1396 * @param[out] p = Pointer to PDO buffer
EasyCAT 0:543d6784d4cc 1397 * @param[in] timeout = Timeout in us, standard is EC_TIMEOUTRXM
EasyCAT 0:543d6784d4cc 1398 * @return Workcounter from last slave response
EasyCAT 0:543d6784d4cc 1399 * @see ecx_TxPDO
EasyCAT 0:543d6784d4cc 1400 */
EasyCAT 0:543d6784d4cc 1401 int ec_TxPDO(uint16 slave, uint16 TxPDOnumber , int *psize, void *p, int timeout)
EasyCAT 0:543d6784d4cc 1402 {
EasyCAT 0:543d6784d4cc 1403 return ecx_TxPDO(&ecx_context, slave, TxPDOnumber, psize, p, timeout);
EasyCAT 0:543d6784d4cc 1404 }
EasyCAT 0:543d6784d4cc 1405
EasyCAT 0:543d6784d4cc 1406 /** Read PDO assign structure
EasyCAT 0:543d6784d4cc 1407 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1408 * @param[in] PDOassign = PDO assign object
EasyCAT 0:543d6784d4cc 1409 * @return total bitlength of PDO assign
EasyCAT 0:543d6784d4cc 1410 */
EasyCAT 0:543d6784d4cc 1411 int ec_readPDOassign(uint16 Slave, uint16 PDOassign)
EasyCAT 0:543d6784d4cc 1412 {
EasyCAT 0:543d6784d4cc 1413 return ecx_readPDOassign(&ecx_context, Slave, PDOassign);
EasyCAT 0:543d6784d4cc 1414 }
EasyCAT 0:543d6784d4cc 1415
EasyCAT 0:543d6784d4cc 1416 /** Read PDO assign structure in Complete Access mode
EasyCAT 0:543d6784d4cc 1417 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1418 * @param[in] PDOassign = PDO assign object
EasyCAT 0:543d6784d4cc 1419 * @param[in] Thread_n = Calling thread index
EasyCAT 0:543d6784d4cc 1420 * @return total bitlength of PDO assign
EasyCAT 0:543d6784d4cc 1421 * @see ecx_readPDOmap
EasyCAT 0:543d6784d4cc 1422 */
EasyCAT 0:543d6784d4cc 1423 int ec_readPDOassignCA(uint16 Slave, uint16 PDOassign, int Thread_n)
EasyCAT 0:543d6784d4cc 1424 {
EasyCAT 0:543d6784d4cc 1425 return ecx_readPDOassignCA(&ecx_context, Slave, Thread_n, PDOassign);
EasyCAT 0:543d6784d4cc 1426 }
EasyCAT 0:543d6784d4cc 1427
EasyCAT 0:543d6784d4cc 1428 /** CoE read PDO mapping.
EasyCAT 0:543d6784d4cc 1429 *
EasyCAT 0:543d6784d4cc 1430 * CANopen has standard indexes defined for PDO mapping. This function
EasyCAT 0:543d6784d4cc 1431 * tries to read them and collect a full input and output mapping size
EasyCAT 0:543d6784d4cc 1432 * of designated slave.
EasyCAT 0:543d6784d4cc 1433 *
EasyCAT 0:543d6784d4cc 1434 * For details, see #ecx_readPDOmap
EasyCAT 0:543d6784d4cc 1435 *
EasyCAT 0:543d6784d4cc 1436 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1437 * @param[out] Osize = Size in bits of output mapping (rxPDO) found
EasyCAT 0:543d6784d4cc 1438 * @param[out] Isize = Size in bits of input mapping (txPDO) found
EasyCAT 0:543d6784d4cc 1439 * @return >0 if mapping succesful.
EasyCAT 0:543d6784d4cc 1440 */
EasyCAT 0:543d6784d4cc 1441 int ec_readPDOmap(uint16 Slave, int *Osize, int *Isize)
EasyCAT 0:543d6784d4cc 1442 {
EasyCAT 0:543d6784d4cc 1443 return ecx_readPDOmap(&ecx_context, Slave, Osize, Isize);
EasyCAT 0:543d6784d4cc 1444 }
EasyCAT 0:543d6784d4cc 1445
EasyCAT 0:543d6784d4cc 1446 /** CoE read PDO mapping in Complete Access mode (CA).
EasyCAT 0:543d6784d4cc 1447 *
EasyCAT 0:543d6784d4cc 1448 * CANopen has standard indexes defined for PDO mapping. This function
EasyCAT 0:543d6784d4cc 1449 * tries to read them and collect a full input and output mapping size
EasyCAT 0:543d6784d4cc 1450 * of designated slave. Slave has to support CA, otherwise use ec_readPDOmap().
EasyCAT 0:543d6784d4cc 1451 *
EasyCAT 0:543d6784d4cc 1452 * @param[in] Slave = Slave number
EasyCAT 0:543d6784d4cc 1453 * @param[in] Thread_n = Calling thread index
EasyCAT 0:543d6784d4cc 1454 * @param[out] Osize = Size in bits of output mapping (rxPDO) found
EasyCAT 0:543d6784d4cc 1455 * @param[out] Isize = Size in bits of input mapping (txPDO) found
EasyCAT 0:543d6784d4cc 1456 * @return >0 if mapping succesful.
EasyCAT 0:543d6784d4cc 1457 * @see ecx_readPDOmap ec_readPDOmapCA
EasyCAT 0:543d6784d4cc 1458 */
EasyCAT 0:543d6784d4cc 1459 int ec_readPDOmapCA(uint16 Slave, int Thread_n, int *Osize, int *Isize)
EasyCAT 0:543d6784d4cc 1460 {
EasyCAT 0:543d6784d4cc 1461 return ecx_readPDOmapCA(&ecx_context, Slave, Thread_n, Osize, Isize);
EasyCAT 0:543d6784d4cc 1462 }
EasyCAT 0:543d6784d4cc 1463
EasyCAT 0:543d6784d4cc 1464 /** CoE read Object Description List.
EasyCAT 0:543d6784d4cc 1465 *
EasyCAT 0:543d6784d4cc 1466 * @param[in] Slave = Slave number.
EasyCAT 0:543d6784d4cc 1467 * @param[out] pODlist = resulting Object Description list.
EasyCAT 0:543d6784d4cc 1468 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 1469 * @see ecx_readODlist
EasyCAT 0:543d6784d4cc 1470 */
EasyCAT 0:543d6784d4cc 1471 int ec_readODlist(uint16 Slave, ec_ODlistt *pODlist)
EasyCAT 0:543d6784d4cc 1472 {
EasyCAT 0:543d6784d4cc 1473 return ecx_readODlist(&ecx_context, Slave, pODlist);
EasyCAT 0:543d6784d4cc 1474 }
EasyCAT 0:543d6784d4cc 1475
EasyCAT 0:543d6784d4cc 1476 /** CoE read Object Description. Adds textual description to object indexes.
EasyCAT 0:543d6784d4cc 1477 *
EasyCAT 0:543d6784d4cc 1478 * @param[in] Item = Item number in ODlist.
EasyCAT 0:543d6784d4cc 1479 * @param[in,out] pODlist = referencing Object Description list.
EasyCAT 0:543d6784d4cc 1480 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 1481 * @see ecx_readODdescription
EasyCAT 0:543d6784d4cc 1482 */
EasyCAT 0:543d6784d4cc 1483 int ec_readODdescription(uint16 Item, ec_ODlistt *pODlist)
EasyCAT 0:543d6784d4cc 1484 {
EasyCAT 0:543d6784d4cc 1485 return ecx_readODdescription(&ecx_context, Item, pODlist);
EasyCAT 0:543d6784d4cc 1486 }
EasyCAT 0:543d6784d4cc 1487
EasyCAT 0:543d6784d4cc 1488 int ec_readOEsingle(uint16 Item, uint8 SubI, ec_ODlistt *pODlist, ec_OElistt *pOElist)
EasyCAT 0:543d6784d4cc 1489 {
EasyCAT 0:543d6784d4cc 1490 return ecx_readOEsingle(&ecx_context, Item, SubI, pODlist, pOElist);
EasyCAT 0:543d6784d4cc 1491 }
EasyCAT 0:543d6784d4cc 1492
EasyCAT 0:543d6784d4cc 1493 /** CoE read SDO service object entry.
EasyCAT 0:543d6784d4cc 1494 *
EasyCAT 0:543d6784d4cc 1495 * @param[in] Item = Item in ODlist.
EasyCAT 0:543d6784d4cc 1496 * @param[in] pODlist = Object description list for reference.
EasyCAT 0:543d6784d4cc 1497 * @param[out] pOElist = resulting object entry structure.
EasyCAT 0:543d6784d4cc 1498 * @return Workcounter of slave response.
EasyCAT 0:543d6784d4cc 1499 * @see ecx_readOE
EasyCAT 0:543d6784d4cc 1500 */
EasyCAT 0:543d6784d4cc 1501 int ec_readOE(uint16 Item, ec_ODlistt *pODlist, ec_OElistt *pOElist)
EasyCAT 0:543d6784d4cc 1502 {
EasyCAT 0:543d6784d4cc 1503 return ecx_readOE(&ecx_context, Item, pODlist, pOElist);
EasyCAT 0:543d6784d4cc 1504 }
EasyCAT 0:543d6784d4cc 1505 #endif