2018-11-13 11:14:19 +01:00
|
|
|
/*
|
|
|
|
* Licensed under the GNU General Public License version 2 with exceptions. See
|
|
|
|
* LICENSE file in the project root for full license information
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
* \brief
|
|
|
|
* Ethernet over EtherCAT (EoE) module.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cc.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "esc.h"
|
|
|
|
#include "esc_eoe.h"
|
|
|
|
|
|
|
|
|
|
|
|
#if defined(EC_BIG_ENDIAN)
|
|
|
|
#define EOE_HTONS(x) (x)
|
|
|
|
#define EOE_NTOHS(x) (x)
|
|
|
|
#define EOE_HTONL(x) (x)
|
|
|
|
#define EOE_NTOHL(x) (x)
|
|
|
|
#else
|
|
|
|
#define EOE_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
|
|
|
|
#define EOE_NTOHS(x) EOE_HTONS(x)
|
|
|
|
#define EOE_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
|
|
|
|
(((x) & 0x0000ff00UL) << 8) | \
|
|
|
|
(((x) & 0x00ff0000UL) >> 8) | \
|
|
|
|
(((x) & 0xff000000UL) >> 24))
|
|
|
|
#define EOE_NTOHL(x) EOE_HTONL(x)
|
|
|
|
#endif /* #if defined(EC_BIG_ENDIAN) */
|
|
|
|
|
|
|
|
#define EOE_MAKEU32(a,b,c,d) (((uint32_t)((a) & 0xff) << 24) | \
|
|
|
|
((uint32_t)((b) & 0xff) << 16) | \
|
|
|
|
((uint32_t)((c) & 0xff) << 8) | \
|
|
|
|
(uint32_t)((d) & 0xff))
|
|
|
|
|
|
|
|
/** Get one byte from the 4-byte address */
|
|
|
|
#define eoe_ip4_addr1(ipaddr) (((const uint8_t*)(&(ipaddr)->addr))[0])
|
|
|
|
#define eoe_ip4_addr2(ipaddr) (((const uint8_t*)(&(ipaddr)->addr))[1])
|
|
|
|
#define eoe_ip4_addr3(ipaddr) (((const uint8_t*)(&(ipaddr)->addr))[2])
|
|
|
|
#define eoe_ip4_addr4(ipaddr) (((const uint8_t*)(&(ipaddr)->addr))[3])
|
|
|
|
|
|
|
|
/** Set an IP address given by the four byte-parts */
|
|
|
|
#define EOE_IP4_ADDR_TO_U32(ipaddr,a,b,c,d) \
|
|
|
|
(ipaddr)->addr = EOE_HTONL(EOE_MAKEU32(a,b,c,d))
|
|
|
|
|
|
|
|
/** Header frame info 1 */
|
|
|
|
#define EOE_HDR_FRAME_TYPE_OFFSET 0
|
|
|
|
#define EOE_HDR_FRAME_TYPE (0xF << 0)
|
|
|
|
#define EOE_HDR_FRAME_TYPE_SET(x) (((x) & 0xF) << 0)
|
|
|
|
#define EOE_HDR_FRAME_TYPE_GET(x) (((x) >> 0) & 0xF)
|
|
|
|
#define EOE_HDR_FRAME_PORT_OFFSET 4
|
|
|
|
#define EOE_HDR_FRAME_PORT (0xF << 4)
|
|
|
|
#define EOE_HDR_FRAME_PORT_SET(x) (((x) & 0xF) << 4)
|
|
|
|
#define EOE_HDR_FRAME_PORT_GET(x) (((x) >> 4) & 0xF)
|
|
|
|
#define EOE_HDR_LAST_FRAGMENT_OFFSET 8
|
|
|
|
#define EOE_HDR_LAST_FRAGMENT (0x1 << 8)
|
|
|
|
#define EOE_HDR_LAST_FRAGMENT_SET(x) (((x) & 0x1) << 8)
|
|
|
|
#define EOE_HDR_LAST_FRAGMENT_GET(x) (((x) >> 8) & 0x1)
|
|
|
|
#define EOE_HDR_TIME_APPEND_OFFSET 9
|
|
|
|
#define EOE_HDR_TIME_APPEND (0x1 << 9)
|
|
|
|
#define EOE_HDR_TIME_APPEND_SET(x) (((x) & 0x1) << 9)
|
|
|
|
#define EOE_HDR_TIME_APPEND_GET(x) (((x) >> 9) & 0x1)
|
|
|
|
#define EOE_HDR_TIME_REQUEST_OFFSET 10
|
|
|
|
#define EOE_HDR_TIME_REQUEST (0x1 << 10)
|
|
|
|
#define EOE_HDR_TIME_REQUEST_SET(x) (((x) & 0x1) << 10)
|
|
|
|
#define EOE_HDR_TIME_REQUEST_GET(x) (((x) >> 10) & 0x1)
|
|
|
|
|
|
|
|
/** Header frame info 2 */
|
|
|
|
#define EOE_HDR_FRAG_NO_OFFSET 0
|
|
|
|
#define EOE_HDR_FRAG_NO (0x3F << 0)
|
|
|
|
#define EOE_HDR_FRAG_NO_SET(x) (((x) & 0x3F) << 0)
|
|
|
|
#define EOE_HDR_FRAG_NO_GET(x) (((x) >> 0) & 0x3F)
|
|
|
|
#define EOE_HDR_FRAME_OFFSET_OFFSET 6
|
|
|
|
#define EOE_HDR_FRAME_OFFSET (0x3F << 6)
|
|
|
|
#define EOE_HDR_FRAME_OFFSET_SET(x) (((x) & 0x3F) << 6)
|
|
|
|
#define EOE_HDR_FRAME_OFFSET_GET(x) (((x) >> 6) & 0x3F)
|
|
|
|
#define EOE_HDR_FRAME_NO_OFFSET 12
|
|
|
|
#define EOE_HDR_FRAME_NO (0xF << 12)
|
|
|
|
#define EOE_HDR_FRAME_NO_SET(x) (((x) & 0xF) << 12)
|
|
|
|
#define EOE_HDR_FRAME_NO_GET(x) (((x) >> 12) & 0xF)
|
|
|
|
|
|
|
|
/** EOE param */
|
|
|
|
#define EOE_PARAM_OFFSET 4
|
|
|
|
#define EOE_PARAM_MAC_INCLUDE (0x1 << 0)
|
|
|
|
#define EOE_PARAM_IP_INCLUDE (0x1 << 1)
|
|
|
|
#define EOE_PARAM_SUBNET_IP_INCLUDE (0x1 << 2)
|
|
|
|
#define EOE_PARAM_DEFAULT_GATEWAY_INCLUDE (0x1 << 3)
|
|
|
|
#define EOE_PARAM_DNS_IP_INCLUDE (0x1 << 4)
|
|
|
|
#define EOE_PARAM_DNS_NAME_INCLUDE (0x1 << 5)
|
|
|
|
|
|
|
|
/** EoE frame types */
|
|
|
|
#define EOE_FRAG_DATA 0
|
|
|
|
#define EOE_INIT_RESP_TIMESTAMP 1
|
|
|
|
#define EOE_INIT_REQ 2 /* Spec SET IP REQ */
|
|
|
|
#define EOE_INIT_RESP 3 /* Spec SET IP RESP */
|
|
|
|
#define EOE_SET_ADDR_FILTER_REQ 4
|
|
|
|
#define EOE_SET_ADDR_FILTER_RESP 5
|
|
|
|
#define EOE_GET_IP_PARAM_REQ 6
|
|
|
|
#define EOE_GET_IP_PARAM_RESP 7
|
|
|
|
#define EOE_GET_ADDR_FILTER_REQ 8
|
|
|
|
#define EOE_GET_ADDR_FILTER_RESP 9
|
|
|
|
|
|
|
|
/** Define number of ports available.(Only one is supported currently */
|
|
|
|
#define EOE_NUMBER_OF_PORTS 1
|
|
|
|
#define EOE_PORT_INDEX(x) ((x > 0) ? (x - 1) : 0)
|
|
|
|
/** DNS length according to ETG 1000.6 */
|
|
|
|
#define EOE_DNS_NAME_LENGTH 32
|
|
|
|
/** Ethernet address length not including VLAN */
|
|
|
|
#define EOE_ETHADDR_LENGTH 6
|
2020-08-14 14:58:17 +02:00
|
|
|
/** IPv4 address length */
|
|
|
|
#define EOE_IP4_LENGTH sizeof(uint32_t)
|
2018-11-13 11:14:19 +01:00
|
|
|
|
|
|
|
/** EOE ip4 address in network order */
|
|
|
|
struct eoe_ip4_addr {
|
|
|
|
uint32_t addr;
|
|
|
|
};
|
|
|
|
typedef struct eoe_ip4_addr eoe_ip4_addr_t;
|
|
|
|
|
|
|
|
/** EOE ethernet address */
|
|
|
|
CC_PACKED_BEGIN
|
|
|
|
typedef struct CC_PACKED eoe_ethaddr
|
|
|
|
{
|
|
|
|
uint8_t addr[EOE_ETHADDR_LENGTH];
|
|
|
|
} eoe_ethaddr_t;
|
|
|
|
CC_PACKED_END
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
/** Pointer to current RX buffer to fill */
|
|
|
|
eoe_pbuf_t rxebuf;
|
|
|
|
/** Pointer to current TX buff to Send */
|
|
|
|
eoe_pbuf_t txebuf;
|
|
|
|
|
|
|
|
/** Current RX fragment number */
|
|
|
|
uint8_t rxfragmentno;
|
|
|
|
/** Complete RX frame size of current frame */
|
|
|
|
uint16_t rxframesize;
|
|
|
|
/** Current RX data offset in frame */
|
|
|
|
uint16_t rxframeoffset;
|
|
|
|
/** Current RX frame number */
|
|
|
|
uint16_t rxframeno;
|
|
|
|
|
|
|
|
/** Current TX fragment number */
|
|
|
|
uint8_t txfragmentno;
|
|
|
|
/** Complete TX frame size of current frame */
|
|
|
|
uint16_t txframesize;
|
|
|
|
/** Current TX data offset in frame */
|
|
|
|
uint16_t txframeoffset;
|
|
|
|
} _EOEvar;
|
|
|
|
|
|
|
|
/** EoE IP request structure */
|
|
|
|
typedef struct eoe_param
|
|
|
|
{
|
|
|
|
uint8_t mac_set:1;
|
|
|
|
uint8_t ip_set:1;
|
|
|
|
uint8_t subnet_set:1;
|
|
|
|
uint8_t default_gateway_set:1;
|
|
|
|
uint8_t dns_ip_set:1;
|
|
|
|
uint8_t dns_name_set:1;
|
|
|
|
eoe_ethaddr_t mac;
|
|
|
|
eoe_ip4_addr_t ip;
|
|
|
|
eoe_ip4_addr_t subnet;
|
|
|
|
eoe_ip4_addr_t default_gateway;
|
|
|
|
eoe_ip4_addr_t dns_ip;
|
|
|
|
char dns_name[EOE_DNS_NAME_LENGTH];
|
|
|
|
} eoe_param_t;
|
|
|
|
|
|
|
|
/** Main EoE status data array. Structure gets filled with current information
|
|
|
|
* variables during EoE receive and send operations.
|
|
|
|
*/
|
|
|
|
static _EOEvar EOEvar;
|
|
|
|
|
|
|
|
/** Main FoE configuration pointer data array. Structure is allocated and filled
|
2019-01-24 17:47:01 +01:00
|
|
|
* by the application defining what preferences it requires.
|
2018-11-13 11:14:19 +01:00
|
|
|
*/
|
|
|
|
static eoe_cfg_t * eoe_cfg;
|
|
|
|
|
|
|
|
/** Local EoE variable holding cached IP information values.
|
|
|
|
* To be set or read from the user application, eg. TCP/IP stack.
|
|
|
|
*/
|
|
|
|
static eoe_param_t nic_ports[EOE_NUMBER_OF_PORTS];
|
|
|
|
|
|
|
|
/** Local init/reset functions on frame receive init */
|
|
|
|
static void EOE_init_rx ();
|
|
|
|
/** Local init/reset functions on frame send completion */
|
|
|
|
static void EOE_init_tx ();
|
|
|
|
|
|
|
|
/** EoE utility function to convert uint32 to eoe ip bytes.
|
|
|
|
* @param[in] ip = ip in uint32
|
|
|
|
* @param[out] byte_ip = eoe ip 4th octet, 3ed octet, 2nd octet, 1st octet
|
|
|
|
*/
|
|
|
|
static void EOE_ip_uint32_to_byte (eoe_ip4_addr_t * ip, uint8_t * byte_ip)
|
|
|
|
{
|
|
|
|
byte_ip[3] = eoe_ip4_addr1(ip); /* 1st octet */
|
|
|
|
byte_ip[2] = eoe_ip4_addr2(ip); /* 2nd octet */
|
|
|
|
byte_ip[1] = eoe_ip4_addr3(ip); /* 3ed octet */
|
|
|
|
byte_ip[0] = eoe_ip4_addr4(ip); /* 4th octet */
|
|
|
|
}
|
|
|
|
|
|
|
|
/** EoE utility function to convert eoe ip bytes to uint32.
|
|
|
|
* @param[in] byte_ip = eoe ip 4th octet, 3ed octet, 2nd octet, 1st octet
|
|
|
|
* @param[out] ip = ip in uint32
|
|
|
|
*/
|
|
|
|
static void EOE_ip_byte_to_uint32 (uint8_t * byte_ip, eoe_ip4_addr_t * ip)
|
|
|
|
{
|
|
|
|
EOE_IP4_ADDR_TO_U32(ip,
|
|
|
|
byte_ip[3], /* 1st octet */
|
|
|
|
byte_ip[2], /* 2nd octet */
|
|
|
|
byte_ip[1], /* 3ed octet */
|
|
|
|
byte_ip[0]) ;/* 4th octet */
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get EoE cached MAC address
|
|
|
|
*
|
|
|
|
* @param[in] port = get MAC for port
|
|
|
|
* @param[out] mac = variable to store mac in, should fit EOE_ETHADDR_LENGTH
|
|
|
|
* @return 0= if we succeed, -1 if not set
|
|
|
|
*/
|
|
|
|
int EOE_get_mac(uint8_t port, uint8_t mac[])
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].mac_set)
|
|
|
|
{
|
|
|
|
memcpy(mac, nic_ports[port_ix].mac.addr,
|
|
|
|
sizeof(nic_ports[port_ix].mac));
|
|
|
|
nic_ports[port_ix].mac_set = 1;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set EoE cached MAC address
|
|
|
|
*
|
|
|
|
* @param[in] port = get MAC for port
|
|
|
|
* @param[in] mac = mac address to store
|
|
|
|
* @return 0= if we succeed, else -1.
|
|
|
|
*/
|
|
|
|
int EOE_ecat_set_mac(uint8_t port, uint8_t mac[])
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
memcpy(nic_ports[port_ix].mac.addr, mac,
|
|
|
|
sizeof(nic_ports[port_ix].mac));
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get EoE cached ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip address for port
|
|
|
|
* @param[out] ip = variable to store ip in
|
|
|
|
* @return 0= if we succeed, -1 if not set
|
|
|
|
*/
|
|
|
|
int EOE_ecat_get_ip(uint8_t port, uint32_t * ip)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].ip_set)
|
|
|
|
{
|
|
|
|
*ip = EOE_NTOHL(nic_ports[port_ix].ip.addr);
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set EoE cached ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip for port
|
|
|
|
* @param[in] ip = ip address to store
|
|
|
|
* @return 0= if we succeed, else -1.
|
|
|
|
*/
|
|
|
|
int EOE_ecat_set_ip(uint8_t port, uint32_t ip)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
nic_ports[port_ix].ip.addr = EOE_HTONL(ip);
|
|
|
|
nic_ports[port_ix].ip_set = 1;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get EoE cached subnet ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip address for port
|
|
|
|
* @param[out] subnet = variable to store ip in
|
|
|
|
* @return 0= if we succeed, -1 if not set
|
|
|
|
*/
|
|
|
|
int EOE_ecat_get_subnet(uint8_t port, uint32_t * subnet)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].subnet_set)
|
|
|
|
{
|
|
|
|
*subnet = EOE_NTOHL(nic_ports[port_ix].subnet.addr);
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set EoE cached subnet ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip for port
|
|
|
|
* @param[in] subnet = ip address to store
|
|
|
|
* @return 0= if we succeed, else -1.
|
|
|
|
*/
|
|
|
|
int EOE_ecat_set_subnet(uint8_t port, uint32_t subnet)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
nic_ports[port_ix].subnet.addr = EOE_HTONL(subnet);
|
|
|
|
nic_ports[port_ix].subnet_set = 1;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get EoE cached default gateway ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip address for port
|
|
|
|
* @param[out] default_gateway = variable to store ip in
|
|
|
|
* @return 0= if we succeed, -1 if not set
|
|
|
|
*/
|
|
|
|
int EOE_ecat_get_gateway(uint8_t port, uint32_t * default_gateway)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].default_gateway_set)
|
|
|
|
{
|
|
|
|
*default_gateway =
|
|
|
|
EOE_NTOHL(nic_ports[port_ix].default_gateway.addr);
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set EoE cached default gateway ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip for port
|
|
|
|
* @param[in] default_gateway = ip address to store
|
|
|
|
* @return 0= if we succeed, else -1.
|
|
|
|
*/
|
|
|
|
int EOE_ecat_set_gateway(uint8_t port, uint32_t default_gateway)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
nic_ports[port_ix].default_gateway.addr =
|
|
|
|
EOE_HTONL(default_gateway);
|
|
|
|
nic_ports[port_ix].default_gateway_set = 1;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get EoE cached dns ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip address for port
|
|
|
|
* @param[out] dns_ip = variable to store ip in
|
|
|
|
* @return 0= if we succeed, -1 if not set
|
|
|
|
*/
|
|
|
|
int EOE_ecat_get_dns_ip(uint8_t port, uint32_t * dns_ip)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].dns_ip_set)
|
|
|
|
{
|
|
|
|
*dns_ip = EOE_NTOHL(nic_ports[port_ix].dns_ip.addr);
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set EoE cached dns ip address
|
|
|
|
*
|
|
|
|
* @param[in] port = get ip for port
|
|
|
|
* @param[in] dns_ip = ip address to store
|
|
|
|
* @return 0= if we succeed, else -1.
|
|
|
|
*/
|
|
|
|
int EOE_ecat_set_dns_ip(uint8_t port, uint32_t dns_ip)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
nic_ports[port_ix].dns_ip.addr = EOE_HTONL(dns_ip);
|
|
|
|
nic_ports[port_ix].dns_ip_set = 1;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Get EoE cached dns name
|
|
|
|
*
|
|
|
|
* @param[in] port = get dns name for port
|
|
|
|
* @param[out] dns_name = variable to store dns name in
|
|
|
|
* @return 0= if we succeed, -1 if not set
|
|
|
|
*/
|
|
|
|
int EOE_ecat_get_dns_name(uint8_t port, char * dns_name)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].dns_name_set)
|
|
|
|
{
|
|
|
|
memcpy(dns_name,
|
|
|
|
nic_ports[port_ix].dns_name,
|
|
|
|
sizeof(nic_ports[port_ix].dns_name));
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Set EoE cached dns name
|
|
|
|
*
|
|
|
|
* @param[in] port = get dns name for port
|
|
|
|
* @param[in] dns_name = dns name to store
|
|
|
|
* @return 0= if we succeed, else -1.
|
|
|
|
*/
|
|
|
|
int EOE_ecat_set_dns_name(uint8_t port, char * dns_name)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
int port_ix;
|
|
|
|
|
|
|
|
if(port < EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
memcpy(nic_ports[port_ix].dns_name,
|
|
|
|
dns_name,
|
|
|
|
sizeof(nic_ports[port_ix].dns_name));
|
|
|
|
nic_ports[port_ix].dns_name_set = 1;
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Function for sending an simple EOE response frame.
|
|
|
|
*
|
|
|
|
* @param[in] frametype1 = frame type of response
|
|
|
|
* @param[in] result = result code
|
|
|
|
*/
|
|
|
|
static void EOE_no_data_response (uint16_t frameinfo1, uint16_t result)
|
|
|
|
{
|
|
|
|
_EOE *eoembx;
|
|
|
|
uint8_t mbxhandle;
|
|
|
|
|
|
|
|
/* Send back a response packet. */
|
|
|
|
mbxhandle = ESC_claimbuffer ();
|
|
|
|
if (mbxhandle)
|
|
|
|
{
|
|
|
|
eoembx = (_EOE *) &MBX[mbxhandle * ESC_MBXSIZE];
|
|
|
|
eoembx->mbxheader.length = htoes (ESC_EOEHSIZE);
|
|
|
|
eoembx->mbxheader.mbxtype = MBXEOE;
|
|
|
|
eoembx->eoeheader.frameinfo1 = htoes(frameinfo1);
|
|
|
|
eoembx->eoeheader.result = htoes(result);
|
|
|
|
MBXcontrol[mbxhandle].state = MBXstate_outreq;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** EoE get IP param request handler. Will send a get IP param response.
|
|
|
|
*/
|
|
|
|
static void EOE_get_ip (void)
|
|
|
|
{
|
|
|
|
_EOE *req_eoembx;
|
|
|
|
_EOE *eoembx;
|
|
|
|
uint8_t mbxhandle;
|
|
|
|
uint16_t frameinfo1;
|
|
|
|
uint8_t port;
|
|
|
|
uint8_t flags;
|
|
|
|
uint8_t data_offset;
|
|
|
|
int port_ix;
|
|
|
|
|
|
|
|
req_eoembx = (_EOE *) &MBX[0];
|
|
|
|
frameinfo1 = etohs(req_eoembx->eoeheader.frameinfo1);
|
|
|
|
port = EOE_HDR_FRAME_PORT_GET(frameinfo1);
|
|
|
|
data_offset = EOE_PARAM_OFFSET;
|
|
|
|
flags = 0;
|
|
|
|
|
|
|
|
if(port > EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
DPRINT("Invalid port\n");
|
|
|
|
/* Return error response on given port */
|
|
|
|
EOE_no_data_response((EOE_HDR_FRAME_PORT_SET(port) |
|
|
|
|
EOE_INIT_RESP |
|
|
|
|
EOE_HDR_LAST_FRAGMENT),
|
|
|
|
EOE_RESULT_UNSPECIFIED_ERROR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh settings if needed */
|
|
|
|
if(eoe_cfg->load_eth_settings != NULL)
|
|
|
|
{
|
|
|
|
(void)eoe_cfg->load_eth_settings();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send back an response packet. */
|
|
|
|
mbxhandle = ESC_claimbuffer ();
|
|
|
|
if (mbxhandle)
|
|
|
|
{
|
|
|
|
eoembx = (_EOE *) &MBX[mbxhandle * ESC_MBXSIZE];
|
|
|
|
eoembx->mbxheader.mbxtype = MBXEOE;
|
|
|
|
MBXcontrol[mbxhandle].state = MBXstate_outreq;
|
|
|
|
eoembx->eoeheader.frameinfo1 =
|
|
|
|
htoes(EOE_HDR_FRAME_TYPE_SET(EOE_GET_IP_PARAM_RESP) |
|
|
|
|
EOE_HDR_FRAME_PORT_SET(port) |
|
|
|
|
EOE_HDR_LAST_FRAGMENT);
|
|
|
|
eoembx->eoeheader.frameinfo2 = 0;
|
|
|
|
|
|
|
|
/* include mac in get ip request */
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(nic_ports[port_ix].mac_set)
|
|
|
|
{
|
|
|
|
flags |= EOE_PARAM_MAC_INCLUDE;
|
|
|
|
memcpy(&eoembx->data[data_offset] ,
|
|
|
|
nic_ports[port_ix].mac.addr,
|
|
|
|
EOE_ETHADDR_LENGTH);
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of mac address */
|
|
|
|
data_offset += EOE_ETHADDR_LENGTH;
|
|
|
|
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* include ip in get ip request */
|
|
|
|
if(nic_ports[port_ix].ip_set)
|
|
|
|
{
|
|
|
|
flags |= EOE_PARAM_IP_INCLUDE;
|
|
|
|
EOE_ip_uint32_to_byte(&nic_ports[port_ix].ip,
|
|
|
|
&eoembx->data[data_offset]);
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
2020-08-14 14:58:17 +02:00
|
|
|
|
2018-11-13 11:14:19 +01:00
|
|
|
/* include subnet in get ip request */
|
|
|
|
if(nic_ports[port_ix].subnet_set)
|
|
|
|
{
|
|
|
|
flags |= EOE_PARAM_SUBNET_IP_INCLUDE;
|
|
|
|
EOE_ip_uint32_to_byte(&nic_ports[port_ix].subnet,
|
|
|
|
&eoembx->data[data_offset]);
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
2020-08-14 14:58:17 +02:00
|
|
|
|
2018-11-13 11:14:19 +01:00
|
|
|
/* include default gateway in get ip request */
|
|
|
|
if(nic_ports[port_ix].default_gateway_set)
|
|
|
|
{
|
|
|
|
flags |= EOE_PARAM_DEFAULT_GATEWAY_INCLUDE;
|
|
|
|
EOE_ip_uint32_to_byte(&nic_ports[port_ix].default_gateway,
|
|
|
|
&eoembx->data[data_offset]);
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* include dns ip in get ip request */
|
|
|
|
if(nic_ports[port_ix].dns_ip_set)
|
|
|
|
{
|
|
|
|
flags |= EOE_PARAM_DNS_IP_INCLUDE;
|
|
|
|
EOE_ip_uint32_to_byte(&nic_ports[port_ix].dns_ip,
|
|
|
|
&eoembx->data[data_offset]);
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
2020-08-14 14:58:17 +02:00
|
|
|
|
2018-11-13 11:14:19 +01:00
|
|
|
/* include dns name in get ip request */
|
|
|
|
if(nic_ports[port_ix].dns_name_set)
|
|
|
|
{
|
2020-08-14 14:58:17 +02:00
|
|
|
/* TwinCAT include EOE_DNS_NAME_LENGTH chars even if name is shorter */
|
2018-11-13 11:14:19 +01:00
|
|
|
flags |= EOE_PARAM_DNS_NAME_INCLUDE;
|
|
|
|
memcpy(&eoembx->data[data_offset],
|
|
|
|
nic_ports[port_ix].dns_name,
|
|
|
|
EOE_DNS_NAME_LENGTH);
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of dns name length */
|
|
|
|
data_offset += EOE_DNS_NAME_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
eoembx->data[0] = flags;
|
|
|
|
eoembx->mbxheader.length = htoes (ESC_EOEHSIZE + data_offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** EoE set IP param request handler. Will send a set IP param response.
|
|
|
|
*/
|
|
|
|
static void EOE_set_ip (void)
|
|
|
|
{
|
|
|
|
_EOE *eoembx;
|
|
|
|
uint16_t eoedatasize;
|
|
|
|
uint16_t frameinfo1;
|
|
|
|
uint8_t port;
|
|
|
|
uint8_t flags;
|
|
|
|
uint8_t data_offset;
|
|
|
|
uint16_t result;
|
|
|
|
int port_ix;
|
|
|
|
|
|
|
|
eoembx = (_EOE *) &MBX[0];
|
|
|
|
eoedatasize = etohs(eoembx->mbxheader.length) - ESC_EOEHSIZE;
|
|
|
|
frameinfo1 = etohs(eoembx->eoeheader.frameinfo1);
|
|
|
|
port = EOE_HDR_FRAME_PORT_GET(frameinfo1);
|
|
|
|
flags = eoembx->data[0];
|
|
|
|
data_offset = EOE_PARAM_OFFSET;
|
|
|
|
|
|
|
|
if(port > EOE_NUMBER_OF_PORTS)
|
|
|
|
{
|
|
|
|
DPRINT("Invalid port\n");
|
|
|
|
/* Return error response on given port */
|
|
|
|
EOE_no_data_response((EOE_HDR_FRAME_PORT_SET(port) |
|
|
|
|
EOE_INIT_RESP |
|
|
|
|
EOE_HDR_LAST_FRAGMENT),
|
|
|
|
EOE_RESULT_UNSPECIFIED_ERROR);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* mac included in set ip request? */
|
|
|
|
port_ix = EOE_PORT_INDEX(port);
|
|
|
|
if(flags & EOE_PARAM_MAC_INCLUDE)
|
|
|
|
{
|
|
|
|
memcpy(&nic_ports[port_ix].mac.addr,
|
|
|
|
&eoembx->data[data_offset],
|
|
|
|
EOE_ETHADDR_LENGTH);
|
|
|
|
nic_ports[port_ix].mac_set = 1;
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of mac address */
|
|
|
|
data_offset += EOE_ETHADDR_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* ip included in set ip request? */
|
|
|
|
if(flags & EOE_PARAM_IP_INCLUDE)
|
|
|
|
{
|
|
|
|
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
|
|
|
|
&nic_ports[port_ix].ip);
|
|
|
|
nic_ports[port_ix].ip_set = 1;
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* subnet included in set ip request? */
|
|
|
|
if(flags & EOE_PARAM_SUBNET_IP_INCLUDE)
|
|
|
|
{
|
|
|
|
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
|
|
|
|
&nic_ports[port_ix].subnet);
|
|
|
|
nic_ports[port_ix].subnet_set = 1;
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* default gateway included in set ip request? */
|
|
|
|
if(flags & EOE_PARAM_DEFAULT_GATEWAY_INCLUDE)
|
|
|
|
{
|
|
|
|
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
|
|
|
|
&nic_ports[port_ix].default_gateway);
|
|
|
|
nic_ports[port_ix].default_gateway_set = 1;
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* dns ip included in set ip request? */
|
|
|
|
if(flags & EOE_PARAM_DNS_IP_INCLUDE)
|
|
|
|
{
|
|
|
|
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
|
|
|
|
&nic_ports[port_ix].dns_ip);
|
|
|
|
nic_ports[port_ix].dns_ip_set = 1;
|
2020-08-14 14:58:17 +02:00
|
|
|
/* Add size of uint32 IP address */
|
|
|
|
data_offset += EOE_IP4_LENGTH;
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
/* dns name included in set ip request? */
|
|
|
|
if(flags & EOE_PARAM_DNS_NAME_INCLUDE)
|
|
|
|
{
|
|
|
|
uint16_t dns_len = MIN((eoedatasize - data_offset), EOE_DNS_NAME_LENGTH);
|
|
|
|
memcpy(nic_ports[port_ix].dns_name,
|
|
|
|
&eoembx->data[data_offset],
|
|
|
|
dns_len);
|
|
|
|
nic_ports[port_ix].dns_name_set = 1;
|
2020-08-14 14:58:17 +02:00
|
|
|
data_offset += dns_len; /* expected 1- EOE_DNS_NAME_LENGTH; */
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(data_offset > eoedatasize)
|
|
|
|
{
|
|
|
|
result = MBXERR_SIZETOOSHORT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Application specific store settings function. From there
|
|
|
|
* you typically set the IP for the TCP/IP stack */
|
|
|
|
if(eoe_cfg->store_ethernet_settings != NULL)
|
|
|
|
{
|
|
|
|
result = eoe_cfg->store_ethernet_settings();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = EOE_RESULT_NO_IP_SUPPORT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
EOE_no_data_response((EOE_HDR_FRAME_PORT_SET(port) |
|
|
|
|
EOE_INIT_RESP |
|
|
|
|
EOE_HDR_LAST_FRAGMENT),
|
|
|
|
result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** EoE receive fragment handler.
|
|
|
|
*/
|
|
|
|
static void EOE_receive_fragment (void)
|
|
|
|
{
|
|
|
|
_EOE *eoembx;
|
|
|
|
eoembx = (_EOE *) &MBX[0];
|
|
|
|
uint16_t eoedatasize = etohs(eoembx->mbxheader.length) - ESC_EOEHSIZE;
|
|
|
|
uint16_t frameinfo1 = etohs(eoembx->eoeheader.frameinfo1);
|
|
|
|
uint16_t frameinfo2 = etohs(eoembx->eoeheader.frameinfo2);
|
|
|
|
|
|
|
|
/* Capture error case */
|
|
|
|
if(EOEvar.rxfragmentno != EOE_HDR_FRAG_NO_GET(frameinfo2))
|
|
|
|
{
|
|
|
|
DPRINT("Unexpected fragment number %d, expected: %d\n",
|
|
|
|
EOE_HDR_FRAG_NO_GET(frameinfo2), EOEvar.rxfragmentno);
|
|
|
|
/* Clean up existing saved data */
|
|
|
|
if(EOEvar.rxfragmentno != 0)
|
|
|
|
{
|
|
|
|
EOE_init_rx();
|
|
|
|
}
|
|
|
|
/* Skip fragment if not start of new frame */
|
|
|
|
if(EOE_HDR_FRAG_NO_GET(frameinfo2) > 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Start of new frame at fragment 0 */
|
|
|
|
if(EOEvar.rxfragmentno == 0)
|
|
|
|
{
|
|
|
|
EOEvar.rxframesize = (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5);
|
|
|
|
|
|
|
|
if(EOEvar.rxebuf.payload != NULL)
|
|
|
|
{
|
|
|
|
EOEvar.rxebuf.len = EOEvar.rxframesize;
|
|
|
|
EOEvar.rxframeoffset = 0;
|
|
|
|
EOEvar.rxframeno = EOE_HDR_FRAME_NO_GET(frameinfo2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* In frame fragment received */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint16_t offset = (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5);
|
|
|
|
/* Validate received fragment */
|
|
|
|
if(EOEvar.rxframeno != EOE_HDR_FRAME_NO_GET(frameinfo2))
|
|
|
|
{
|
|
|
|
DPRINT("Unexpected frame number %d, expected: %d\n",
|
|
|
|
EOE_HDR_FRAME_NO_GET(frameinfo2), EOEvar.rxframeno);
|
|
|
|
EOE_init_rx ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(EOEvar.rxframeoffset != offset)
|
|
|
|
{
|
|
|
|
DPRINT("Unexpected frame offset %d, expected: %d\n",
|
|
|
|
offset, EOEvar.rxframeoffset);
|
|
|
|
EOE_init_rx ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check so allocated buffer is sufficient */
|
|
|
|
if ((EOEvar.rxframeoffset + eoedatasize) <= EOEvar.rxframesize)
|
|
|
|
{
|
|
|
|
memcpy((uint8_t *)(EOEvar.rxebuf.payload + EOEvar.rxframeoffset),
|
|
|
|
eoembx->data,
|
|
|
|
eoedatasize);
|
|
|
|
EOEvar.rxframeoffset += eoedatasize;
|
|
|
|
EOEvar.rxfragmentno++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-07-10 11:59:00 +02:00
|
|
|
DPRINT("Size of data exceed available buffer size\n");
|
2018-11-13 11:14:19 +01:00
|
|
|
EOE_init_rx ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(EOE_HDR_LAST_FRAGMENT_GET(frameinfo1))
|
|
|
|
{
|
|
|
|
/* Remove time stamp, TODO support for time stamp? */
|
|
|
|
if(EOE_HDR_TIME_APPEND_GET(frameinfo1))
|
|
|
|
{
|
|
|
|
EOEvar.rxframeoffset -= 4;
|
|
|
|
}
|
|
|
|
EOEvar.rxebuf.len = EOEvar.rxframeoffset;
|
|
|
|
eoe_cfg->handle_recv_buffer(EOE_HDR_FRAME_PORT_GET(frameinfo1),
|
|
|
|
&EOEvar.rxebuf);
|
|
|
|
/* Pass ownership of buf to receive function */
|
|
|
|
EOEvar.rxebuf.payload = NULL;
|
|
|
|
EOE_init_rx ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** EoE send fragment handler.
|
|
|
|
*/
|
|
|
|
static void EOE_send_fragment ()
|
|
|
|
{
|
|
|
|
_EOE *eoembx;
|
|
|
|
uint8_t mbxhandle;
|
|
|
|
int len;
|
|
|
|
int len_to_send;
|
|
|
|
uint16_t frameinfo1;
|
|
|
|
uint16_t frameinfo2;
|
|
|
|
static uint8_t frameno = 0;
|
|
|
|
|
|
|
|
/* Do we have a current transfer on-going */
|
|
|
|
if(EOEvar.txebuf.payload == NULL)
|
|
|
|
{
|
|
|
|
/* Fetch a buffer if available */
|
|
|
|
len = eoe_cfg->fetch_send_buffer(0, &EOEvar.txebuf);
|
|
|
|
if(len > 0)
|
|
|
|
{
|
|
|
|
EOEvar.txframesize = len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Process the frame if we can get a free mailbox */
|
|
|
|
mbxhandle = ESC_claimbuffer ();
|
|
|
|
if (mbxhandle)
|
|
|
|
{
|
|
|
|
len_to_send = EOEvar.txframesize - EOEvar.txframeoffset;
|
|
|
|
if((len_to_send + ESC_EOEHSIZE + ESC_MBXHSIZE) > ESC_MBXSIZE)
|
|
|
|
{
|
|
|
|
/* Adjust to len in whole 32 octet blocks to fit specification*/
|
|
|
|
len_to_send =
|
|
|
|
(((ESC_MBXSIZE - ESC_EOEHSIZE - ESC_MBXHSIZE) >> 5) << 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: port handling? */
|
|
|
|
if(len_to_send == (EOEvar.txframesize - EOEvar.txframeoffset))
|
|
|
|
{
|
|
|
|
frameinfo1 = EOE_HDR_LAST_FRAGMENT_SET(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frameinfo1 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set fragment number */
|
|
|
|
frameinfo2 = EOE_HDR_FRAG_NO_SET(EOEvar.txfragmentno);
|
|
|
|
|
|
|
|
/* Set complete size for fragment 0 or offset for in frame fragments */
|
|
|
|
if(EOEvar.txfragmentno > 0)
|
|
|
|
{
|
|
|
|
frameinfo2 |= (EOE_HDR_FRAME_OFFSET_SET((EOEvar.txframeoffset >> 5)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frameinfo2 |=
|
|
|
|
(EOE_HDR_FRAME_OFFSET_SET(((EOEvar.txframesize + 31) >> 5)));
|
|
|
|
frameno++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set frame number */
|
|
|
|
frameinfo2 = frameinfo2 | EOE_HDR_FRAME_NO_SET(frameno);
|
|
|
|
|
|
|
|
eoembx = (_EOE *) &MBX[mbxhandle * ESC_MBXSIZE];
|
|
|
|
eoembx->mbxheader.length = htoes (len_to_send + ESC_EOEHSIZE);
|
|
|
|
eoembx->mbxheader.mbxtype = MBXEOE;
|
|
|
|
eoembx->eoeheader.frameinfo1 = htoes(frameinfo1);
|
|
|
|
eoembx->eoeheader.frameinfo2 = htoes(frameinfo2);
|
|
|
|
|
|
|
|
/* Copy data to mailbox */
|
|
|
|
memcpy(eoembx->data,
|
|
|
|
&EOEvar.txebuf.payload[EOEvar.txframeoffset],
|
|
|
|
len_to_send);
|
|
|
|
MBXcontrol[mbxhandle].state = MBXstate_outreq;
|
|
|
|
|
|
|
|
/* Did we complete the frame? */
|
|
|
|
if(len_to_send == (EOEvar.txframesize - EOEvar.txframeoffset))
|
|
|
|
{
|
|
|
|
EOE_init_tx ();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
EOEvar.txframeoffset += len_to_send;
|
|
|
|
EOEvar.txfragmentno += 1;
|
|
|
|
}
|
2019-04-03 17:58:46 +02:00
|
|
|
if(eoe_cfg->fragment_sent_event != NULL)
|
|
|
|
{
|
|
|
|
eoe_cfg->fragment_sent_event();
|
|
|
|
}
|
2018-11-13 11:14:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize by clearing all current status variables and fetch new buffer.
|
|
|
|
*/
|
|
|
|
static void EOE_init_rx ()
|
|
|
|
{
|
|
|
|
/* Reset RX transfer status variables */
|
|
|
|
EOEvar.rxfragmentno = 0;
|
|
|
|
EOEvar.rxframesize = 0;
|
|
|
|
EOEvar.rxframeoffset = 0;
|
|
|
|
EOEvar.rxframeno = 0;
|
|
|
|
|
|
|
|
/* Fetch buffer */
|
|
|
|
if(EOEvar.rxebuf.payload == NULL)
|
|
|
|
{
|
|
|
|
if(eoe_cfg->get_buffer != NULL)
|
|
|
|
{
|
|
|
|
/* TODO: verify size VS buffer size */
|
|
|
|
eoe_cfg->get_buffer(&EOEvar.rxebuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize by clearing all current status variables and release old buffer.
|
|
|
|
*/
|
|
|
|
static void EOE_init_tx ()
|
|
|
|
{
|
|
|
|
/* Reset TX transfer status variables */
|
|
|
|
EOEvar.txfragmentno = 0;
|
|
|
|
EOEvar.txframesize = 0;
|
|
|
|
EOEvar.txframeoffset = 0;
|
|
|
|
|
|
|
|
/* Release what seems as an abandoned buffer */
|
|
|
|
if((EOEvar.txebuf.payload != NULL))
|
|
|
|
{
|
|
|
|
if(eoe_cfg->free_buffer != NULL)
|
|
|
|
{
|
|
|
|
eoe_cfg->free_buffer(&EOEvar.txebuf);
|
|
|
|
EOEvar.txebuf.pbuf = NULL;
|
|
|
|
EOEvar.txebuf.payload = NULL;
|
|
|
|
EOEvar.txebuf.len = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize by clearing all current status variables.
|
|
|
|
*/
|
|
|
|
void EOE_init ()
|
|
|
|
{
|
|
|
|
DPRINT("EOE_init\n");
|
|
|
|
EOE_init_tx ();
|
|
|
|
EOE_init_rx ();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Function copying the application configuration variable
|
|
|
|
* to the EoE module local pointer variable.
|
|
|
|
*
|
|
|
|
* @param[in] cfg = Pointer to by the Application static declared
|
|
|
|
* configuration variable holding application specific details.
|
|
|
|
*/
|
|
|
|
void EOE_config (eoe_cfg_t * cfg)
|
|
|
|
{
|
|
|
|
eoe_cfg = cfg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Main EoE receive function checking the status on current mailbox buffers
|
|
|
|
* carrying data, distributing the mailboxes to appropriate EOE functions
|
|
|
|
* depending on requested frametype.
|
|
|
|
*/
|
|
|
|
void ESC_eoeprocess (void)
|
|
|
|
{
|
|
|
|
_MBXh *mbh;
|
|
|
|
_EOE *eoembx;
|
|
|
|
uint16_t frameinfo1;
|
|
|
|
|
|
|
|
if (ESCvar.MBXrun == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!ESCvar.xoe && (MBXcontrol[0].state == MBXstate_inclaim))
|
|
|
|
{
|
|
|
|
mbh = (_MBXh *) &MBX[0];
|
|
|
|
if (mbh->mbxtype == MBXEOE)
|
|
|
|
{
|
|
|
|
ESCvar.xoe = MBXEOE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ESCvar.xoe == MBXEOE)
|
|
|
|
{
|
|
|
|
eoembx = (_EOE *) &MBX[0];
|
|
|
|
/* Verify the size of the file data. */
|
|
|
|
if (etohs (eoembx->mbxheader.length) < ESC_EOEHSIZE)
|
|
|
|
{
|
|
|
|
EOE_no_data_response (
|
|
|
|
EOE_INIT_RESP | EOE_HDR_LAST_FRAGMENT,
|
|
|
|
MBXERR_SIZETOOSHORT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
frameinfo1 = etohs(eoembx->eoeheader.frameinfo1);
|
|
|
|
switch (EOE_HDR_FRAME_TYPE_GET(frameinfo1))
|
|
|
|
{
|
|
|
|
case EOE_FRAG_DATA:
|
|
|
|
{
|
|
|
|
EOE_receive_fragment ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case EOE_INIT_REQ:
|
|
|
|
{
|
|
|
|
EOE_set_ip ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case EOE_GET_IP_PARAM_REQ:
|
|
|
|
{
|
|
|
|
EOE_get_ip ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case EOE_INIT_RESP_TIMESTAMP:
|
|
|
|
case EOE_INIT_RESP:
|
|
|
|
case EOE_SET_ADDR_FILTER_REQ:
|
|
|
|
case EOE_SET_ADDR_FILTER_RESP:
|
|
|
|
case EOE_GET_IP_PARAM_RESP:
|
|
|
|
case EOE_GET_ADDR_FILTER_REQ:
|
|
|
|
case EOE_GET_ADDR_FILTER_RESP:
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
DPRINT("EOE_RESULT_UNSUPPORTED_TYPE\n");
|
|
|
|
EOE_no_data_response ((EOE_HDR_FRAME_PORT & frameinfo1) |
|
|
|
|
(EOE_HDR_FRAME_TYPE & frameinfo1) |
|
|
|
|
EOE_HDR_LAST_FRAGMENT,
|
|
|
|
EOE_RESULT_UNSUPPORTED_FRAME_TYPE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
MBXcontrol[0].state = MBXstate_idle;
|
|
|
|
ESCvar.xoe = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/** EoE function to send a fragment.
|
|
|
|
* NOTE: Not thread safe, should be called from the SOES task sequential
|
|
|
|
* with other mailbox functions. Add support for threading by adding
|
|
|
|
* a thread safe application fetch function, example a mailbox with buffers
|
|
|
|
* to send, posted by TCP/IP stack and fetched by SOES task.
|
|
|
|
*/
|
|
|
|
void ESC_eoeprocess_tx (void)
|
|
|
|
{
|
|
|
|
if (ESCvar.MBXrun == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
EOE_send_fragment ();
|
|
|
|
}
|