SOEM EtherCAT Master library for STM Nucleo F767ZI
Dependents: EasyCAT_LAB_simple EasyCAT_LAB_very_simple EasyCAT_LAB
- This repository contains the SOEM (Simple Open EtherCAT® Master) library by rt-labs, that has been ported in the ecosystem by AB&T Tecnologie Informatiche.
- It has been developed for the EasyCAT LAB , a complete educational and experimental EtherCAT® system, composed of one master and two slaves .
- The EasyCAT LAB is provided as a kit by AB&T Tecnologie Informatiche, to allow everybody to have an educational EtherCAT® system up and running in a matter of minutes.
Warning
- Currently only the Nucleo STM32F767ZI board is supported.
SOEM/ethercatfoe.c@0:543d6784d4cc, 2019-06-11 (annotated)
- Committer:
- EasyCAT
- Date:
- Tue Jun 11 10:29:09 2019 +0000
- Revision:
- 0:543d6784d4cc
SOEM EtherCAT Master Library for STM Nucleo F767ZI
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
EasyCAT | 0:543d6784d4cc | 1 | /* |
EasyCAT | 0:543d6784d4cc | 2 | * Licensed under the GNU General Public License version 2 with exceptions. See |
EasyCAT | 0:543d6784d4cc | 3 | * LICENSE file in the project root for full license information |
EasyCAT | 0:543d6784d4cc | 4 | */ |
EasyCAT | 0:543d6784d4cc | 5 | |
EasyCAT | 0:543d6784d4cc | 6 | /** \file |
EasyCAT | 0:543d6784d4cc | 7 | * \brief |
EasyCAT | 0:543d6784d4cc | 8 | * File over EtherCAT (FoE) 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 "ethercatfoe.h" |
EasyCAT | 0:543d6784d4cc | 21 | |
EasyCAT | 0:543d6784d4cc | 22 | #define EC_MAXFOEDATA 512 |
EasyCAT | 0:543d6784d4cc | 23 | |
EasyCAT | 0:543d6784d4cc | 24 | /** FOE structure. |
EasyCAT | 0:543d6784d4cc | 25 | * Used for Read, Write, Data, Ack and Error mailbox packets. |
EasyCAT | 0:543d6784d4cc | 26 | */ |
EasyCAT | 0:543d6784d4cc | 27 | PACKED_BEGIN |
EasyCAT | 0:543d6784d4cc | 28 | typedef struct PACKED |
EasyCAT | 0:543d6784d4cc | 29 | { |
EasyCAT | 0:543d6784d4cc | 30 | ec_mbxheadert MbxHeader; |
EasyCAT | 0:543d6784d4cc | 31 | uint8 OpCode; |
EasyCAT | 0:543d6784d4cc | 32 | uint8 Reserved; |
EasyCAT | 0:543d6784d4cc | 33 | union |
EasyCAT | 0:543d6784d4cc | 34 | { |
EasyCAT | 0:543d6784d4cc | 35 | uint32 Password; |
EasyCAT | 0:543d6784d4cc | 36 | uint32 PacketNumber; |
EasyCAT | 0:543d6784d4cc | 37 | uint32 ErrorCode; |
EasyCAT | 0:543d6784d4cc | 38 | }; |
EasyCAT | 0:543d6784d4cc | 39 | union |
EasyCAT | 0:543d6784d4cc | 40 | { |
EasyCAT | 0:543d6784d4cc | 41 | char FileName[EC_MAXFOEDATA]; |
EasyCAT | 0:543d6784d4cc | 42 | uint8 Data[EC_MAXFOEDATA]; |
EasyCAT | 0:543d6784d4cc | 43 | char ErrorText[EC_MAXFOEDATA]; |
EasyCAT | 0:543d6784d4cc | 44 | }; |
EasyCAT | 0:543d6784d4cc | 45 | } ec_FOEt; |
EasyCAT | 0:543d6784d4cc | 46 | PACKED_END |
EasyCAT | 0:543d6784d4cc | 47 | |
EasyCAT | 0:543d6784d4cc | 48 | /** FoE progress hook. |
EasyCAT | 0:543d6784d4cc | 49 | * |
EasyCAT | 0:543d6784d4cc | 50 | * @param[in] context = context struct |
EasyCAT | 0:543d6784d4cc | 51 | * @param[in] hook = Pointer to hook function. |
EasyCAT | 0:543d6784d4cc | 52 | * @return 1 |
EasyCAT | 0:543d6784d4cc | 53 | */ |
EasyCAT | 0:543d6784d4cc | 54 | int ecx_FOEdefinehook(ecx_contextt *context, void *hook) |
EasyCAT | 0:543d6784d4cc | 55 | { |
EasyCAT | 0:543d6784d4cc | 56 | context->FOEhook = hook; |
EasyCAT | 0:543d6784d4cc | 57 | return 1; |
EasyCAT | 0:543d6784d4cc | 58 | } |
EasyCAT | 0:543d6784d4cc | 59 | |
EasyCAT | 0:543d6784d4cc | 60 | /** FoE read, blocking. |
EasyCAT | 0:543d6784d4cc | 61 | * |
EasyCAT | 0:543d6784d4cc | 62 | * @param[in] context = context struct |
EasyCAT | 0:543d6784d4cc | 63 | * @param[in] slave = Slave number. |
EasyCAT | 0:543d6784d4cc | 64 | * @param[in] filename = Filename of file to read. |
EasyCAT | 0:543d6784d4cc | 65 | * @param[in] password = password. |
EasyCAT | 0:543d6784d4cc | 66 | * @param[in,out] psize = Size in bytes of file buffer, returns bytes read from file. |
EasyCAT | 0:543d6784d4cc | 67 | * @param[out] p = Pointer to file buffer |
EasyCAT | 0:543d6784d4cc | 68 | * @param[in] timeout = Timeout per mailbox cycle in us, standard is EC_TIMEOUTRXM |
EasyCAT | 0:543d6784d4cc | 69 | * @return Workcounter from last slave response |
EasyCAT | 0:543d6784d4cc | 70 | */ |
EasyCAT | 0:543d6784d4cc | 71 | int ecx_FOEread(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout) |
EasyCAT | 0:543d6784d4cc | 72 | { |
EasyCAT | 0:543d6784d4cc | 73 | ec_FOEt *FOEp, *aFOEp; |
EasyCAT | 0:543d6784d4cc | 74 | int wkc; |
EasyCAT | 0:543d6784d4cc | 75 | int32 dataread = 0; |
EasyCAT | 0:543d6784d4cc | 76 | int32 buffersize, packetnumber, prevpacket = 0; |
EasyCAT | 0:543d6784d4cc | 77 | uint16 fnsize, maxdata, segmentdata; |
EasyCAT | 0:543d6784d4cc | 78 | ec_mbxbuft MbxIn, MbxOut; |
EasyCAT | 0:543d6784d4cc | 79 | uint8 cnt; |
EasyCAT | 0:543d6784d4cc | 80 | boolean worktodo; |
EasyCAT | 0:543d6784d4cc | 81 | |
EasyCAT | 0:543d6784d4cc | 82 | buffersize = *psize; |
EasyCAT | 0:543d6784d4cc | 83 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 84 | /* Empty slave out mailbox if something is in. Timeout set to 0 */ |
EasyCAT | 0:543d6784d4cc | 85 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0); |
EasyCAT | 0:543d6784d4cc | 86 | ec_clearmbx(&MbxOut); |
EasyCAT | 0:543d6784d4cc | 87 | aFOEp = (ec_FOEt *)&MbxIn; |
EasyCAT | 0:543d6784d4cc | 88 | FOEp = (ec_FOEt *)&MbxOut; |
EasyCAT | 0:543d6784d4cc | 89 | fnsize = (uint16)strlen(filename); |
EasyCAT | 0:543d6784d4cc | 90 | maxdata = context->slavelist[slave].mbx_l - 12; |
EasyCAT | 0:543d6784d4cc | 91 | if (fnsize > maxdata) |
EasyCAT | 0:543d6784d4cc | 92 | { |
EasyCAT | 0:543d6784d4cc | 93 | fnsize = maxdata; |
EasyCAT | 0:543d6784d4cc | 94 | } |
EasyCAT | 0:543d6784d4cc | 95 | FOEp->MbxHeader.length = htoes(0x0006 + fnsize); |
EasyCAT | 0:543d6784d4cc | 96 | FOEp->MbxHeader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 97 | FOEp->MbxHeader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 98 | /* get new mailbox count value, used as session handle */ |
EasyCAT | 0:543d6784d4cc | 99 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 100 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 101 | FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */ |
EasyCAT | 0:543d6784d4cc | 102 | FOEp->OpCode = ECT_FOE_READ; |
EasyCAT | 0:543d6784d4cc | 103 | FOEp->Password = htoel(password); |
EasyCAT | 0:543d6784d4cc | 104 | /* copy filename in mailbox */ |
EasyCAT | 0:543d6784d4cc | 105 | memcpy(&FOEp->FileName[0], filename, fnsize); |
EasyCAT | 0:543d6784d4cc | 106 | /* send FoE request to slave */ |
EasyCAT | 0:543d6784d4cc | 107 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM); |
EasyCAT | 0:543d6784d4cc | 108 | if (wkc > 0) /* succeeded to place mailbox in slave ? */ |
EasyCAT | 0:543d6784d4cc | 109 | { |
EasyCAT | 0:543d6784d4cc | 110 | do |
EasyCAT | 0:543d6784d4cc | 111 | { |
EasyCAT | 0:543d6784d4cc | 112 | worktodo = FALSE; |
EasyCAT | 0:543d6784d4cc | 113 | /* clean mailboxbuffer */ |
EasyCAT | 0:543d6784d4cc | 114 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 115 | /* read slave response */ |
EasyCAT | 0:543d6784d4cc | 116 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout); |
EasyCAT | 0:543d6784d4cc | 117 | if (wkc > 0) /* succeeded to read slave response ? */ |
EasyCAT | 0:543d6784d4cc | 118 | { |
EasyCAT | 0:543d6784d4cc | 119 | /* slave response should be FoE */ |
EasyCAT | 0:543d6784d4cc | 120 | if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE) |
EasyCAT | 0:543d6784d4cc | 121 | { |
EasyCAT | 0:543d6784d4cc | 122 | if(aFOEp->OpCode == ECT_FOE_DATA) |
EasyCAT | 0:543d6784d4cc | 123 | { |
EasyCAT | 0:543d6784d4cc | 124 | segmentdata = etohs(aFOEp->MbxHeader.length) - 0x0006; |
EasyCAT | 0:543d6784d4cc | 125 | packetnumber = etohl(aFOEp->PacketNumber); |
EasyCAT | 0:543d6784d4cc | 126 | if ((packetnumber == ++prevpacket) && (dataread + segmentdata <= buffersize)) |
EasyCAT | 0:543d6784d4cc | 127 | { |
EasyCAT | 0:543d6784d4cc | 128 | memcpy(p, &aFOEp->Data[0], segmentdata); |
EasyCAT | 0:543d6784d4cc | 129 | dataread += segmentdata; |
EasyCAT | 0:543d6784d4cc | 130 | p = (uint8 *)p + segmentdata; |
EasyCAT | 0:543d6784d4cc | 131 | if (segmentdata == maxdata) |
EasyCAT | 0:543d6784d4cc | 132 | { |
EasyCAT | 0:543d6784d4cc | 133 | worktodo = TRUE; |
EasyCAT | 0:543d6784d4cc | 134 | } |
EasyCAT | 0:543d6784d4cc | 135 | FOEp->MbxHeader.length = htoes(0x0006); |
EasyCAT | 0:543d6784d4cc | 136 | FOEp->MbxHeader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 137 | FOEp->MbxHeader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 138 | /* get new mailbox count value */ |
EasyCAT | 0:543d6784d4cc | 139 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 140 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 141 | FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */ |
EasyCAT | 0:543d6784d4cc | 142 | FOEp->OpCode = ECT_FOE_ACK; |
EasyCAT | 0:543d6784d4cc | 143 | FOEp->PacketNumber = htoel(packetnumber); |
EasyCAT | 0:543d6784d4cc | 144 | /* send FoE ack to slave */ |
EasyCAT | 0:543d6784d4cc | 145 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM); |
EasyCAT | 0:543d6784d4cc | 146 | if (wkc <= 0) |
EasyCAT | 0:543d6784d4cc | 147 | { |
EasyCAT | 0:543d6784d4cc | 148 | worktodo = FALSE; |
EasyCAT | 0:543d6784d4cc | 149 | } |
EasyCAT | 0:543d6784d4cc | 150 | if (context->FOEhook) |
EasyCAT | 0:543d6784d4cc | 151 | { |
EasyCAT | 0:543d6784d4cc | 152 | context->FOEhook(slave, packetnumber, dataread); |
EasyCAT | 0:543d6784d4cc | 153 | } |
EasyCAT | 0:543d6784d4cc | 154 | } |
EasyCAT | 0:543d6784d4cc | 155 | else |
EasyCAT | 0:543d6784d4cc | 156 | { |
EasyCAT | 0:543d6784d4cc | 157 | /* FoE error */ |
EasyCAT | 0:543d6784d4cc | 158 | wkc = -EC_ERR_TYPE_FOE_BUF2SMALL; |
EasyCAT | 0:543d6784d4cc | 159 | } |
EasyCAT | 0:543d6784d4cc | 160 | } |
EasyCAT | 0:543d6784d4cc | 161 | else |
EasyCAT | 0:543d6784d4cc | 162 | { |
EasyCAT | 0:543d6784d4cc | 163 | if(aFOEp->OpCode == ECT_FOE_ERROR) |
EasyCAT | 0:543d6784d4cc | 164 | { |
EasyCAT | 0:543d6784d4cc | 165 | /* FoE error */ |
EasyCAT | 0:543d6784d4cc | 166 | wkc = -EC_ERR_TYPE_FOE_ERROR; |
EasyCAT | 0:543d6784d4cc | 167 | } |
EasyCAT | 0:543d6784d4cc | 168 | else |
EasyCAT | 0:543d6784d4cc | 169 | { |
EasyCAT | 0:543d6784d4cc | 170 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 171 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 172 | } |
EasyCAT | 0:543d6784d4cc | 173 | } |
EasyCAT | 0:543d6784d4cc | 174 | } |
EasyCAT | 0:543d6784d4cc | 175 | else |
EasyCAT | 0:543d6784d4cc | 176 | { |
EasyCAT | 0:543d6784d4cc | 177 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 178 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 179 | } |
EasyCAT | 0:543d6784d4cc | 180 | *psize = dataread; |
EasyCAT | 0:543d6784d4cc | 181 | } |
EasyCAT | 0:543d6784d4cc | 182 | } while (worktodo); |
EasyCAT | 0:543d6784d4cc | 183 | } |
EasyCAT | 0:543d6784d4cc | 184 | |
EasyCAT | 0:543d6784d4cc | 185 | return wkc; |
EasyCAT | 0:543d6784d4cc | 186 | } |
EasyCAT | 0:543d6784d4cc | 187 | |
EasyCAT | 0:543d6784d4cc | 188 | /** FoE write, blocking. |
EasyCAT | 0:543d6784d4cc | 189 | * |
EasyCAT | 0:543d6784d4cc | 190 | * @param[in] context = context struct |
EasyCAT | 0:543d6784d4cc | 191 | * @param[in] slave = Slave number. |
EasyCAT | 0:543d6784d4cc | 192 | * @param[in] filename = Filename of file to write. |
EasyCAT | 0:543d6784d4cc | 193 | * @param[in] password = password. |
EasyCAT | 0:543d6784d4cc | 194 | * @param[in] psize = Size in bytes of file buffer. |
EasyCAT | 0:543d6784d4cc | 195 | * @param[out] p = Pointer to file buffer |
EasyCAT | 0:543d6784d4cc | 196 | * @param[in] timeout = Timeout per mailbox cycle in us, standard is EC_TIMEOUTRXM |
EasyCAT | 0:543d6784d4cc | 197 | * @return Workcounter from last slave response |
EasyCAT | 0:543d6784d4cc | 198 | */ |
EasyCAT | 0:543d6784d4cc | 199 | int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout) |
EasyCAT | 0:543d6784d4cc | 200 | { |
EasyCAT | 0:543d6784d4cc | 201 | ec_FOEt *FOEp, *aFOEp; |
EasyCAT | 0:543d6784d4cc | 202 | int wkc; |
EasyCAT | 0:543d6784d4cc | 203 | int32 packetnumber, sendpacket = 0; |
EasyCAT | 0:543d6784d4cc | 204 | uint16 fnsize, maxdata; |
EasyCAT | 0:543d6784d4cc | 205 | int segmentdata; |
EasyCAT | 0:543d6784d4cc | 206 | ec_mbxbuft MbxIn, MbxOut; |
EasyCAT | 0:543d6784d4cc | 207 | uint8 cnt; |
EasyCAT | 0:543d6784d4cc | 208 | boolean worktodo, dofinalzero; |
EasyCAT | 0:543d6784d4cc | 209 | int tsize; |
EasyCAT | 0:543d6784d4cc | 210 | |
EasyCAT | 0:543d6784d4cc | 211 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 212 | /* Empty slave out mailbox if something is in. Timeout set to 0 */ |
EasyCAT | 0:543d6784d4cc | 213 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0); |
EasyCAT | 0:543d6784d4cc | 214 | ec_clearmbx(&MbxOut); |
EasyCAT | 0:543d6784d4cc | 215 | aFOEp = (ec_FOEt *)&MbxIn; |
EasyCAT | 0:543d6784d4cc | 216 | FOEp = (ec_FOEt *)&MbxOut; |
EasyCAT | 0:543d6784d4cc | 217 | dofinalzero = FALSE; |
EasyCAT | 0:543d6784d4cc | 218 | fnsize = (uint16)strlen(filename); |
EasyCAT | 0:543d6784d4cc | 219 | maxdata = context->slavelist[slave].mbx_l - 12; |
EasyCAT | 0:543d6784d4cc | 220 | if (fnsize > maxdata) |
EasyCAT | 0:543d6784d4cc | 221 | { |
EasyCAT | 0:543d6784d4cc | 222 | fnsize = maxdata; |
EasyCAT | 0:543d6784d4cc | 223 | } |
EasyCAT | 0:543d6784d4cc | 224 | FOEp->MbxHeader.length = htoes(0x0006 + fnsize); |
EasyCAT | 0:543d6784d4cc | 225 | FOEp->MbxHeader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 226 | FOEp->MbxHeader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 227 | /* get new mailbox count value, used as session handle */ |
EasyCAT | 0:543d6784d4cc | 228 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 229 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 230 | FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */ |
EasyCAT | 0:543d6784d4cc | 231 | FOEp->OpCode = ECT_FOE_WRITE; |
EasyCAT | 0:543d6784d4cc | 232 | FOEp->Password = htoel(password); |
EasyCAT | 0:543d6784d4cc | 233 | /* copy filename in mailbox */ |
EasyCAT | 0:543d6784d4cc | 234 | memcpy(&FOEp->FileName[0], filename, fnsize); |
EasyCAT | 0:543d6784d4cc | 235 | /* send FoE request to slave */ |
EasyCAT | 0:543d6784d4cc | 236 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM); |
EasyCAT | 0:543d6784d4cc | 237 | if (wkc > 0) /* succeeded to place mailbox in slave ? */ |
EasyCAT | 0:543d6784d4cc | 238 | { |
EasyCAT | 0:543d6784d4cc | 239 | do |
EasyCAT | 0:543d6784d4cc | 240 | { |
EasyCAT | 0:543d6784d4cc | 241 | worktodo = FALSE; |
EasyCAT | 0:543d6784d4cc | 242 | /* clean mailboxbuffer */ |
EasyCAT | 0:543d6784d4cc | 243 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 244 | /* read slave response */ |
EasyCAT | 0:543d6784d4cc | 245 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout); |
EasyCAT | 0:543d6784d4cc | 246 | if (wkc > 0) /* succeeded to read slave response ? */ |
EasyCAT | 0:543d6784d4cc | 247 | { |
EasyCAT | 0:543d6784d4cc | 248 | /* slave response should be FoE */ |
EasyCAT | 0:543d6784d4cc | 249 | if ((aFOEp->MbxHeader.mbxtype & 0x0f) == ECT_MBXT_FOE) |
EasyCAT | 0:543d6784d4cc | 250 | { |
EasyCAT | 0:543d6784d4cc | 251 | switch (aFOEp->OpCode) |
EasyCAT | 0:543d6784d4cc | 252 | { |
EasyCAT | 0:543d6784d4cc | 253 | case ECT_FOE_ACK: |
EasyCAT | 0:543d6784d4cc | 254 | { |
EasyCAT | 0:543d6784d4cc | 255 | packetnumber = etohl(aFOEp->PacketNumber); |
EasyCAT | 0:543d6784d4cc | 256 | if (packetnumber == sendpacket) |
EasyCAT | 0:543d6784d4cc | 257 | { |
EasyCAT | 0:543d6784d4cc | 258 | if (context->FOEhook) |
EasyCAT | 0:543d6784d4cc | 259 | { |
EasyCAT | 0:543d6784d4cc | 260 | context->FOEhook(slave, packetnumber, psize); |
EasyCAT | 0:543d6784d4cc | 261 | } |
EasyCAT | 0:543d6784d4cc | 262 | tsize = psize; |
EasyCAT | 0:543d6784d4cc | 263 | if (tsize > maxdata) |
EasyCAT | 0:543d6784d4cc | 264 | { |
EasyCAT | 0:543d6784d4cc | 265 | tsize = maxdata; |
EasyCAT | 0:543d6784d4cc | 266 | } |
EasyCAT | 0:543d6784d4cc | 267 | if(tsize || dofinalzero) |
EasyCAT | 0:543d6784d4cc | 268 | { |
EasyCAT | 0:543d6784d4cc | 269 | worktodo = TRUE; |
EasyCAT | 0:543d6784d4cc | 270 | dofinalzero = FALSE; |
EasyCAT | 0:543d6784d4cc | 271 | segmentdata = tsize; |
EasyCAT | 0:543d6784d4cc | 272 | psize -= segmentdata; |
EasyCAT | 0:543d6784d4cc | 273 | /* if last packet was full size, add a zero size packet as final */ |
EasyCAT | 0:543d6784d4cc | 274 | /* EOF is defined as packetsize < full packetsize */ |
EasyCAT | 0:543d6784d4cc | 275 | if (!psize && (segmentdata == maxdata)) |
EasyCAT | 0:543d6784d4cc | 276 | { |
EasyCAT | 0:543d6784d4cc | 277 | dofinalzero = TRUE; |
EasyCAT | 0:543d6784d4cc | 278 | } |
EasyCAT | 0:543d6784d4cc | 279 | FOEp->MbxHeader.length = htoes(0x0006 + segmentdata); |
EasyCAT | 0:543d6784d4cc | 280 | FOEp->MbxHeader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 281 | FOEp->MbxHeader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 282 | /* get new mailbox count value */ |
EasyCAT | 0:543d6784d4cc | 283 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 284 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 285 | FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */ |
EasyCAT | 0:543d6784d4cc | 286 | FOEp->OpCode = ECT_FOE_DATA; |
EasyCAT | 0:543d6784d4cc | 287 | sendpacket++; |
EasyCAT | 0:543d6784d4cc | 288 | FOEp->PacketNumber = htoel(sendpacket); |
EasyCAT | 0:543d6784d4cc | 289 | memcpy(&FOEp->Data[0], p, segmentdata); |
EasyCAT | 0:543d6784d4cc | 290 | p = (uint8 *)p + segmentdata; |
EasyCAT | 0:543d6784d4cc | 291 | /* send FoE data to slave */ |
EasyCAT | 0:543d6784d4cc | 292 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM); |
EasyCAT | 0:543d6784d4cc | 293 | if (wkc <= 0) |
EasyCAT | 0:543d6784d4cc | 294 | { |
EasyCAT | 0:543d6784d4cc | 295 | worktodo = FALSE; |
EasyCAT | 0:543d6784d4cc | 296 | } |
EasyCAT | 0:543d6784d4cc | 297 | } |
EasyCAT | 0:543d6784d4cc | 298 | } |
EasyCAT | 0:543d6784d4cc | 299 | else |
EasyCAT | 0:543d6784d4cc | 300 | { |
EasyCAT | 0:543d6784d4cc | 301 | /* FoE error */ |
EasyCAT | 0:543d6784d4cc | 302 | wkc = -EC_ERR_TYPE_FOE_PACKETNUMBER; |
EasyCAT | 0:543d6784d4cc | 303 | } |
EasyCAT | 0:543d6784d4cc | 304 | break; |
EasyCAT | 0:543d6784d4cc | 305 | } |
EasyCAT | 0:543d6784d4cc | 306 | case ECT_FOE_BUSY: |
EasyCAT | 0:543d6784d4cc | 307 | { |
EasyCAT | 0:543d6784d4cc | 308 | /* resend if data has been send before */ |
EasyCAT | 0:543d6784d4cc | 309 | /* otherwise ignore */ |
EasyCAT | 0:543d6784d4cc | 310 | if (sendpacket) |
EasyCAT | 0:543d6784d4cc | 311 | { |
EasyCAT | 0:543d6784d4cc | 312 | if (!psize) |
EasyCAT | 0:543d6784d4cc | 313 | { |
EasyCAT | 0:543d6784d4cc | 314 | dofinalzero = TRUE; |
EasyCAT | 0:543d6784d4cc | 315 | } |
EasyCAT | 0:543d6784d4cc | 316 | psize += segmentdata; |
EasyCAT | 0:543d6784d4cc | 317 | p = (uint8 *)p - segmentdata; |
EasyCAT | 0:543d6784d4cc | 318 | --sendpacket; |
EasyCAT | 0:543d6784d4cc | 319 | } |
EasyCAT | 0:543d6784d4cc | 320 | break; |
EasyCAT | 0:543d6784d4cc | 321 | } |
EasyCAT | 0:543d6784d4cc | 322 | case ECT_FOE_ERROR: |
EasyCAT | 0:543d6784d4cc | 323 | { |
EasyCAT | 0:543d6784d4cc | 324 | /* FoE error */ |
EasyCAT | 0:543d6784d4cc | 325 | if (aFOEp->ErrorCode == 0x8001) |
EasyCAT | 0:543d6784d4cc | 326 | { |
EasyCAT | 0:543d6784d4cc | 327 | wkc = -EC_ERR_TYPE_FOE_FILE_NOTFOUND; |
EasyCAT | 0:543d6784d4cc | 328 | } |
EasyCAT | 0:543d6784d4cc | 329 | else |
EasyCAT | 0:543d6784d4cc | 330 | { |
EasyCAT | 0:543d6784d4cc | 331 | wkc = -EC_ERR_TYPE_FOE_ERROR; |
EasyCAT | 0:543d6784d4cc | 332 | } |
EasyCAT | 0:543d6784d4cc | 333 | break; |
EasyCAT | 0:543d6784d4cc | 334 | } |
EasyCAT | 0:543d6784d4cc | 335 | default: |
EasyCAT | 0:543d6784d4cc | 336 | { |
EasyCAT | 0:543d6784d4cc | 337 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 338 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 339 | break; |
EasyCAT | 0:543d6784d4cc | 340 | } |
EasyCAT | 0:543d6784d4cc | 341 | } |
EasyCAT | 0:543d6784d4cc | 342 | } |
EasyCAT | 0:543d6784d4cc | 343 | else |
EasyCAT | 0:543d6784d4cc | 344 | { |
EasyCAT | 0:543d6784d4cc | 345 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 346 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 347 | } |
EasyCAT | 0:543d6784d4cc | 348 | } |
EasyCAT | 0:543d6784d4cc | 349 | } while (worktodo); |
EasyCAT | 0:543d6784d4cc | 350 | } |
EasyCAT | 0:543d6784d4cc | 351 | |
EasyCAT | 0:543d6784d4cc | 352 | return wkc; |
EasyCAT | 0:543d6784d4cc | 353 | } |
EasyCAT | 0:543d6784d4cc | 354 | |
EasyCAT | 0:543d6784d4cc | 355 | #ifdef EC_VER1 |
EasyCAT | 0:543d6784d4cc | 356 | int ec_FOEdefinehook(void *hook) |
EasyCAT | 0:543d6784d4cc | 357 | { |
EasyCAT | 0:543d6784d4cc | 358 | return ecx_FOEdefinehook(&ecx_context, hook); |
EasyCAT | 0:543d6784d4cc | 359 | } |
EasyCAT | 0:543d6784d4cc | 360 | |
EasyCAT | 0:543d6784d4cc | 361 | int ec_FOEread(uint16 slave, char *filename, uint32 password, int *psize, void *p, int timeout) |
EasyCAT | 0:543d6784d4cc | 362 | { |
EasyCAT | 0:543d6784d4cc | 363 | return ecx_FOEread(&ecx_context, slave, filename, password, psize, p, timeout); |
EasyCAT | 0:543d6784d4cc | 364 | } |
EasyCAT | 0:543d6784d4cc | 365 | |
EasyCAT | 0:543d6784d4cc | 366 | int ec_FOEwrite(uint16 slave, char *filename, uint32 password, int psize, void *p, int timeout) |
EasyCAT | 0:543d6784d4cc | 367 | { |
EasyCAT | 0:543d6784d4cc | 368 | return ecx_FOEwrite(&ecx_context, slave, filename, password, psize, p, timeout); |
EasyCAT | 0:543d6784d4cc | 369 | } |
EasyCAT | 0:543d6784d4cc | 370 | #endif |