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/ethercateoe.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 | * Ethernet over EtherCAT (EoE) module. |
EasyCAT | 0:543d6784d4cc | 9 | * |
EasyCAT | 0:543d6784d4cc | 10 | * Set / Get IP functions |
EasyCAT | 0:543d6784d4cc | 11 | * Blocking send/receive Ethernet Frame |
EasyCAT | 0:543d6784d4cc | 12 | * Read incoming EoE fragment to Ethernet Frame |
EasyCAT | 0:543d6784d4cc | 13 | */ |
EasyCAT | 0:543d6784d4cc | 14 | |
EasyCAT | 0:543d6784d4cc | 15 | #include <stdio.h> |
EasyCAT | 0:543d6784d4cc | 16 | #include <string.h> |
EasyCAT | 0:543d6784d4cc | 17 | #include "osal.h" |
EasyCAT | 0:543d6784d4cc | 18 | #include "oshw.h" |
EasyCAT | 0:543d6784d4cc | 19 | #include "ethercat.h" |
EasyCAT | 0:543d6784d4cc | 20 | |
EasyCAT | 0:543d6784d4cc | 21 | /** EoE utility function to convert uint32 to eoe ip bytes. |
EasyCAT | 0:543d6784d4cc | 22 | * @param[in] ip = ip in uint32 |
EasyCAT | 0:543d6784d4cc | 23 | * @param[out] byte_ip = eoe ip 4th octet, 3ed octet, 2nd octet, 1st octet |
EasyCAT | 0:543d6784d4cc | 24 | */ |
EasyCAT | 0:543d6784d4cc | 25 | static void EOE_ip_uint32_to_byte(eoe_ip4_addr_t * ip, uint8_t * byte_ip) |
EasyCAT | 0:543d6784d4cc | 26 | { |
EasyCAT | 0:543d6784d4cc | 27 | byte_ip[3] = eoe_ip4_addr1(ip); /* 1st octet */ |
EasyCAT | 0:543d6784d4cc | 28 | byte_ip[2] = eoe_ip4_addr2(ip); /* 2nd octet */ |
EasyCAT | 0:543d6784d4cc | 29 | byte_ip[1] = eoe_ip4_addr3(ip); /* 3ed octet */ |
EasyCAT | 0:543d6784d4cc | 30 | byte_ip[0] = eoe_ip4_addr4(ip); /* 4th octet */ |
EasyCAT | 0:543d6784d4cc | 31 | } |
EasyCAT | 0:543d6784d4cc | 32 | |
EasyCAT | 0:543d6784d4cc | 33 | /** EoE utility function to convert eoe ip bytes to uint32. |
EasyCAT | 0:543d6784d4cc | 34 | * @param[in] byte_ip = eoe ip 4th octet, 3ed octet, 2nd octet, 1st octet |
EasyCAT | 0:543d6784d4cc | 35 | * @param[out] ip = ip in uint32 |
EasyCAT | 0:543d6784d4cc | 36 | */ |
EasyCAT | 0:543d6784d4cc | 37 | static void EOE_ip_byte_to_uint32(uint8_t * byte_ip, eoe_ip4_addr_t * ip) |
EasyCAT | 0:543d6784d4cc | 38 | { |
EasyCAT | 0:543d6784d4cc | 39 | EOE_IP4_ADDR_TO_U32(ip, |
EasyCAT | 0:543d6784d4cc | 40 | byte_ip[3], /* 1st octet */ |
EasyCAT | 0:543d6784d4cc | 41 | byte_ip[2], /* 2nd octet */ |
EasyCAT | 0:543d6784d4cc | 42 | byte_ip[1], /* 3ed octet */ |
EasyCAT | 0:543d6784d4cc | 43 | byte_ip[0]); /* 4th octet */ |
EasyCAT | 0:543d6784d4cc | 44 | } |
EasyCAT | 0:543d6784d4cc | 45 | |
EasyCAT | 0:543d6784d4cc | 46 | /** EoE fragment data handler hook. Should not block. |
EasyCAT | 0:543d6784d4cc | 47 | * |
EasyCAT | 0:543d6784d4cc | 48 | * @param[in] context = context struct |
EasyCAT | 0:543d6784d4cc | 49 | * @param[in] hook = Pointer to hook function. |
EasyCAT | 0:543d6784d4cc | 50 | * @return 1 |
EasyCAT | 0:543d6784d4cc | 51 | */ |
EasyCAT | 0:543d6784d4cc | 52 | int ecx_EOEdefinehook(ecx_contextt *context, void *hook) |
EasyCAT | 0:543d6784d4cc | 53 | { |
EasyCAT | 0:543d6784d4cc | 54 | context->EOEhook = hook; |
EasyCAT | 0:543d6784d4cc | 55 | return 1; |
EasyCAT | 0:543d6784d4cc | 56 | } |
EasyCAT | 0:543d6784d4cc | 57 | |
EasyCAT | 0:543d6784d4cc | 58 | /** EoE EOE set IP, blocking. Waits for response from the slave. |
EasyCAT | 0:543d6784d4cc | 59 | * |
EasyCAT | 0:543d6784d4cc | 60 | * @param[in] context = Context struct |
EasyCAT | 0:543d6784d4cc | 61 | * @param[in] slave = Slave number |
EasyCAT | 0:543d6784d4cc | 62 | * @param[in] port = Port number on slave if applicable |
EasyCAT | 0:543d6784d4cc | 63 | * @param[in] ipparam = IP parameter data to be sent |
EasyCAT | 0:543d6784d4cc | 64 | * @param[in] Timeout = Timeout in us, standard is EC_TIMEOUTRXM |
EasyCAT | 0:543d6784d4cc | 65 | * @return Workcounter from last slave response or returned result code |
EasyCAT | 0:543d6784d4cc | 66 | */ |
EasyCAT | 0:543d6784d4cc | 67 | int ecx_EOEsetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t * ipparam, int timeout) |
EasyCAT | 0:543d6784d4cc | 68 | { |
EasyCAT | 0:543d6784d4cc | 69 | ec_EOEt *EOEp, *aEOEp; |
EasyCAT | 0:543d6784d4cc | 70 | ec_mbxbuft MbxIn, MbxOut; |
EasyCAT | 0:543d6784d4cc | 71 | uint16 frameinfo1, result; |
EasyCAT | 0:543d6784d4cc | 72 | uint8 cnt, data_offset; |
EasyCAT | 0:543d6784d4cc | 73 | uint8 flags = 0; |
EasyCAT | 0:543d6784d4cc | 74 | int wkc; |
EasyCAT | 0:543d6784d4cc | 75 | |
EasyCAT | 0:543d6784d4cc | 76 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 77 | /* Empty slave out mailbox if something is in. Timout set to 0 */ |
EasyCAT | 0:543d6784d4cc | 78 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0); |
EasyCAT | 0:543d6784d4cc | 79 | ec_clearmbx(&MbxOut); |
EasyCAT | 0:543d6784d4cc | 80 | aEOEp = (ec_EOEt *)&MbxIn; |
EasyCAT | 0:543d6784d4cc | 81 | EOEp = (ec_EOEt *)&MbxOut; |
EasyCAT | 0:543d6784d4cc | 82 | EOEp->mbxheader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 83 | EOEp->mbxheader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 84 | data_offset = EOE_PARAM_OFFSET; |
EasyCAT | 0:543d6784d4cc | 85 | |
EasyCAT | 0:543d6784d4cc | 86 | /* get new mailbox count value, used as session handle */ |
EasyCAT | 0:543d6784d4cc | 87 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 88 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 89 | |
EasyCAT | 0:543d6784d4cc | 90 | EOEp->mbxheader.mbxtype = ECT_MBXT_EOE + (cnt << 4); /* EoE */ |
EasyCAT | 0:543d6784d4cc | 91 | |
EasyCAT | 0:543d6784d4cc | 92 | EOEp->frameinfo1 = htoes(EOE_HDR_FRAME_TYPE_SET(EOE_INIT_REQ) | |
EasyCAT | 0:543d6784d4cc | 93 | EOE_HDR_FRAME_PORT_SET(port) | |
EasyCAT | 0:543d6784d4cc | 94 | EOE_HDR_LAST_FRAGMENT); |
EasyCAT | 0:543d6784d4cc | 95 | EOEp->frameinfo2 = 0; |
EasyCAT | 0:543d6784d4cc | 96 | |
EasyCAT | 0:543d6784d4cc | 97 | /* The EoE frame will include "empty" IP/DNS entries, makes wireshark happy. |
EasyCAT | 0:543d6784d4cc | 98 | * Specification say they are optional, TwinCAT include empty entries. |
EasyCAT | 0:543d6784d4cc | 99 | */ |
EasyCAT | 0:543d6784d4cc | 100 | if (ipparam->mac_set) |
EasyCAT | 0:543d6784d4cc | 101 | { |
EasyCAT | 0:543d6784d4cc | 102 | flags |= EOE_PARAM_MAC_INCLUDE; |
EasyCAT | 0:543d6784d4cc | 103 | memcpy(&EOEp->data[data_offset], ipparam->mac.addr, EOE_ETHADDR_LENGTH); |
EasyCAT | 0:543d6784d4cc | 104 | } |
EasyCAT | 0:543d6784d4cc | 105 | data_offset += EOE_ETHADDR_LENGTH; |
EasyCAT | 0:543d6784d4cc | 106 | if (ipparam->ip_set) |
EasyCAT | 0:543d6784d4cc | 107 | { |
EasyCAT | 0:543d6784d4cc | 108 | flags |= EOE_PARAM_IP_INCLUDE; |
EasyCAT | 0:543d6784d4cc | 109 | EOE_ip_uint32_to_byte(&ipparam->ip, &EOEp->data[data_offset]); |
EasyCAT | 0:543d6784d4cc | 110 | } |
EasyCAT | 0:543d6784d4cc | 111 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 112 | if (ipparam->subnet_set) |
EasyCAT | 0:543d6784d4cc | 113 | { |
EasyCAT | 0:543d6784d4cc | 114 | flags |= EOE_PARAM_SUBNET_IP_INCLUDE; |
EasyCAT | 0:543d6784d4cc | 115 | EOE_ip_uint32_to_byte(&ipparam->subnet, &EOEp->data[data_offset]); |
EasyCAT | 0:543d6784d4cc | 116 | } |
EasyCAT | 0:543d6784d4cc | 117 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 118 | if (ipparam->default_gateway_set) |
EasyCAT | 0:543d6784d4cc | 119 | { |
EasyCAT | 0:543d6784d4cc | 120 | flags |= EOE_PARAM_DEFAULT_GATEWAY_INCLUDE; |
EasyCAT | 0:543d6784d4cc | 121 | EOE_ip_uint32_to_byte(&ipparam->default_gateway, &EOEp->data[data_offset]); |
EasyCAT | 0:543d6784d4cc | 122 | } |
EasyCAT | 0:543d6784d4cc | 123 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 124 | if (ipparam->dns_ip_set) |
EasyCAT | 0:543d6784d4cc | 125 | { |
EasyCAT | 0:543d6784d4cc | 126 | flags |= EOE_PARAM_DNS_IP_INCLUDE; |
EasyCAT | 0:543d6784d4cc | 127 | EOE_ip_uint32_to_byte(&ipparam->dns_ip, &EOEp->data[data_offset]); |
EasyCAT | 0:543d6784d4cc | 128 | } |
EasyCAT | 0:543d6784d4cc | 129 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 130 | if (ipparam->dns_name_set) |
EasyCAT | 0:543d6784d4cc | 131 | { |
EasyCAT | 0:543d6784d4cc | 132 | flags |= EOE_PARAM_DNS_NAME_INCLUDE; |
EasyCAT | 0:543d6784d4cc | 133 | memcpy(&EOEp->data[data_offset], (void *)ipparam->dns_name, EOE_DNS_NAME_LENGTH); |
EasyCAT | 0:543d6784d4cc | 134 | } |
EasyCAT | 0:543d6784d4cc | 135 | data_offset += EOE_DNS_NAME_LENGTH; |
EasyCAT | 0:543d6784d4cc | 136 | |
EasyCAT | 0:543d6784d4cc | 137 | EOEp->mbxheader.length = htoes(EOE_PARAM_OFFSET + data_offset); |
EasyCAT | 0:543d6784d4cc | 138 | EOEp->data[0] = flags; |
EasyCAT | 0:543d6784d4cc | 139 | |
EasyCAT | 0:543d6784d4cc | 140 | /* send EoE request to slave */ |
EasyCAT | 0:543d6784d4cc | 141 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM); |
EasyCAT | 0:543d6784d4cc | 142 | |
EasyCAT | 0:543d6784d4cc | 143 | if (wkc > 0) /* succeeded to place mailbox in slave ? */ |
EasyCAT | 0:543d6784d4cc | 144 | { |
EasyCAT | 0:543d6784d4cc | 145 | /* clean mailboxbuffer */ |
EasyCAT | 0:543d6784d4cc | 146 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 147 | /* read slave response */ |
EasyCAT | 0:543d6784d4cc | 148 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout); |
EasyCAT | 0:543d6784d4cc | 149 | if (wkc > 0) /* succeeded to read slave response ? */ |
EasyCAT | 0:543d6784d4cc | 150 | { |
EasyCAT | 0:543d6784d4cc | 151 | /* slave response should be FoE */ |
EasyCAT | 0:543d6784d4cc | 152 | if ((aEOEp->mbxheader.mbxtype & 0x0f) == ECT_MBXT_EOE) |
EasyCAT | 0:543d6784d4cc | 153 | { |
EasyCAT | 0:543d6784d4cc | 154 | frameinfo1 = etohs(aEOEp->frameinfo1); |
EasyCAT | 0:543d6784d4cc | 155 | result = etohs(aEOEp->result); |
EasyCAT | 0:543d6784d4cc | 156 | if ((EOE_HDR_FRAME_TYPE_GET(frameinfo1) != EOE_INIT_RESP) || |
EasyCAT | 0:543d6784d4cc | 157 | (result != EOE_RESULT_SUCCESS)) |
EasyCAT | 0:543d6784d4cc | 158 | { |
EasyCAT | 0:543d6784d4cc | 159 | wkc = -result; |
EasyCAT | 0:543d6784d4cc | 160 | } |
EasyCAT | 0:543d6784d4cc | 161 | } |
EasyCAT | 0:543d6784d4cc | 162 | else |
EasyCAT | 0:543d6784d4cc | 163 | { |
EasyCAT | 0:543d6784d4cc | 164 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 165 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 166 | } |
EasyCAT | 0:543d6784d4cc | 167 | } |
EasyCAT | 0:543d6784d4cc | 168 | } |
EasyCAT | 0:543d6784d4cc | 169 | return wkc; |
EasyCAT | 0:543d6784d4cc | 170 | } |
EasyCAT | 0:543d6784d4cc | 171 | |
EasyCAT | 0:543d6784d4cc | 172 | /** EoE EOE get IP, blocking. Waits for response from the slave. |
EasyCAT | 0:543d6784d4cc | 173 | * |
EasyCAT | 0:543d6784d4cc | 174 | * @param[in] context = Context struct |
EasyCAT | 0:543d6784d4cc | 175 | * @param[in] slave = Slave number |
EasyCAT | 0:543d6784d4cc | 176 | * @param[in] port = Port number on slave if applicable |
EasyCAT | 0:543d6784d4cc | 177 | * @param[out] ipparam = IP parameter data retrived from slave |
EasyCAT | 0:543d6784d4cc | 178 | * @param[in] Timeout = Timeout in us, standard is EC_TIMEOUTRXM |
EasyCAT | 0:543d6784d4cc | 179 | * @return Workcounter from last slave response or returned result code |
EasyCAT | 0:543d6784d4cc | 180 | */ |
EasyCAT | 0:543d6784d4cc | 181 | int ecx_EOEgetIp(ecx_contextt *context, uint16 slave, uint8 port, eoe_param_t * ipparam, int timeout) |
EasyCAT | 0:543d6784d4cc | 182 | { |
EasyCAT | 0:543d6784d4cc | 183 | ec_EOEt *EOEp, *aEOEp; |
EasyCAT | 0:543d6784d4cc | 184 | ec_mbxbuft MbxIn, MbxOut; |
EasyCAT | 0:543d6784d4cc | 185 | uint16 frameinfo1, eoedatasize; |
EasyCAT | 0:543d6784d4cc | 186 | uint8 cnt, data_offset; |
EasyCAT | 0:543d6784d4cc | 187 | uint8 flags = 0; |
EasyCAT | 0:543d6784d4cc | 188 | int wkc; |
EasyCAT | 0:543d6784d4cc | 189 | |
EasyCAT | 0:543d6784d4cc | 190 | /* Empty slave out mailbox if something is in. Timout set to 0 */ |
EasyCAT | 0:543d6784d4cc | 191 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, 0); |
EasyCAT | 0:543d6784d4cc | 192 | ec_clearmbx(&MbxOut); |
EasyCAT | 0:543d6784d4cc | 193 | aEOEp = (ec_EOEt *)&MbxIn; |
EasyCAT | 0:543d6784d4cc | 194 | EOEp = (ec_EOEt *)&MbxOut; |
EasyCAT | 0:543d6784d4cc | 195 | EOEp->mbxheader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 196 | EOEp->mbxheader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 197 | data_offset = EOE_PARAM_OFFSET; |
EasyCAT | 0:543d6784d4cc | 198 | |
EasyCAT | 0:543d6784d4cc | 199 | /* get new mailbox count value, used as session handle */ |
EasyCAT | 0:543d6784d4cc | 200 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 201 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 202 | |
EasyCAT | 0:543d6784d4cc | 203 | EOEp->mbxheader.mbxtype = ECT_MBXT_EOE + (cnt << 4); /* EoE */ |
EasyCAT | 0:543d6784d4cc | 204 | |
EasyCAT | 0:543d6784d4cc | 205 | EOEp->frameinfo1 = htoes(EOE_HDR_FRAME_TYPE_SET(EOE_GET_IP_PARAM_REQ) | |
EasyCAT | 0:543d6784d4cc | 206 | EOE_HDR_FRAME_PORT_SET(port) | |
EasyCAT | 0:543d6784d4cc | 207 | EOE_HDR_LAST_FRAGMENT); |
EasyCAT | 0:543d6784d4cc | 208 | EOEp->frameinfo2 = 0; |
EasyCAT | 0:543d6784d4cc | 209 | |
EasyCAT | 0:543d6784d4cc | 210 | EOEp->mbxheader.length = htoes(0x0004); |
EasyCAT | 0:543d6784d4cc | 211 | EOEp->data[0] = flags; |
EasyCAT | 0:543d6784d4cc | 212 | |
EasyCAT | 0:543d6784d4cc | 213 | /* send EoE request to slave */ |
EasyCAT | 0:543d6784d4cc | 214 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM); |
EasyCAT | 0:543d6784d4cc | 215 | if (wkc > 0) /* succeeded to place mailbox in slave ? */ |
EasyCAT | 0:543d6784d4cc | 216 | { |
EasyCAT | 0:543d6784d4cc | 217 | /* clean mailboxbuffer */ |
EasyCAT | 0:543d6784d4cc | 218 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 219 | /* read slave response */ |
EasyCAT | 0:543d6784d4cc | 220 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout); |
EasyCAT | 0:543d6784d4cc | 221 | if (wkc > 0) /* succeeded to read slave response ? */ |
EasyCAT | 0:543d6784d4cc | 222 | { |
EasyCAT | 0:543d6784d4cc | 223 | /* slave response should be FoE */ |
EasyCAT | 0:543d6784d4cc | 224 | if ((aEOEp->mbxheader.mbxtype & 0x0f) == ECT_MBXT_EOE) |
EasyCAT | 0:543d6784d4cc | 225 | { |
EasyCAT | 0:543d6784d4cc | 226 | frameinfo1 = etohs(aEOEp->frameinfo1); |
EasyCAT | 0:543d6784d4cc | 227 | eoedatasize = etohs(aEOEp->mbxheader.length) - 0x0004; |
EasyCAT | 0:543d6784d4cc | 228 | if (EOE_HDR_FRAME_TYPE_GET(frameinfo1) != EOE_GET_IP_PARAM_RESP) |
EasyCAT | 0:543d6784d4cc | 229 | { |
EasyCAT | 0:543d6784d4cc | 230 | wkc = -EOE_RESULT_UNSUPPORTED_FRAME_TYPE; |
EasyCAT | 0:543d6784d4cc | 231 | } |
EasyCAT | 0:543d6784d4cc | 232 | else |
EasyCAT | 0:543d6784d4cc | 233 | { |
EasyCAT | 0:543d6784d4cc | 234 | /* The EoE frame will include "empty" IP/DNS entries, makes |
EasyCAT | 0:543d6784d4cc | 235 | * wireshark happy. Specification say they are optional, TwinCAT |
EasyCAT | 0:543d6784d4cc | 236 | * include empty entries. |
EasyCAT | 0:543d6784d4cc | 237 | */ |
EasyCAT | 0:543d6784d4cc | 238 | flags = aEOEp->data[0]; |
EasyCAT | 0:543d6784d4cc | 239 | if (flags & EOE_PARAM_MAC_INCLUDE) |
EasyCAT | 0:543d6784d4cc | 240 | { |
EasyCAT | 0:543d6784d4cc | 241 | memcpy(ipparam->mac.addr, |
EasyCAT | 0:543d6784d4cc | 242 | &aEOEp->data[data_offset], |
EasyCAT | 0:543d6784d4cc | 243 | EOE_ETHADDR_LENGTH); |
EasyCAT | 0:543d6784d4cc | 244 | ipparam->mac_set = 1; |
EasyCAT | 0:543d6784d4cc | 245 | } |
EasyCAT | 0:543d6784d4cc | 246 | data_offset += EOE_ETHADDR_LENGTH; |
EasyCAT | 0:543d6784d4cc | 247 | if (flags & EOE_PARAM_IP_INCLUDE) |
EasyCAT | 0:543d6784d4cc | 248 | { |
EasyCAT | 0:543d6784d4cc | 249 | EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], |
EasyCAT | 0:543d6784d4cc | 250 | &ipparam->ip); |
EasyCAT | 0:543d6784d4cc | 251 | ipparam->ip_set = 1; |
EasyCAT | 0:543d6784d4cc | 252 | } |
EasyCAT | 0:543d6784d4cc | 253 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 254 | if (flags & EOE_PARAM_SUBNET_IP_INCLUDE) |
EasyCAT | 0:543d6784d4cc | 255 | { |
EasyCAT | 0:543d6784d4cc | 256 | EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], |
EasyCAT | 0:543d6784d4cc | 257 | &ipparam->subnet); |
EasyCAT | 0:543d6784d4cc | 258 | ipparam->subnet_set = 1; |
EasyCAT | 0:543d6784d4cc | 259 | } |
EasyCAT | 0:543d6784d4cc | 260 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 261 | if (flags & EOE_PARAM_DEFAULT_GATEWAY_INCLUDE) |
EasyCAT | 0:543d6784d4cc | 262 | { |
EasyCAT | 0:543d6784d4cc | 263 | EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], |
EasyCAT | 0:543d6784d4cc | 264 | &ipparam->default_gateway); |
EasyCAT | 0:543d6784d4cc | 265 | ipparam->default_gateway_set = 1; |
EasyCAT | 0:543d6784d4cc | 266 | } |
EasyCAT | 0:543d6784d4cc | 267 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 268 | if (flags & EOE_PARAM_DNS_IP_INCLUDE) |
EasyCAT | 0:543d6784d4cc | 269 | { |
EasyCAT | 0:543d6784d4cc | 270 | EOE_ip_byte_to_uint32(&aEOEp->data[data_offset], |
EasyCAT | 0:543d6784d4cc | 271 | &ipparam->dns_ip); |
EasyCAT | 0:543d6784d4cc | 272 | ipparam->dns_ip_set = 1; |
EasyCAT | 0:543d6784d4cc | 273 | } |
EasyCAT | 0:543d6784d4cc | 274 | data_offset += 4; |
EasyCAT | 0:543d6784d4cc | 275 | if (flags & EOE_PARAM_DNS_NAME_INCLUDE) |
EasyCAT | 0:543d6784d4cc | 276 | { |
EasyCAT | 0:543d6784d4cc | 277 | uint16_t dns_len; |
EasyCAT | 0:543d6784d4cc | 278 | if ((eoedatasize - data_offset) < EOE_DNS_NAME_LENGTH) |
EasyCAT | 0:543d6784d4cc | 279 | { |
EasyCAT | 0:543d6784d4cc | 280 | dns_len = (eoedatasize - data_offset); |
EasyCAT | 0:543d6784d4cc | 281 | } |
EasyCAT | 0:543d6784d4cc | 282 | else |
EasyCAT | 0:543d6784d4cc | 283 | { |
EasyCAT | 0:543d6784d4cc | 284 | dns_len = EOE_DNS_NAME_LENGTH; |
EasyCAT | 0:543d6784d4cc | 285 | } |
EasyCAT | 0:543d6784d4cc | 286 | /* Assume ZERO terminated string */ |
EasyCAT | 0:543d6784d4cc | 287 | memcpy(ipparam->dns_name, &aEOEp->data[data_offset], dns_len); |
EasyCAT | 0:543d6784d4cc | 288 | ipparam->dns_name_set = 1; |
EasyCAT | 0:543d6784d4cc | 289 | } |
EasyCAT | 0:543d6784d4cc | 290 | data_offset += EOE_DNS_NAME_LENGTH; |
EasyCAT | 0:543d6784d4cc | 291 | /* Something os not correct, flag the error */ |
EasyCAT | 0:543d6784d4cc | 292 | if(data_offset > eoedatasize) |
EasyCAT | 0:543d6784d4cc | 293 | { |
EasyCAT | 0:543d6784d4cc | 294 | wkc = -EC_ERR_TYPE_MBX_ERROR; |
EasyCAT | 0:543d6784d4cc | 295 | } |
EasyCAT | 0:543d6784d4cc | 296 | } |
EasyCAT | 0:543d6784d4cc | 297 | } |
EasyCAT | 0:543d6784d4cc | 298 | else |
EasyCAT | 0:543d6784d4cc | 299 | { |
EasyCAT | 0:543d6784d4cc | 300 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 301 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 302 | } |
EasyCAT | 0:543d6784d4cc | 303 | } |
EasyCAT | 0:543d6784d4cc | 304 | } |
EasyCAT | 0:543d6784d4cc | 305 | return wkc; |
EasyCAT | 0:543d6784d4cc | 306 | } |
EasyCAT | 0:543d6784d4cc | 307 | |
EasyCAT | 0:543d6784d4cc | 308 | /** EoE ethernet buffer write, blocking. |
EasyCAT | 0:543d6784d4cc | 309 | * |
EasyCAT | 0:543d6784d4cc | 310 | * If the buffer is larger than the mailbox size then the buffer is sent in |
EasyCAT | 0:543d6784d4cc | 311 | * several fragments. The function will split the buf data in fragments and |
EasyCAT | 0:543d6784d4cc | 312 | * send them to the slave one by one. |
EasyCAT | 0:543d6784d4cc | 313 | * |
EasyCAT | 0:543d6784d4cc | 314 | * @param[in] context = context struct |
EasyCAT | 0:543d6784d4cc | 315 | * @param[in] slave = Slave number |
EasyCAT | 0:543d6784d4cc | 316 | * @param[in] port = Port number on slave if applicable |
EasyCAT | 0:543d6784d4cc | 317 | * @param[in] psize = Size in bytes of parameter buffer. |
EasyCAT | 0:543d6784d4cc | 318 | * @param[in] p = Pointer to parameter buffer |
EasyCAT | 0:543d6784d4cc | 319 | * @param[in] Timeout = Timeout in us, standard is EC_TIMEOUTRXM |
EasyCAT | 0:543d6784d4cc | 320 | * @return Workcounter from last slave transmission |
EasyCAT | 0:543d6784d4cc | 321 | */ |
EasyCAT | 0:543d6784d4cc | 322 | int ecx_EOEsend(ecx_contextt *context, uint16 slave, uint8 port, int psize, void *p, int timeout) |
EasyCAT | 0:543d6784d4cc | 323 | { |
EasyCAT | 0:543d6784d4cc | 324 | ec_EOEt *EOEp; |
EasyCAT | 0:543d6784d4cc | 325 | ec_mbxbuft MbxOut; |
EasyCAT | 0:543d6784d4cc | 326 | uint16 frameinfo1, frameinfo2; |
EasyCAT | 0:543d6784d4cc | 327 | uint16 txframesize, txframeoffset; |
EasyCAT | 0:543d6784d4cc | 328 | uint8 cnt, txfragmentno; |
EasyCAT | 0:543d6784d4cc | 329 | boolean NotLast; |
EasyCAT | 0:543d6784d4cc | 330 | int wkc, maxdata; |
EasyCAT | 0:543d6784d4cc | 331 | const uint8 * buf = p; |
EasyCAT | 0:543d6784d4cc | 332 | static uint8_t txframeno = 0; |
EasyCAT | 0:543d6784d4cc | 333 | |
EasyCAT | 0:543d6784d4cc | 334 | ec_clearmbx(&MbxOut); |
EasyCAT | 0:543d6784d4cc | 335 | EOEp = (ec_EOEt *)&MbxOut; |
EasyCAT | 0:543d6784d4cc | 336 | EOEp->mbxheader.address = htoes(0x0000); |
EasyCAT | 0:543d6784d4cc | 337 | EOEp->mbxheader.priority = 0x00; |
EasyCAT | 0:543d6784d4cc | 338 | /* data section=mailbox size - 6 mbx - 4 EoEh */ |
EasyCAT | 0:543d6784d4cc | 339 | maxdata = context->slavelist[slave].mbx_l - 0x0A; |
EasyCAT | 0:543d6784d4cc | 340 | txframesize = psize; |
EasyCAT | 0:543d6784d4cc | 341 | txfragmentno = 0; |
EasyCAT | 0:543d6784d4cc | 342 | txframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 343 | NotLast = TRUE; |
EasyCAT | 0:543d6784d4cc | 344 | |
EasyCAT | 0:543d6784d4cc | 345 | do |
EasyCAT | 0:543d6784d4cc | 346 | { |
EasyCAT | 0:543d6784d4cc | 347 | txframesize = psize - txframeoffset; |
EasyCAT | 0:543d6784d4cc | 348 | if (txframesize > maxdata) |
EasyCAT | 0:543d6784d4cc | 349 | { |
EasyCAT | 0:543d6784d4cc | 350 | /* Adjust to even 32-octect blocks */ |
EasyCAT | 0:543d6784d4cc | 351 | txframesize = ((maxdata >> 5) << 5); |
EasyCAT | 0:543d6784d4cc | 352 | } |
EasyCAT | 0:543d6784d4cc | 353 | |
EasyCAT | 0:543d6784d4cc | 354 | if (txframesize == (psize - txframeoffset)) |
EasyCAT | 0:543d6784d4cc | 355 | { |
EasyCAT | 0:543d6784d4cc | 356 | frameinfo1 = (EOE_HDR_LAST_FRAGMENT_SET(1) | EOE_HDR_FRAME_PORT_SET(port)); |
EasyCAT | 0:543d6784d4cc | 357 | NotLast = FALSE; |
EasyCAT | 0:543d6784d4cc | 358 | } |
EasyCAT | 0:543d6784d4cc | 359 | else |
EasyCAT | 0:543d6784d4cc | 360 | { |
EasyCAT | 0:543d6784d4cc | 361 | frameinfo1 = EOE_HDR_FRAME_PORT_SET(port); |
EasyCAT | 0:543d6784d4cc | 362 | } |
EasyCAT | 0:543d6784d4cc | 363 | |
EasyCAT | 0:543d6784d4cc | 364 | frameinfo2 = EOE_HDR_FRAG_NO_SET(txfragmentno); |
EasyCAT | 0:543d6784d4cc | 365 | if (txfragmentno > 0) |
EasyCAT | 0:543d6784d4cc | 366 | { |
EasyCAT | 0:543d6784d4cc | 367 | frameinfo2 = frameinfo2 | (EOE_HDR_FRAME_OFFSET_SET((txframeoffset >> 5))); |
EasyCAT | 0:543d6784d4cc | 368 | } |
EasyCAT | 0:543d6784d4cc | 369 | else |
EasyCAT | 0:543d6784d4cc | 370 | { |
EasyCAT | 0:543d6784d4cc | 371 | frameinfo2 = frameinfo2 | (EOE_HDR_FRAME_OFFSET_SET(((psize + 31) >> 5))); |
EasyCAT | 0:543d6784d4cc | 372 | txframeno++; |
EasyCAT | 0:543d6784d4cc | 373 | } |
EasyCAT | 0:543d6784d4cc | 374 | frameinfo2 = frameinfo2 | EOE_HDR_FRAME_NO_SET(txframeno); |
EasyCAT | 0:543d6784d4cc | 375 | |
EasyCAT | 0:543d6784d4cc | 376 | /* get new mailbox count value, used as session handle */ |
EasyCAT | 0:543d6784d4cc | 377 | cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt); |
EasyCAT | 0:543d6784d4cc | 378 | context->slavelist[slave].mbx_cnt = cnt; |
EasyCAT | 0:543d6784d4cc | 379 | |
EasyCAT | 0:543d6784d4cc | 380 | EOEp->mbxheader.length = htoes(4 + txframesize); /* no timestamp */ |
EasyCAT | 0:543d6784d4cc | 381 | EOEp->mbxheader.mbxtype = ECT_MBXT_EOE + (cnt << 4); /* EoE */ |
EasyCAT | 0:543d6784d4cc | 382 | |
EasyCAT | 0:543d6784d4cc | 383 | EOEp->frameinfo1 = htoes(frameinfo1); |
EasyCAT | 0:543d6784d4cc | 384 | EOEp->frameinfo2 = htoes(frameinfo2); |
EasyCAT | 0:543d6784d4cc | 385 | |
EasyCAT | 0:543d6784d4cc | 386 | memcpy(EOEp->data, &buf[txframeoffset], txframesize); |
EasyCAT | 0:543d6784d4cc | 387 | |
EasyCAT | 0:543d6784d4cc | 388 | /* send EoE request to slave */ |
EasyCAT | 0:543d6784d4cc | 389 | wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, timeout); |
EasyCAT | 0:543d6784d4cc | 390 | if ((NotLast == TRUE) && (wkc > 0)) |
EasyCAT | 0:543d6784d4cc | 391 | { |
EasyCAT | 0:543d6784d4cc | 392 | txframeoffset += txframesize; |
EasyCAT | 0:543d6784d4cc | 393 | txfragmentno++; |
EasyCAT | 0:543d6784d4cc | 394 | } |
EasyCAT | 0:543d6784d4cc | 395 | } while ((NotLast == TRUE) && (wkc > 0)); |
EasyCAT | 0:543d6784d4cc | 396 | |
EasyCAT | 0:543d6784d4cc | 397 | return wkc; |
EasyCAT | 0:543d6784d4cc | 398 | } |
EasyCAT | 0:543d6784d4cc | 399 | |
EasyCAT | 0:543d6784d4cc | 400 | |
EasyCAT | 0:543d6784d4cc | 401 | /** EoE ethernet buffer read, blocking. |
EasyCAT | 0:543d6784d4cc | 402 | * |
EasyCAT | 0:543d6784d4cc | 403 | * If the buffer is larger than the mailbox size then the buffer is received |
EasyCAT | 0:543d6784d4cc | 404 | * by several fragments. The function will assamble the fragments into |
EasyCAT | 0:543d6784d4cc | 405 | * a complete Ethernet buffer. |
EasyCAT | 0:543d6784d4cc | 406 | * |
EasyCAT | 0:543d6784d4cc | 407 | * @param[in] context = context struct |
EasyCAT | 0:543d6784d4cc | 408 | * @param[in] slave = Slave number |
EasyCAT | 0:543d6784d4cc | 409 | * @param[in] port = Port number on slave if applicable |
EasyCAT | 0:543d6784d4cc | 410 | * @param[in/out] psize = Size in bytes of parameter buffer. |
EasyCAT | 0:543d6784d4cc | 411 | * @param[in] p = Pointer to parameter buffer |
EasyCAT | 0:543d6784d4cc | 412 | * @param[in] timeout = Timeout in us, standard is EC_TIMEOUTRXM |
EasyCAT | 0:543d6784d4cc | 413 | * @return Workcounter from last slave response or error code |
EasyCAT | 0:543d6784d4cc | 414 | */ |
EasyCAT | 0:543d6784d4cc | 415 | int ecx_EOErecv(ecx_contextt *context, uint16 slave, uint8 port, int * psize, void *p, int timeout) |
EasyCAT | 0:543d6784d4cc | 416 | { |
EasyCAT | 0:543d6784d4cc | 417 | ec_EOEt *aEOEp; |
EasyCAT | 0:543d6784d4cc | 418 | ec_mbxbuft MbxIn; |
EasyCAT | 0:543d6784d4cc | 419 | uint16 frameinfo1, frameinfo2, rxframesize, rxframeoffset, eoedatasize; |
EasyCAT | 0:543d6784d4cc | 420 | uint8 rxfragmentno, rxframeno; |
EasyCAT | 0:543d6784d4cc | 421 | boolean NotLast; |
EasyCAT | 0:543d6784d4cc | 422 | int wkc, buffersize; |
EasyCAT | 0:543d6784d4cc | 423 | uint8 * buf = p; |
EasyCAT | 0:543d6784d4cc | 424 | |
EasyCAT | 0:543d6784d4cc | 425 | ec_clearmbx(&MbxIn); |
EasyCAT | 0:543d6784d4cc | 426 | aEOEp = (ec_EOEt *)&MbxIn; |
EasyCAT | 0:543d6784d4cc | 427 | NotLast = TRUE; |
EasyCAT | 0:543d6784d4cc | 428 | buffersize = *psize; |
EasyCAT | 0:543d6784d4cc | 429 | rxfragmentno = 0; |
EasyCAT | 0:543d6784d4cc | 430 | |
EasyCAT | 0:543d6784d4cc | 431 | /* Hang for a while if nothing is in */ |
EasyCAT | 0:543d6784d4cc | 432 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout); |
EasyCAT | 0:543d6784d4cc | 433 | |
EasyCAT | 0:543d6784d4cc | 434 | while ((wkc > 0) && (NotLast == TRUE)) |
EasyCAT | 0:543d6784d4cc | 435 | { |
EasyCAT | 0:543d6784d4cc | 436 | /* slave response should be FoE */ |
EasyCAT | 0:543d6784d4cc | 437 | if ((aEOEp->mbxheader.mbxtype & 0x0f) == ECT_MBXT_EOE) |
EasyCAT | 0:543d6784d4cc | 438 | { |
EasyCAT | 0:543d6784d4cc | 439 | |
EasyCAT | 0:543d6784d4cc | 440 | eoedatasize = etohs(aEOEp->mbxheader.length) - 0x00004; |
EasyCAT | 0:543d6784d4cc | 441 | frameinfo1 = etohs(aEOEp->frameinfo1); |
EasyCAT | 0:543d6784d4cc | 442 | frameinfo2 = etohs(aEOEp->frameinfo2); |
EasyCAT | 0:543d6784d4cc | 443 | |
EasyCAT | 0:543d6784d4cc | 444 | if (rxfragmentno != EOE_HDR_FRAG_NO_GET(frameinfo2)) |
EasyCAT | 0:543d6784d4cc | 445 | { |
EasyCAT | 0:543d6784d4cc | 446 | if (EOE_HDR_FRAG_NO_GET(frameinfo2) > 0) |
EasyCAT | 0:543d6784d4cc | 447 | { |
EasyCAT | 0:543d6784d4cc | 448 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 449 | /* Exit here*/ |
EasyCAT | 0:543d6784d4cc | 450 | break; |
EasyCAT | 0:543d6784d4cc | 451 | } |
EasyCAT | 0:543d6784d4cc | 452 | } |
EasyCAT | 0:543d6784d4cc | 453 | |
EasyCAT | 0:543d6784d4cc | 454 | if (rxfragmentno == 0) |
EasyCAT | 0:543d6784d4cc | 455 | { |
EasyCAT | 0:543d6784d4cc | 456 | rxframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 457 | rxframeno = EOE_HDR_FRAME_NO_GET(frameinfo2); |
EasyCAT | 0:543d6784d4cc | 458 | rxframesize = (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5); |
EasyCAT | 0:543d6784d4cc | 459 | if (rxframesize > buffersize) |
EasyCAT | 0:543d6784d4cc | 460 | { |
EasyCAT | 0:543d6784d4cc | 461 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 462 | /* Exit here*/ |
EasyCAT | 0:543d6784d4cc | 463 | break; |
EasyCAT | 0:543d6784d4cc | 464 | } |
EasyCAT | 0:543d6784d4cc | 465 | if (port != EOE_HDR_FRAME_PORT_GET(frameinfo1)) |
EasyCAT | 0:543d6784d4cc | 466 | { |
EasyCAT | 0:543d6784d4cc | 467 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 468 | /* Exit here*/ |
EasyCAT | 0:543d6784d4cc | 469 | break; |
EasyCAT | 0:543d6784d4cc | 470 | } |
EasyCAT | 0:543d6784d4cc | 471 | } |
EasyCAT | 0:543d6784d4cc | 472 | else |
EasyCAT | 0:543d6784d4cc | 473 | { |
EasyCAT | 0:543d6784d4cc | 474 | if (rxframeno != EOE_HDR_FRAME_NO_GET(frameinfo2)) |
EasyCAT | 0:543d6784d4cc | 475 | { |
EasyCAT | 0:543d6784d4cc | 476 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 477 | /* Exit here*/ |
EasyCAT | 0:543d6784d4cc | 478 | break; |
EasyCAT | 0:543d6784d4cc | 479 | } |
EasyCAT | 0:543d6784d4cc | 480 | else if (rxframeoffset != (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5)) |
EasyCAT | 0:543d6784d4cc | 481 | { |
EasyCAT | 0:543d6784d4cc | 482 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 483 | /* Exit here*/ |
EasyCAT | 0:543d6784d4cc | 484 | break; |
EasyCAT | 0:543d6784d4cc | 485 | } |
EasyCAT | 0:543d6784d4cc | 486 | } |
EasyCAT | 0:543d6784d4cc | 487 | |
EasyCAT | 0:543d6784d4cc | 488 | if ((rxframeoffset + eoedatasize) <= buffersize) |
EasyCAT | 0:543d6784d4cc | 489 | { |
EasyCAT | 0:543d6784d4cc | 490 | memcpy(&buf[rxframeoffset], aEOEp->data, eoedatasize); |
EasyCAT | 0:543d6784d4cc | 491 | rxframeoffset += eoedatasize; |
EasyCAT | 0:543d6784d4cc | 492 | rxfragmentno++; |
EasyCAT | 0:543d6784d4cc | 493 | } |
EasyCAT | 0:543d6784d4cc | 494 | |
EasyCAT | 0:543d6784d4cc | 495 | if (EOE_HDR_LAST_FRAGMENT_GET(frameinfo1)) |
EasyCAT | 0:543d6784d4cc | 496 | { |
EasyCAT | 0:543d6784d4cc | 497 | /* Remove timestamp */ |
EasyCAT | 0:543d6784d4cc | 498 | if (EOE_HDR_TIME_APPEND_GET(frameinfo1)) |
EasyCAT | 0:543d6784d4cc | 499 | { |
EasyCAT | 0:543d6784d4cc | 500 | rxframeoffset -= 4; |
EasyCAT | 0:543d6784d4cc | 501 | } |
EasyCAT | 0:543d6784d4cc | 502 | NotLast = FALSE; |
EasyCAT | 0:543d6784d4cc | 503 | *psize = rxframeoffset; |
EasyCAT | 0:543d6784d4cc | 504 | } |
EasyCAT | 0:543d6784d4cc | 505 | else |
EasyCAT | 0:543d6784d4cc | 506 | { |
EasyCAT | 0:543d6784d4cc | 507 | /* Hang for a while if nothing is in */ |
EasyCAT | 0:543d6784d4cc | 508 | wkc = ecx_mbxreceive(context, slave, (ec_mbxbuft *)&MbxIn, timeout); |
EasyCAT | 0:543d6784d4cc | 509 | } |
EasyCAT | 0:543d6784d4cc | 510 | } |
EasyCAT | 0:543d6784d4cc | 511 | else |
EasyCAT | 0:543d6784d4cc | 512 | { |
EasyCAT | 0:543d6784d4cc | 513 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 514 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 515 | } |
EasyCAT | 0:543d6784d4cc | 516 | } |
EasyCAT | 0:543d6784d4cc | 517 | return wkc; |
EasyCAT | 0:543d6784d4cc | 518 | } |
EasyCAT | 0:543d6784d4cc | 519 | |
EasyCAT | 0:543d6784d4cc | 520 | /** EoE mailbox fragment read |
EasyCAT | 0:543d6784d4cc | 521 | * |
EasyCAT | 0:543d6784d4cc | 522 | * Will take the data in incoming mailbox buffer and copy to destination |
EasyCAT | 0:543d6784d4cc | 523 | * Ethernet frame buffer at given offset and update current fragment variables |
EasyCAT | 0:543d6784d4cc | 524 | * |
EasyCAT | 0:543d6784d4cc | 525 | * @param[in] MbxIn = Received mailbox containing fragment data |
EasyCAT | 0:543d6784d4cc | 526 | * @param[in/out] rxfragmentno = Fragment number |
EasyCAT | 0:543d6784d4cc | 527 | * @param[in/out] rxframesize = Frame size |
EasyCAT | 0:543d6784d4cc | 528 | * @param[in/out] rxframeoffset = Frame offset |
EasyCAT | 0:543d6784d4cc | 529 | * @param[in/out] rxframeno = Frame number |
EasyCAT | 0:543d6784d4cc | 530 | * @param[in/out] psize = Size in bytes of frame buffer. |
EasyCAT | 0:543d6784d4cc | 531 | * @param[out] p = Pointer to frame buffer |
EasyCAT | 0:543d6784d4cc | 532 | * @return 0= if fragment OK, >0 if last fragment, <0 on error |
EasyCAT | 0:543d6784d4cc | 533 | */ |
EasyCAT | 0:543d6784d4cc | 534 | int ecx_EOEreadfragment( |
EasyCAT | 0:543d6784d4cc | 535 | ec_mbxbuft * MbxIn, |
EasyCAT | 0:543d6784d4cc | 536 | uint8 * rxfragmentno, |
EasyCAT | 0:543d6784d4cc | 537 | uint16 * rxframesize, |
EasyCAT | 0:543d6784d4cc | 538 | uint16 * rxframeoffset, |
EasyCAT | 0:543d6784d4cc | 539 | uint16 * rxframeno, |
EasyCAT | 0:543d6784d4cc | 540 | int * psize, |
EasyCAT | 0:543d6784d4cc | 541 | void *p) |
EasyCAT | 0:543d6784d4cc | 542 | { |
EasyCAT | 0:543d6784d4cc | 543 | uint16 frameinfo1, frameinfo2, eoedatasize; |
EasyCAT | 0:543d6784d4cc | 544 | int wkc; |
EasyCAT | 0:543d6784d4cc | 545 | ec_EOEt * aEOEp; |
EasyCAT | 0:543d6784d4cc | 546 | uint8 * buf; |
EasyCAT | 0:543d6784d4cc | 547 | |
EasyCAT | 0:543d6784d4cc | 548 | aEOEp = (ec_EOEt *)MbxIn; |
EasyCAT | 0:543d6784d4cc | 549 | buf = p; |
EasyCAT | 0:543d6784d4cc | 550 | wkc = 0; |
EasyCAT | 0:543d6784d4cc | 551 | |
EasyCAT | 0:543d6784d4cc | 552 | /* slave response should be EoE */ |
EasyCAT | 0:543d6784d4cc | 553 | if ((aEOEp->mbxheader.mbxtype & 0x0f) == ECT_MBXT_EOE) |
EasyCAT | 0:543d6784d4cc | 554 | { |
EasyCAT | 0:543d6784d4cc | 555 | eoedatasize = etohs(aEOEp->mbxheader.length) - 0x00004; |
EasyCAT | 0:543d6784d4cc | 556 | frameinfo1 = etohs(aEOEp->frameinfo1); |
EasyCAT | 0:543d6784d4cc | 557 | frameinfo2 = etohs(aEOEp->frameinfo2); |
EasyCAT | 0:543d6784d4cc | 558 | |
EasyCAT | 0:543d6784d4cc | 559 | /* Retrive fragment number, is it what we expect? */ |
EasyCAT | 0:543d6784d4cc | 560 | if (*rxfragmentno != EOE_HDR_FRAG_NO_GET(frameinfo2)) |
EasyCAT | 0:543d6784d4cc | 561 | { |
EasyCAT | 0:543d6784d4cc | 562 | /* If expected fragment number is not 0, reset working variables */ |
EasyCAT | 0:543d6784d4cc | 563 | if (*rxfragmentno != 0) |
EasyCAT | 0:543d6784d4cc | 564 | { |
EasyCAT | 0:543d6784d4cc | 565 | *rxfragmentno = 0; |
EasyCAT | 0:543d6784d4cc | 566 | *rxframesize = 0; |
EasyCAT | 0:543d6784d4cc | 567 | *rxframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 568 | *rxframeno = 0; |
EasyCAT | 0:543d6784d4cc | 569 | } |
EasyCAT | 0:543d6784d4cc | 570 | |
EasyCAT | 0:543d6784d4cc | 571 | /* If incoming fragment number is not 0 we can't recover, exit */ |
EasyCAT | 0:543d6784d4cc | 572 | if (EOE_HDR_FRAG_NO_GET(frameinfo2) > 0) |
EasyCAT | 0:543d6784d4cc | 573 | { |
EasyCAT | 0:543d6784d4cc | 574 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 575 | return wkc; |
EasyCAT | 0:543d6784d4cc | 576 | } |
EasyCAT | 0:543d6784d4cc | 577 | } |
EasyCAT | 0:543d6784d4cc | 578 | |
EasyCAT | 0:543d6784d4cc | 579 | /* Is it a new frame?*/ |
EasyCAT | 0:543d6784d4cc | 580 | if (*rxfragmentno == 0) |
EasyCAT | 0:543d6784d4cc | 581 | { |
EasyCAT | 0:543d6784d4cc | 582 | *rxframesize = (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5); |
EasyCAT | 0:543d6784d4cc | 583 | *rxframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 584 | *rxframeno = EOE_HDR_FRAME_NO_GET(frameinfo2); |
EasyCAT | 0:543d6784d4cc | 585 | } |
EasyCAT | 0:543d6784d4cc | 586 | else |
EasyCAT | 0:543d6784d4cc | 587 | { |
EasyCAT | 0:543d6784d4cc | 588 | /* If we're inside a frame, make sure it is the same */ |
EasyCAT | 0:543d6784d4cc | 589 | if (*rxframeno != EOE_HDR_FRAME_NO_GET(frameinfo2)) |
EasyCAT | 0:543d6784d4cc | 590 | { |
EasyCAT | 0:543d6784d4cc | 591 | *rxfragmentno = 0; |
EasyCAT | 0:543d6784d4cc | 592 | *rxframesize = 0; |
EasyCAT | 0:543d6784d4cc | 593 | *rxframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 594 | *rxframeno = 0; |
EasyCAT | 0:543d6784d4cc | 595 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 596 | return wkc; |
EasyCAT | 0:543d6784d4cc | 597 | } |
EasyCAT | 0:543d6784d4cc | 598 | else if (*rxframeoffset != (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5)) |
EasyCAT | 0:543d6784d4cc | 599 | { |
EasyCAT | 0:543d6784d4cc | 600 | *rxfragmentno = 0; |
EasyCAT | 0:543d6784d4cc | 601 | *rxframesize = 0; |
EasyCAT | 0:543d6784d4cc | 602 | *rxframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 603 | *rxframeno = 0; |
EasyCAT | 0:543d6784d4cc | 604 | wkc = -EC_ERR_TYPE_EOE_INVALID_RX_DATA; |
EasyCAT | 0:543d6784d4cc | 605 | return wkc; |
EasyCAT | 0:543d6784d4cc | 606 | } |
EasyCAT | 0:543d6784d4cc | 607 | } |
EasyCAT | 0:543d6784d4cc | 608 | |
EasyCAT | 0:543d6784d4cc | 609 | /* Make sure we're inside expected frame size */ |
EasyCAT | 0:543d6784d4cc | 610 | if (((*rxframeoffset + eoedatasize) <= *rxframesize) && |
EasyCAT | 0:543d6784d4cc | 611 | ((*rxframeoffset + eoedatasize) <= *psize)) |
EasyCAT | 0:543d6784d4cc | 612 | { |
EasyCAT | 0:543d6784d4cc | 613 | memcpy(&buf[*rxframeoffset], aEOEp->data, eoedatasize); |
EasyCAT | 0:543d6784d4cc | 614 | *rxframeoffset += eoedatasize; |
EasyCAT | 0:543d6784d4cc | 615 | *rxfragmentno += 1; |
EasyCAT | 0:543d6784d4cc | 616 | } |
EasyCAT | 0:543d6784d4cc | 617 | |
EasyCAT | 0:543d6784d4cc | 618 | /* Is it the last fragment */ |
EasyCAT | 0:543d6784d4cc | 619 | if (EOE_HDR_LAST_FRAGMENT_GET(frameinfo1)) |
EasyCAT | 0:543d6784d4cc | 620 | { |
EasyCAT | 0:543d6784d4cc | 621 | /* Remove timestamp */ |
EasyCAT | 0:543d6784d4cc | 622 | if (EOE_HDR_TIME_APPEND_GET(frameinfo1)) |
EasyCAT | 0:543d6784d4cc | 623 | { |
EasyCAT | 0:543d6784d4cc | 624 | *rxframeoffset -= 4; |
EasyCAT | 0:543d6784d4cc | 625 | } |
EasyCAT | 0:543d6784d4cc | 626 | *psize = *rxframeoffset; |
EasyCAT | 0:543d6784d4cc | 627 | *rxfragmentno = 0; |
EasyCAT | 0:543d6784d4cc | 628 | *rxframesize = 0; |
EasyCAT | 0:543d6784d4cc | 629 | *rxframeoffset = 0; |
EasyCAT | 0:543d6784d4cc | 630 | *rxframeno = 0; |
EasyCAT | 0:543d6784d4cc | 631 | wkc = 1; |
EasyCAT | 0:543d6784d4cc | 632 | } |
EasyCAT | 0:543d6784d4cc | 633 | } |
EasyCAT | 0:543d6784d4cc | 634 | else |
EasyCAT | 0:543d6784d4cc | 635 | { |
EasyCAT | 0:543d6784d4cc | 636 | /* unexpected mailbox received */ |
EasyCAT | 0:543d6784d4cc | 637 | wkc = -EC_ERR_TYPE_PACKET_ERROR; |
EasyCAT | 0:543d6784d4cc | 638 | } |
EasyCAT | 0:543d6784d4cc | 639 | return wkc; |
EasyCAT | 0:543d6784d4cc | 640 | } |