AB&T / Mbed OS EasyCAT_LAB

Dependencies:   SOEM SPI_STMPE610 SPI_TFT_ILI9341 TFT_fonts

Committer:
sulymarco
Date:
Tue Jun 11 10:19:08 2019 +0000
Revision:
0:7077d8f28b3e
Added SPI speed parameter

Who changed what in which revision?

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