479 lines
13 KiB
C
479 lines
13 KiB
C
/**
|
|
* \addtogroup EtherCAT middleware layer (DRAFT)
|
|
* \{
|
|
*/
|
|
|
|
#ifndef ECAT_H
|
|
#define ECAT_H
|
|
|
|
#include "ethercattype.h"
|
|
#include "nicdrv.h"
|
|
#include "ethercatbase.h"
|
|
#include "ethercatmain.h"
|
|
#include "ethercatconfig.h"
|
|
#include "ethercatcoe.h"
|
|
#include "ethercatdc.h"
|
|
#include "ethercatprint.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
typedef struct {
|
|
ecx_contextt ctx;
|
|
char * ifname;
|
|
uint8_t * io_map;
|
|
unsigned int expected_wc;
|
|
} ecat_net_t;
|
|
|
|
|
|
typedef struct {
|
|
uint32_t a;
|
|
/* TBD */
|
|
} ecat_slave_t;
|
|
|
|
typedef struct {
|
|
uint32_t a;
|
|
/* TBD */
|
|
} ecat_statistics_t;
|
|
|
|
typedef enum {
|
|
ECAT_STATE_INIT = 0x01,
|
|
ECAT_STATE_PRE_OP = 0x02,
|
|
ECAT_STATE_BOOT = 0x03,
|
|
ECAT_STATE_SAFE_OP = 0x04,
|
|
ECAT_STATE_OP = 0x08,
|
|
|
|
ECAT_STATE_ACK = 0x10,
|
|
ECAT_STATE_ERROR = 0x10,
|
|
} ecat_state_t;
|
|
|
|
typedef enum {
|
|
ECAT_SLAVE_NO_LINK,
|
|
ECAT_SLAVE_LINK_DETECTED
|
|
} ecat_slave_link_detected_t;
|
|
|
|
typedef enum {
|
|
ECAT_SLAVE_PORT_OPEN,
|
|
ECAT_SLAVE_PORT_CLOSED
|
|
} ecat_slave_loop_port_t;
|
|
|
|
typedef enum {
|
|
ECAT_SLAVE_NO_STABLE_COM,
|
|
ECAT_SLAVE_COM_ESTABLISHED
|
|
} ecat_slave_stable_com_t;
|
|
|
|
typedef struct {
|
|
ecat_slave_link_detected_t link_detected;
|
|
ecat_slave_loop_port_t loop_port;
|
|
ecat_slave_stable_com_t stable_com;
|
|
uint8_t lost_link_counter;
|
|
uint8_t invalid_frame_counter;
|
|
uint8_t rx_error_counter;
|
|
uint8_t forwarded_rx_error_counter;
|
|
} ecat_slave_port_status_t;
|
|
|
|
typedef struct {
|
|
uint8_t watchdog_counter_process_data;
|
|
uint8_t watchdog_counter_pdi;
|
|
} ecat_slave_wd_cnt_t;
|
|
|
|
typedef struct {
|
|
ecat_slave_port_status_t port[4];
|
|
ecat_slave_wd_cnt_t wd_cnt;
|
|
uint8_t ecat_processing_unit_error_counter;
|
|
uint8_t pdi_error_counter;
|
|
uint8_t pdi_error_code;
|
|
} ecat_slave_status_t;
|
|
|
|
typedef struct {
|
|
uint64_t time;
|
|
uint64_t offset;
|
|
uint32_t delay;
|
|
int32_t difference;
|
|
} ecat_slave_dc_status_t;
|
|
|
|
/***********************************************************************
|
|
Example:
|
|
|
|
ecat_net_t * net;
|
|
...
|
|
|
|
// This part is done during "boot"
|
|
net = ecat_net_init ("ie1g1", settings);
|
|
num_slaves = ecat_net_scan (net);
|
|
|
|
if (ecat_net_verify (net, ...) < 0)
|
|
{
|
|
// handle net mismatch
|
|
}
|
|
|
|
if (ecat_net_get_state (net) != ECAT_STATE_SAFE_OP)
|
|
{
|
|
// handle that not all slaves are in SAFE-OP
|
|
}
|
|
|
|
expected_wc = ecat_net_get_expected_wc (net);
|
|
ecat_net_print_slave_states (net);
|
|
|
|
|
|
|
|
// This is done when starting the EtherCAT communication
|
|
if (ecat_net_set_state (net, ECAT_STATE_OP) < 0)
|
|
{
|
|
// handle that not all slaves are in OPERATIONAL
|
|
}
|
|
|
|
|
|
|
|
// When the EtherCAT network is up and running
|
|
// In the start of the cycle process incomming message
|
|
wc = ecat_net_receive (net, 0);
|
|
if (wc != expected_wc)
|
|
{
|
|
// handle invalid working counter
|
|
}
|
|
|
|
// In the end of the cycle, send out the message
|
|
ecat_net_send (net);
|
|
|
|
|
|
|
|
// This is done when shutting down the system.
|
|
ecat_net_set_state (net, ECAT_STATE_SAFE_OP);
|
|
// go to other states if needed
|
|
...
|
|
ecat_net_deinit (net);
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
*** EtherCAT network ***
|
|
***********************************************************************/
|
|
|
|
/**
|
|
* Initiate a master instance, allocates memory.
|
|
*
|
|
* \return The network handle to be used in all subsequent operations
|
|
* on the EtherCAT network and slaves
|
|
*/
|
|
ecat_net_t * ecat_net_init(char * ifname); //, ecat_net_settings_t * settings);
|
|
|
|
/**
|
|
* Sets up network interface, scan the EtherCAT network, set up the IOMAP,
|
|
* configure slaves and bring the slaves up to SAFE OPERATIONAL.
|
|
*
|
|
* \param net Network handle
|
|
* \return number of slaves found on success, negative number on failure
|
|
*/
|
|
int ecat_net_scan(ecat_net_t * net);
|
|
|
|
/**
|
|
* Verifies the scanned network against an expected newtork.
|
|
*
|
|
* \param net Network handle
|
|
* \param TBD Expected network
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_net_verify(ecat_net_t * net); //, /* TBD */);
|
|
|
|
/**
|
|
* Tries to change the state on all slaves on the network, for example
|
|
* SAFE OPERATIONAL to OPERATIONAL.
|
|
*
|
|
* \param net Network handle
|
|
* \param state State to change to
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_net_set_state(ecat_net_t * net, ecat_state_t state);
|
|
|
|
/**
|
|
* Get the lowest common state for all slaves on the network. If all
|
|
* slaves are in ECAT_STATE_OP and one in ECAT_STATE_SAFE_OP this
|
|
* function will return ECAT_STATE_SAFE_OP.
|
|
*
|
|
* \param net Network handle
|
|
* \param state State to change to
|
|
* \return current network state
|
|
*/
|
|
ecat_state_t ecat_net_get_state(ecat_net_t * net);
|
|
|
|
/**
|
|
* Sends process data from the IOMAP on the network.
|
|
*
|
|
* \param net Network handle
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_net_send(ecat_net_t * net);
|
|
|
|
/**
|
|
* Process incomming process data and store it in the IOMAP.
|
|
*
|
|
* \param net Network handle
|
|
* \param timeout_us Timeout (us)
|
|
* \return wc on success, negative number on failure
|
|
*/
|
|
int ecat_net_receive(ecat_net_t * net, unsigned int timeout_us);
|
|
|
|
/**
|
|
* Closes the network and cleans up the allocated memory.
|
|
*
|
|
* \param net Network handle
|
|
*/
|
|
void ecat_net_deinit(ecat_net_t * net);
|
|
|
|
/**
|
|
* Gets the expected working counter of the network.
|
|
*
|
|
* \param net Network handle
|
|
* \return the expected network handle of the network
|
|
*/
|
|
int ecat_net_get_expected_wc(ecat_net_t * net);
|
|
|
|
/**
|
|
* Query the slaves for slave status and error codes and prints the
|
|
* result to the console.
|
|
*
|
|
* \param net Network handle
|
|
*/
|
|
void ecat_net_print_slave_states (ecat_net_t * net);
|
|
|
|
/**
|
|
* Returns statistics from this master such as number of sent and
|
|
* received frames.
|
|
*
|
|
* \param net Network handle
|
|
* \param stats Statistics stuct
|
|
*/
|
|
void ecat_net_statistics(ecat_net_t * net, ecat_statistics_t * stats);
|
|
|
|
|
|
/***********************************************************************
|
|
*** EtherCAT slave ***
|
|
***********************************************************************/
|
|
|
|
/**
|
|
* Set state on a specific slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param state State to go to
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_set_state(ecat_net_t * net, uint32_t slave,
|
|
ecat_state_t state);
|
|
|
|
/**
|
|
* Get state on a specific slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
ecat_state_t ecat_slave_get_state(ecat_net_t * net);
|
|
|
|
/**
|
|
* Read SDO data from a slave. The `data` area to be large enough to
|
|
* hold the SDO data.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param index CoE index
|
|
* \param subindex CoE subindex
|
|
* \param data Pointer to where the data should be stored
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_sdo_read(ecat_net_t * net, uint32_t slave, uint16_t index,
|
|
uint16_t subindex, void * data);
|
|
/**
|
|
* Write SDO data to a slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param index CoE index
|
|
* \param subindex CoE subindex
|
|
* \param data Pointer to the SDO data
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_sdo_write(ecat_net_t * net, uint32_t slave, uint16_t index,
|
|
uint16_t subindex, const void * data);
|
|
|
|
/**
|
|
* Read PDO data from the IOMAP. The `data` area to be large enough to
|
|
* hold the PDO data.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param index CoE index
|
|
* \param subindex CoE subindex
|
|
* \param data Pointer to where the data should be stored
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_pdo_read(ecat_net_t * net, uint32_t slave, uint16_t index,
|
|
uint16_t subindex, void * data);
|
|
|
|
/**
|
|
* Write PDO data to the IOMAP.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param index CoE index
|
|
* \param subindex CoE subindex
|
|
* \param data Pointer to the SDO data
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_pdo_write(ecat_net_t * net, uint32_t slave, uint16_t index,
|
|
uint16_t subindex, const void * data);
|
|
|
|
/**
|
|
* Read EEPROM data from the slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param address EEPROM start address
|
|
* \param size EEPROM data size
|
|
* \param data Pointer to where the data should be stored
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_eeprom_read(ecat_net_t * net, uint32_t slave, uint32_t address,
|
|
size_t size, void * data);
|
|
|
|
/**
|
|
* Write EEPROM data to the slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param address EEPROM start address
|
|
* \param size EEPROM data size
|
|
* \param data Pointer to EEPROM data
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_eeprom_write(ecat_net_t * net, uint32_t slave, uint32_t address,
|
|
size_t size, const void * data);
|
|
|
|
/**
|
|
* Read register data from the slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param address Register start address
|
|
* \param length Register data length
|
|
* \param data Pointer to where the data should be stored
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_reg_read(ecat_net_t * net, uint32_t slave, uint32_t address,
|
|
uint32_t length, void * data);
|
|
|
|
/**
|
|
* Write register data to the slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param address Register start address
|
|
* \param size Register data size
|
|
* \param data Pointer to register data
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_reg_write(ecat_net_t * net, uint32_t slave, uint32_t address,
|
|
size_t size, void * data);
|
|
|
|
/**
|
|
* Read file data from the slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param filename File to read
|
|
* \param size Maximum file size
|
|
* \param data Pointer to where the data should be stored
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_file_read(ecat_net_t * net, uint32_t slave, char * filename,
|
|
size_t size, void * data);
|
|
|
|
/**
|
|
* Write file data to the slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param filename File to write
|
|
* \param size File size
|
|
* \param data Pointer to file data
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_file_write(ecat_net_t * net, uint32_t slave, char * filename,
|
|
size_t size, const void * data);
|
|
|
|
/**
|
|
* Gets the AL status from a slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \return AL status
|
|
*/
|
|
uint16_t ecat_slave_get_al_status(ecat_net_t * net, uint32_t slave);
|
|
|
|
/**
|
|
* Gets the distributed clock status from a slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param status Pointer to slave dc status structure
|
|
* \return 0 on success, negative number on failure
|
|
*/
|
|
int ecat_slave_get_dc_status(ecat_net_t * net, uint32_t slave,
|
|
ecat_slave_dc_status_t * status);
|
|
|
|
/**
|
|
* Gets the status from a slave.
|
|
*
|
|
* \param net Network handle
|
|
* \param slave Slave index
|
|
* \param status Pointer to slave status structure
|
|
* \return 0 on success, negative number on failure
|
|
* -1 DL status read failed
|
|
* -2 Error counters read failed
|
|
* -3 DL status and Error counters read failed
|
|
* -4 Watchdog read failed
|
|
* -5 DL status and Watchdog read failed
|
|
* -6 Error counters and Watchdog read failed
|
|
* -7 DL status and Error counters and Watchdog read failed
|
|
*/
|
|
int ecat_slave_get_status(ecat_net_t * net, uint32_t slave,
|
|
ecat_slave_status_t * status);
|
|
|
|
|
|
/***********************************************************************
|
|
*** EtherCAT utils ***
|
|
***********************************************************************/
|
|
|
|
/**
|
|
* Returns the corresponding string for a EtherCAT state.
|
|
*
|
|
* \param state The state
|
|
* \returns a string
|
|
*/
|
|
char * ecat_util_state_to_str(ecat_state_t state);
|
|
|
|
/**
|
|
* Returns the corresponding string for an AL status code.
|
|
*
|
|
* \param alstatus AL status
|
|
* \returns a string
|
|
*/
|
|
char * ecat_util_al_status_to_str(ecat_net_t * net, uint16_t alstatus);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* ECAT_H */
|
|
|
|
/**
|
|
* \}
|
|
*/
|