SOEM/soem/ecat.h

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 */
/**
* \}
*/