# HG changeset patch # User Florian Pose # Date 1220278638 0 # Node ID 8be462afb7f4d5aefb95444e37256109e76a3e7f # Parent 026e35646ab40bba81bdbf9a7c200c01483105a1 Added VoE handler. diff -r 026e35646ab4 -r 8be462afb7f4 examples/mini/mini.c --- a/examples/mini/mini.c Wed Aug 27 16:04:18 2008 +0000 +++ b/examples/mini/mini.c Mon Sep 01 14:17:18 2008 +0000 @@ -48,6 +48,7 @@ #define EL3152_ALT_PDOS 0 #define EXTERNAL_MEMORY 1 #define SDO_ACCESS 0 +#define VOE_ACCESS 0 #define PFX "ec_mini: " @@ -184,6 +185,10 @@ static ec_sdo_request_t *sdo; #endif +#if VOE_ACCESS +static ec_voe_handler_t *voe; +#endif + /*****************************************************************************/ void check_domain1_state(void) @@ -249,18 +254,18 @@ void read_sdo(void) { switch (ecrt_sdo_request_state(sdo)) { - case EC_SDO_REQUEST_UNUSED: // request was not used yet + case EC_REQUEST_UNUSED: // request was not used yet ecrt_sdo_request_read(sdo); // trigger first read break; - case EC_SDO_REQUEST_BUSY: + case EC_REQUEST_BUSY: printk(KERN_INFO PFX "Still busy...\n"); break; - case EC_SDO_REQUEST_SUCCESS: + case EC_REQUEST_SUCCESS: printk(KERN_INFO PFX "Sdo value: 0x%04X\n", EC_READ_U16(ecrt_sdo_request_data(sdo))); ecrt_sdo_request_read(sdo); // trigger next read break; - case EC_SDO_REQUEST_ERROR: + case EC_REQUEST_ERROR: printk(KERN_INFO PFX "Failed to read Sdo!\n"); ecrt_sdo_request_read(sdo); // retry reading break; @@ -270,6 +275,31 @@ /*****************************************************************************/ +#if VOE_ACCESS +void read_voe(void) +{ + switch (ecrt_voe_handler_execute(voe)) { + case EC_REQUEST_UNUSED: + ecrt_voe_handler_read(voe); // trigger first read + break; + case EC_REQUEST_BUSY: + printk(KERN_INFO PFX "VoE read still busy...\n"); + break; + case EC_REQUEST_SUCCESS: + printk(KERN_INFO PFX "VoE received.\n"); + // get data via ecrt_voe_handler_data(voe) + ecrt_voe_handler_read(voe); // trigger next read + break; + case EC_REQUEST_ERROR: + printk(KERN_INFO PFX "Failed to read VoE data!\n"); + ecrt_voe_handler_read(voe); // retry reading + break; + } +} +#endif + +/*****************************************************************************/ + void cyclic_task(unsigned long data) { // receive process data @@ -299,6 +329,10 @@ // read process data Sdo read_sdo(); #endif + +#if VOE_ACCESS + read_voe(); +#endif } // write process data @@ -401,6 +435,14 @@ ecrt_sdo_request_timeout(sdo, 500); // ms #endif +#if VOE_ACCESS + printk(KERN_INFO PFX "Creating VoE handlers...\n"); + if (!(voe = ecrt_slave_config_create_voe_handler(sc_ana_in, 1000))) { + printk(KERN_ERR PFX "Failed to create VoE handler.\n"); + goto out_release_master; + } +#endif + printk(KERN_INFO PFX "Registering Pdo entries...\n"); if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) { printk(KERN_ERR PFX "Pdo entry registration failed!\n"); diff -r 026e35646ab4 -r 8be462afb7f4 include/ecrt.h --- a/include/ecrt.h Wed Aug 27 16:04:18 2008 +0000 +++ b/include/ecrt.h Mon Sep 01 14:17:18 2008 +0000 @@ -113,7 +113,7 @@ /** EtherCAT realtime interface minor version number. */ -#define ECRT_VER_MINOR 4 +#define ECRT_VER_MINOR 5 /** EtherCAT realtime interface version word generator. */ @@ -151,6 +151,9 @@ struct ec_sdo_request; typedef struct ec_sdo_request ec_sdo_request_t; /**< \see ec_sdo_request. */ +struct ec_voe_handler; +typedef struct ec_voe_handler ec_voe_handler_t; /**< \see ec_voe_handler. */ + /*****************************************************************************/ /** Master state. @@ -305,16 +308,17 @@ /*****************************************************************************/ -/** Sdo request state. - * - * This is used as return type of ecrt_sdo_request_state(). +/** Request state. + * + * This is used as return type for ecrt_sdo_request_state() and + * ecrt_voe_handler_state(). */ typedef enum { - EC_SDO_REQUEST_UNUSED, /**< Not requested. */ - EC_SDO_REQUEST_BUSY, /**< Request is being processed. */ - EC_SDO_REQUEST_SUCCESS, /**< Request was processed successfully. */ - EC_SDO_REQUEST_ERROR, /**< Request processing failed. */ -} ec_sdo_request_state_t; + EC_REQUEST_UNUSED, /**< Not requested. */ + EC_REQUEST_BUSY, /**< Request is being processed. */ + EC_REQUEST_SUCCESS, /**< Request was processed successfully. */ + EC_REQUEST_ERROR, /**< Request processing failed. */ +} ec_request_state_t; /****************************************************************************** * Global functions @@ -727,6 +731,17 @@ size_t size /**< Data size to reserve. */ ); +/** Create an VoE handler to exchange vendor-specific data during realtime + * operation. + * + * The created VoE handler object is freed automatically when the master is + * released. + */ +ec_voe_handler_t *ecrt_slave_config_create_voe_handler( + ec_slave_config_t *sc, /**< Slave configuration. */ + size_t size /**< Data size to reserve. */ + ); + /** Outputs the state of the slave configuration. * * Stores the state information in the given \a state structure. @@ -878,7 +893,7 @@ * * \return Request state. */ -ec_sdo_request_state_t ecrt_sdo_request_state( +ec_request_state_t ecrt_sdo_request_state( const ec_sdo_request_t *req /**< Sdo request. */ ); @@ -904,6 +919,73 @@ ec_sdo_request_t *req /**< Sdo request. */ ); +/***************************************************************************** + * VoE handler methods. + ****************************************************************************/ + +/** Access to the VoE handler's data. + * + * This function returns a pointer to the handler's internal memory. + * + * - After a read operation was successful, the memory contains the received + * data. The size of the received data can be determined via + * ecrt_voe_handler_data_size(). + * - Before a write operation is triggered, the data have to be written to + * the internal memory. Be sure, that the data fit into the memory. The + * memory size is a parameter of ecrt_slave_config_create_voe_handler(). + * + * \return Pointer to the internal memory. + */ +uint8_t *ecrt_voe_handler_data( + ec_voe_handler_t *voe /**< VoE handler. */ + ); + +/** Returns the current data size. + * + * When the VoE handler is created, the data size is set to the size of the + * reserved memory. At a write operation, the data size is set to the number + * of bytes to write. After a read operation the size is set to the size of + * the read data. The size is not modified in any other situation. + * + * \return Data size in bytes. + */ +size_t ecrt_voe_handler_data_size( + const ec_voe_handler_t *voe /**< VoE handler. */ + ); + +/** Start a VoE write operation. + * + * After this function has been called, the ecrt_voe_handler_execute() method + * must be called in every bus cycle as long as it returns EC_REQUEST_BUSY. + */ +void ecrt_voe_handler_write( + ec_voe_handler_t *voe, /**< VoE handler. */ + size_t size /**< Number of bytes to write. */ + ); + +/** Start a VoE read operation. + * + * After this function has been called, the ecrt_voe_handler_execute() method + * must be called in every bus cycle as long as it returns EC_REQUEST_BUSY. + * + * On success, the size of the read data can be determined via + * ecrt_voe_handler_data_size(). + */ +void ecrt_voe_handler_read( + ec_voe_handler_t *voe /**< VoE handler. */ + ); + +/** Execute the handler. + * + * This method executes the VoE handler. It has to be called in every bus cycle + * as long as it returns EC_REQUEST_BUSY. + * + * \return Handler state. + */ +ec_request_state_t ecrt_voe_handler_execute( + ec_voe_handler_t *voe /**< VoE handler. */ + ); + /****************************************************************************** * Bitwise read/write macros *****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/Kbuild.in --- a/master/Kbuild.in Wed Aug 27 16:04:18 2008 +0000 +++ b/master/Kbuild.in Mon Sep 01 14:17:18 2008 +0000 @@ -61,7 +61,8 @@ slave.o \ slave_config.o \ sync.o \ - sync_config.o + sync_config.o \ + voe_handler.o ifeq (@ENABLE_EOE@,1) ec_master-objs += ethernet.o diff -r 026e35646ab4 -r 8be462afb7f4 master/Makefile.am --- a/master/Makefile.am Wed Aug 27 16:04:18 2008 +0000 +++ b/master/Makefile.am Mon Sep 01 14:17:18 2008 +0000 @@ -64,7 +64,8 @@ slave.c slave.h \ slave_config.c slave_config.h \ sync.c sync.h \ - sync_config.c sync_config.h + sync_config.c sync_config.h \ + voe_handler.c voe_handler.h BUILT_SOURCES = \ Kbuild diff -r 026e35646ab4 -r 8be462afb7f4 master/cdev.c --- a/master/cdev.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/cdev.c Mon Sep 01 14:17:18 2008 +0000 @@ -726,10 +726,10 @@ // wait for processing through FSM if (wait_event_interruptible(master->sdo_queue, - request.req.state != EC_REQUEST_QUEUED)) { + request.req.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.req.state == EC_REQUEST_QUEUED) { + if (request.req.state == EC_INT_REQUEST_QUEUED) { list_del(&request.req.list); up(&master->master_sem); ec_sdo_request_clear(&request.req); @@ -740,11 +740,11 @@ } // wait until master FSM has finished processing - wait_event(master->sdo_queue, request.req.state != EC_REQUEST_BUSY); + wait_event(master->sdo_queue, request.req.state != EC_INT_REQUEST_BUSY); data.abort_code = request.req.abort_code; - if (request.req.state != EC_REQUEST_SUCCESS) { + if (request.req.state != EC_INT_REQUEST_SUCCESS) { data.data_size = 0; retval = -EIO; } else { @@ -828,10 +828,10 @@ // wait for processing through FSM if (wait_event_interruptible(master->sdo_queue, - request.req.state != EC_REQUEST_QUEUED)) { + request.req.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.req.state == EC_REQUEST_QUEUED) { + if (request.req.state == EC_INT_REQUEST_QUEUED) { list_del(&request.req.list); up(&master->master_sem); ec_sdo_request_clear(&request.req); @@ -842,11 +842,11 @@ } // wait until master FSM has finished processing - wait_event(master->sdo_queue, request.req.state != EC_REQUEST_BUSY); + wait_event(master->sdo_queue, request.req.state != EC_INT_REQUEST_BUSY); data.abort_code = request.req.abort_code; - retval = request.req.state == EC_REQUEST_SUCCESS ? 0 : -EIO; + retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; if (__copy_to_user((void __user *) arg, &data, sizeof(data))) { retval = -EFAULT; @@ -954,7 +954,7 @@ request.words = words; request.offset = data.offset; request.nwords = data.nwords; - request.state = EC_REQUEST_QUEUED; + request.state = EC_INT_REQUEST_QUEUED; // schedule SII write request. list_add_tail(&request.list, &master->sii_requests); @@ -963,10 +963,10 @@ // wait for processing through FSM if (wait_event_interruptible(master->sii_queue, - request.state != EC_REQUEST_QUEUED)) { + request.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.state == EC_REQUEST_QUEUED) { + if (request.state == EC_INT_REQUEST_QUEUED) { // abort request list_del(&request.list); up(&master->master_sem); @@ -977,11 +977,11 @@ } // wait until master FSM has finished processing - wait_event(master->sii_queue, request.state != EC_REQUEST_BUSY); + wait_event(master->sii_queue, request.state != EC_INT_REQUEST_BUSY); kfree(words); - return request.state == EC_REQUEST_SUCCESS ? 0 : -EIO; + return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; } /*****************************************************************************/ @@ -1027,7 +1027,7 @@ request.data = contents; request.offset = data.offset; request.length = data.length; - request.state = EC_REQUEST_QUEUED; + request.state = EC_INT_REQUEST_QUEUED; // schedule request. list_add_tail(&request.list, &master->phy_requests); @@ -1036,10 +1036,10 @@ // wait for processing through FSM if (wait_event_interruptible(master->phy_queue, - request.state != EC_REQUEST_QUEUED)) { + request.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.state == EC_REQUEST_QUEUED) { + if (request.state == EC_INT_REQUEST_QUEUED) { // abort request list_del(&request.list); up(&master->master_sem); @@ -1050,15 +1050,15 @@ } // wait until master FSM has finished processing - wait_event(master->phy_queue, request.state != EC_REQUEST_BUSY); - - if (request.state == EC_REQUEST_SUCCESS) { + wait_event(master->phy_queue, request.state != EC_INT_REQUEST_BUSY); + + if (request.state == EC_INT_REQUEST_SUCCESS) { if (copy_to_user((void __user *) data.data, contents, data.length)) return -EFAULT; } kfree(contents); - return request.state == EC_REQUEST_SUCCESS ? 0 : -EIO; + return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; } /*****************************************************************************/ @@ -1110,7 +1110,7 @@ request.data = contents; request.offset = data.offset; request.length = data.length; - request.state = EC_REQUEST_QUEUED; + request.state = EC_INT_REQUEST_QUEUED; // schedule request. list_add_tail(&request.list, &master->phy_requests); @@ -1119,10 +1119,10 @@ // wait for processing through FSM if (wait_event_interruptible(master->phy_queue, - request.state != EC_REQUEST_QUEUED)) { + request.state != EC_INT_REQUEST_QUEUED)) { // interrupted by signal down(&master->master_sem); - if (request.state == EC_REQUEST_QUEUED) { + if (request.state == EC_INT_REQUEST_QUEUED) { // abort request list_del(&request.list); up(&master->master_sem); @@ -1133,11 +1133,11 @@ } // wait until master FSM has finished processing - wait_event(master->phy_queue, request.state != EC_REQUEST_BUSY); + wait_event(master->phy_queue, request.state != EC_INT_REQUEST_BUSY); kfree(contents); - return request.state == EC_REQUEST_SUCCESS ? 0 : -EIO; + return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; } /*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/cdev.h --- a/master/cdev.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/cdev.h Mon Sep 01 14:17:18 2008 +0000 @@ -45,7 +45,6 @@ #include #include "globals.h" -#include "../include/ecrt.h" /*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/device.h --- a/master/device.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/device.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,7 +43,6 @@ #include -#include "../include/ecrt.h" #include "../devices/ecdev.h" #include "globals.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/ethernet.c --- a/master/ethernet.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/ethernet.c Mon Sep 01 14:17:18 2008 +0000 @@ -41,7 +41,6 @@ #include #include -#include "../include/ecrt.h" #include "globals.h" #include "master.h" #include "slave.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/ethernet.h --- a/master/ethernet.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/ethernet.h Mon Sep 01 14:17:18 2008 +0000 @@ -41,7 +41,6 @@ #include #include -#include "../include/ecrt.h" #include "globals.h" #include "slave.h" #include "datagram.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fmmu_config.h --- a/master/fmmu_config.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fmmu_config.h Mon Sep 01 14:17:18 2008 +0000 @@ -40,8 +40,6 @@ #ifndef __EC_FMMU_CONFIG_H__ #define __EC_FMMU_CONFIG_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "sync.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_change.h --- a/master/fsm_change.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_change.h Mon Sep 01 14:17:18 2008 +0000 @@ -42,7 +42,6 @@ #define __EC_FSM_CHANGE_H__ #include "globals.h" -#include "../include/ecrt.h" #include "datagram.h" #include "slave.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_coe.h --- a/master/fsm_coe.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_coe.h Mon Sep 01 14:17:18 2008 +0000 @@ -42,7 +42,6 @@ #define __EC_FSM_COE_H__ #include "globals.h" -#include "../include/ecrt.h" #include "datagram.h" #include "slave.h" #include "sdo.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_master.c --- a/master/fsm_master.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_master.c Mon Sep 01 14:17:18 2008 +0000 @@ -305,7 +305,7 @@ request = list_entry(master->sii_requests.next, ec_sii_write_request_t, list); list_del_init(&request->list); // dequeue - request->state = EC_REQUEST_BUSY; + request->state = EC_INT_REQUEST_BUSY; // found pending SII write operation. execute it! if (master->debug_level) @@ -345,7 +345,7 @@ request = list_entry(master->phy_requests.next, ec_phy_request_t, list); list_del_init(&request->list); // dequeue - request->state = EC_REQUEST_BUSY; + request->state = EC_INT_REQUEST_BUSY; // found pending request; process it! if (master->debug_level) @@ -360,7 +360,7 @@ if (request->length > fsm->datagram->mem_size) { EC_ERR("Request length (%u) exceeds maximum datagram size (%u)!\n", request->length, fsm->datagram->mem_size); - request->state = EC_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&master->phy_queue); continue; } @@ -398,10 +398,10 @@ if (!slave->config) continue; list_for_each_entry(req, &slave->config->sdo_requests, list) { - if (req->state == EC_REQUEST_QUEUED) { + if (req->state == EC_INT_REQUEST_QUEUED) { if (ec_sdo_request_timed_out(req)) { - req->state = EC_REQUEST_FAILURE; + req->state = EC_INT_REQUEST_FAILURE; if (master->debug_level) EC_DBG("Sdo request for slave %u timed out...\n", slave->ring_position); @@ -409,11 +409,11 @@ } if (slave->current_state == EC_SLAVE_STATE_INIT) { - req->state = EC_REQUEST_FAILURE; + req->state = EC_INT_REQUEST_FAILURE; continue; } - req->state = EC_REQUEST_BUSY; + req->state = EC_INT_REQUEST_BUSY; if (master->debug_level) EC_DBG("Processing Sdo request for slave %u...\n", slave->ring_position); @@ -438,13 +438,13 @@ request = list_entry(master->slave_sdo_requests.next, ec_master_sdo_request_t, list); list_del_init(&request->list); // dequeue - request->req.state = EC_REQUEST_BUSY; + request->req.state = EC_INT_REQUEST_BUSY; slave = request->slave; if (slave->current_state == EC_SLAVE_STATE_INIT) { EC_ERR("Discarding Sdo request, slave %u is in INIT.\n", slave->ring_position); - request->req.state = EC_REQUEST_FAILURE; + request->req.state = EC_INT_REQUEST_FAILURE; wake_up(&master->sdo_queue); continue; } @@ -812,7 +812,7 @@ if (!ec_fsm_sii_success(&fsm->fsm_sii)) { EC_ERR("Failed to write SII data to slave %u.\n", slave->ring_position); - request->state = EC_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&master->sii_queue); ec_fsm_master_restart(fsm); return; @@ -839,7 +839,7 @@ } // TODO: Evaluate other SII contents! - request->state = EC_REQUEST_SUCCESS; + request->state = EC_INT_REQUEST_SUCCESS; wake_up(&master->sii_queue); // check for another SII write request @@ -898,14 +898,14 @@ if (!ec_fsm_coe_success(&fsm->fsm_coe)) { EC_DBG("Failed to process Sdo request for slave %u.\n", fsm->slave->ring_position); - request->state = EC_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&master->sdo_queue); ec_fsm_master_restart(fsm); return; } // Sdo request finished - request->state = EC_REQUEST_SUCCESS; + request->state = EC_INT_REQUEST_SUCCESS; wake_up(&master->sdo_queue); if (master->debug_level) @@ -934,7 +934,7 @@ if (datagram->state != EC_DATAGRAM_RECEIVED) { EC_ERR("Failed to receive phy request datagram (state %u).\n", datagram->state); - request->state = EC_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&master->phy_queue); ec_fsm_master_restart(fsm); return; @@ -947,7 +947,7 @@ if (!request->data) { EC_ERR("Failed to allocate %u bytes of memory for phy request.\n", request->length); - request->state = EC_REQUEST_FAILURE; + request->state = EC_INT_REQUEST_FAILURE; wake_up(&master->phy_queue); ec_fsm_master_restart(fsm); return; @@ -955,7 +955,7 @@ memcpy(request->data, datagram->data, request->length); } - request->state = EC_REQUEST_SUCCESS; + request->state = EC_INT_REQUEST_SUCCESS; wake_up(&master->phy_queue); // check for another PHY request diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_master.h --- a/master/fsm_master.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_master.h Mon Sep 01 14:17:18 2008 +0000 @@ -41,8 +41,6 @@ #ifndef __EC_FSM_MASTER_H__ #define __EC_FSM_MASTER_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "datagram.h" #include "sdo_request.h" @@ -60,7 +58,7 @@ uint16_t offset; /**< SII word offset. */ size_t nwords; /**< Number of words. */ const uint16_t *words; /**< Pointer to the data words. */ - ec_request_state_t state; /**< State of the request. */ + ec_internal_request_state_t state; /**< State of the request. */ } ec_sii_write_request_t; /*****************************************************************************/ @@ -74,7 +72,7 @@ uint16_t offset; /**< Physical memory offset. */ size_t length; /**< Number of bytes. */ uint8_t *data; - ec_request_state_t state; /**< State of the request. */ + ec_internal_request_state_t state; /**< State of the request. */ } ec_phy_request_t; /*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_pdo.h --- a/master/fsm_pdo.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_pdo.h Mon Sep 01 14:17:18 2008 +0000 @@ -41,8 +41,6 @@ #ifndef __EC_FSM_PDO_H__ #define __EC_FSM_PDO_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "datagram.h" #include "fsm_coe.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_pdo_entry.h --- a/master/fsm_pdo_entry.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_pdo_entry.h Mon Sep 01 14:17:18 2008 +0000 @@ -41,7 +41,6 @@ #define __EC_FSM_PDO_ENTRY_H__ #include "globals.h" -#include "../include/ecrt.h" #include "datagram.h" #include "fsm_coe.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_sii.h --- a/master/fsm_sii.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_sii.h Mon Sep 01 14:17:18 2008 +0000 @@ -42,7 +42,6 @@ #define __EC_FSM_SII_H__ #include "globals.h" -#include "../include/ecrt.h" #include "datagram.h" #include "slave.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_slave_config.h --- a/master/fsm_slave_config.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_slave_config.h Mon Sep 01 14:17:18 2008 +0000 @@ -41,8 +41,6 @@ #ifndef __EC_FSM_SLAVE_CONFIG_H__ #define __EC_FSM_SLAVE_CONFIG_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "slave.h" #include "datagram.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/fsm_slave_scan.h --- a/master/fsm_slave_scan.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/fsm_slave_scan.h Mon Sep 01 14:17:18 2008 +0000 @@ -41,8 +41,6 @@ #ifndef __EC_FSM_SLAVE_SCAN_H__ #define __EC_FSM_SLAVE_SCAN_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "datagram.h" #include "slave.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/globals.h --- a/master/globals.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/globals.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,6 +43,7 @@ #include #include "../globals.h" +#include "../include/ecrt.h" /****************************************************************************** * EtherCAT master @@ -253,12 +254,16 @@ * state_table in master/sdo_request.c. */ typedef enum { - EC_REQUEST_INIT, - EC_REQUEST_QUEUED, - EC_REQUEST_BUSY, - EC_REQUEST_SUCCESS, - EC_REQUEST_FAILURE -} ec_request_state_t; + EC_INT_REQUEST_INIT, + EC_INT_REQUEST_QUEUED, + EC_INT_REQUEST_BUSY, + EC_INT_REQUEST_SUCCESS, + EC_INT_REQUEST_FAILURE +} ec_internal_request_state_t; + +/*****************************************************************************/ + +extern const ec_request_state_t ec_request_state_translation_table[]; /*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/master.c --- a/master/master.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/master.c Mon Sep 01 14:17:18 2008 +0000 @@ -46,7 +46,6 @@ #include #include -#include "../include/ecrt.h" #include "globals.h" #include "slave.h" #include "slave_config.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/module.c --- a/master/module.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/module.c Mon Sep 01 14:17:18 2008 +0000 @@ -545,6 +545,20 @@ /*****************************************************************************/ +/** Global request state type translation table. + * + * Translates an internal request state to an external one. + */ +const ec_request_state_t ec_request_state_translation_table[] = { + EC_REQUEST_UNUSED, // EC_INT_REQUEST_INIT, + EC_REQUEST_BUSY, // EC_INT_REQUEST_QUEUED, + EC_REQUEST_BUSY, // EC_INT_REQUEST_BUSY, + EC_REQUEST_SUCCESS, // EC_INT_REQUEST_SUCCESS, + EC_REQUEST_ERROR // EC_INT_REQUEST_FAILURE +}; + +/*****************************************************************************/ + /** \cond */ module_init(ec_init_module); diff -r 026e35646ab4 -r 8be462afb7f4 master/pdo.h --- a/master/pdo.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/pdo.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,8 +43,6 @@ #include -#include "../include/ecrt.h" - #include "globals.h" #include "pdo_entry.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/pdo_entry.h --- a/master/pdo_entry.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/pdo_entry.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,8 +43,6 @@ #include -#include "../include/ecrt.h" - #include "globals.h" /*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/pdo_list.h --- a/master/pdo_list.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/pdo_list.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,8 +43,6 @@ #include -#include "../include/ecrt.h" - #include "globals.h" #include "pdo.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/sdo_request.c --- a/master/sdo_request.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/sdo_request.c Mon Sep 01 14:17:18 2008 +0000 @@ -54,18 +54,6 @@ /*****************************************************************************/ -/** State type translation table. - */ -static const ec_sdo_request_state_t state_translation_table[] = { - EC_SDO_REQUEST_UNUSED, // EC_REQUEST_INIT, - EC_SDO_REQUEST_BUSY, // EC_REQUEST_QUEUED, - EC_SDO_REQUEST_BUSY, // EC_REQUEST_BUSY, - EC_SDO_REQUEST_SUCCESS, // EC_REQUEST_SUCCESS, - EC_SDO_REQUEST_ERROR // EC_REQUEST_FAILURE -}; - -/*****************************************************************************/ - /** Sdo request constructor. */ void ec_sdo_request_init( @@ -78,7 +66,7 @@ req->dir = EC_DIR_INVALID; req->issue_timeout = 0; // no timeout req->response_timeout = EC_SDO_REQUEST_RESPONSE_TIMEOUT; - req->state = EC_REQUEST_INIT; + req->state = EC_INT_REQUEST_INIT; req->abort_code = 0x00000000; } @@ -207,9 +195,9 @@ /*****************************************************************************/ -ec_sdo_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req) -{ - return state_translation_table[req->state]; +ec_request_state_t ecrt_sdo_request_state(const ec_sdo_request_t *req) +{ + return ec_request_state_translation_table[req->state]; } /*****************************************************************************/ @@ -217,7 +205,7 @@ void ecrt_sdo_request_read(ec_sdo_request_t *req) { req->dir = EC_DIR_INPUT; - req->state = EC_REQUEST_QUEUED; + req->state = EC_INT_REQUEST_QUEUED; req->abort_code = 0x00000000; req->jiffies_start = jiffies; } @@ -227,7 +215,7 @@ void ecrt_sdo_request_write(ec_sdo_request_t *req) { req->dir = EC_DIR_OUTPUT; - req->state = EC_REQUEST_QUEUED; + req->state = EC_INT_REQUEST_QUEUED; req->abort_code = 0x00000000; req->jiffies_start = jiffies; } diff -r 026e35646ab4 -r 8be462afb7f4 master/sdo_request.h --- a/master/sdo_request.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/sdo_request.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,8 +43,6 @@ #include -#include "../include/ecrt.h" - #include "globals.h" /*****************************************************************************/ @@ -65,7 +63,7 @@ ec_direction_t dir; /**< Direction. EC_DIR_OUTPUT means downloading to the slave, EC_DIR_INPUT means uploading from the slave. */ - ec_request_state_t state; /**< Sdo request state. */ + ec_internal_request_state_t state; /**< Sdo request state. */ unsigned long jiffies_start; /**< Jiffies, when the request was issued. */ unsigned long jiffies_sent; /**< Jiffies, when the upload/download request was sent. */ diff -r 026e35646ab4 -r 8be462afb7f4 master/slave.h --- a/master/slave.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/slave.h Mon Sep 01 14:17:18 2008 +0000 @@ -44,8 +44,6 @@ #include #include -#include "../include/ecrt.h" - #include "globals.h" #include "datagram.h" #include "pdo.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/slave_config.c --- a/master/slave_config.c Wed Aug 27 16:04:18 2008 +0000 +++ b/master/slave_config.c Mon Sep 01 14:17:18 2008 +0000 @@ -42,6 +42,7 @@ #include "globals.h" #include "master.h" +#include "voe_handler.h" #include "slave_config.h" @@ -75,6 +76,7 @@ INIT_LIST_HEAD(&sc->sdo_configs); INIT_LIST_HEAD(&sc->sdo_requests); + INIT_LIST_HEAD(&sc->voe_handlers); sc->used_fmmus = 0; } @@ -91,6 +93,7 @@ { unsigned int i; ec_sdo_request_t *req, *next_req; + ec_voe_handler_t *voe, *next_voe; ec_slave_config_detach(sc); @@ -111,6 +114,13 @@ ec_sdo_request_clear(req); kfree(req); } + + // free all VoE handlers + list_for_each_entry_safe(voe, next_voe, &sc->voe_handlers, list) { + list_del(&voe->list); + ec_voe_handler_clear(voe); + kfree(voe); + } } /*****************************************************************************/ @@ -742,6 +752,35 @@ /*****************************************************************************/ +ec_voe_handler_t *ecrt_slave_config_create_voe_handler(ec_slave_config_t *sc, + size_t size) +{ + ec_voe_handler_t *voe; + + if (sc->master->debug_level) + EC_DBG("ecrt_slave_config_create_voe_handler(sc = 0x%x, size = %u)\n", + (u32) sc, size); + + if (!(voe = (ec_voe_handler_t *) + kmalloc(sizeof(ec_voe_handler_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate Sdo request memory!\n"); + return NULL; + } + + if (ec_voe_handler_init(voe, sc, size)) { + kfree(voe); + return NULL; + } + + down(&sc->master->master_sem); + list_add_tail(&voe->list, &sc->voe_handlers); + up(&sc->master->master_sem); + + return voe; +} + +/*****************************************************************************/ + void ecrt_slave_config_state(const ec_slave_config_t *sc, ec_slave_config_state_t *state) { diff -r 026e35646ab4 -r 8be462afb7f4 master/slave_config.h --- a/master/slave_config.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/slave_config.h Mon Sep 01 14:17:18 2008 +0000 @@ -43,8 +43,6 @@ #include -#include "../include/ecrt.h" - #include "globals.h" #include "slave.h" #include "sync_config.h" @@ -74,7 +72,7 @@ struct list_head sdo_configs; /**< List of Sdo configurations. */ struct list_head sdo_requests; /**< List of Sdo requests. */ - + struct list_head voe_handlers; /**< List of VoE handlers. */ }; /*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/sync.h --- a/master/sync.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/sync.h Mon Sep 01 14:17:18 2008 +0000 @@ -40,8 +40,6 @@ #ifndef __EC_SYNC_H__ #define __EC_SYNC_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "pdo_list.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/sync_config.h --- a/master/sync_config.h Wed Aug 27 16:04:18 2008 +0000 +++ b/master/sync_config.h Mon Sep 01 14:17:18 2008 +0000 @@ -40,8 +40,6 @@ #ifndef __EC_SYNC_CONFIG_H__ #define __EC_SYNC_CONFIG_H__ -#include "../include/ecrt.h" - #include "globals.h" #include "pdo_list.h" diff -r 026e35646ab4 -r 8be462afb7f4 master/voe_handler.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/voe_handler.c Mon Sep 01 14:17:18 2008 +0000 @@ -0,0 +1,386 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** \file + * Vendor-specific-over-EtherCAT protocol handler functions. + */ + +/*****************************************************************************/ + +#include + +#include "master.h" +#include "slave_config.h" +#include "mailbox.h" +#include "voe_handler.h" + +/** VoE response timeout in [ms]. + */ +#define EC_VOE_RESPONSE_TIMEOUT 500 + +/*****************************************************************************/ + +void ec_voe_handler_clear_data(ec_voe_handler_t *); + +void ec_voe_handler_state_write_start(ec_voe_handler_t *); +void ec_voe_handler_state_write_response(ec_voe_handler_t *); + +void ec_voe_handler_state_read_start(ec_voe_handler_t *); +void ec_voe_handler_state_read_check(ec_voe_handler_t *); +void ec_voe_handler_state_read_response(ec_voe_handler_t *); + +void ec_voe_handler_state_end(ec_voe_handler_t *); +void ec_voe_handler_state_error(ec_voe_handler_t *); + +/*****************************************************************************/ + +/** VoE handler constructor. + */ +int ec_voe_handler_init( + ec_voe_handler_t *voe, /**< VoE handler. */ + ec_slave_config_t *sc, /**< Parent slave configuration. */ + size_t size /**< Size of memory to reserve. */ + ) +{ + voe->config = sc; + voe->data_size = 0; + voe->dir = EC_DIR_INVALID; + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_INIT; + + ec_datagram_init(&voe->datagram); + if (ec_datagram_prealloc(&voe->datagram, size + 6)) + return -1; + + return 0; +} + +/*****************************************************************************/ + +/** VoE handler destructor. + */ +void ec_voe_handler_clear( + ec_voe_handler_t *voe /**< VoE handler. */ + ) +{ + ec_datagram_clear(&voe->datagram); +} + +/***************************************************************************** + * Application interface. + ****************************************************************************/ + +uint8_t *ecrt_voe_handler_data(ec_voe_handler_t *voe) +{ + return voe->datagram.data + 6; +} + +/*****************************************************************************/ + +size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe) +{ + return voe->data_size; +} + +/*****************************************************************************/ + +void ecrt_voe_handler_read(ec_voe_handler_t *voe) +{ + voe->dir = EC_DIR_INPUT; + voe->state = ec_voe_handler_state_read_start; + voe->request_state = EC_INT_REQUEST_QUEUED; +} + +/*****************************************************************************/ + +void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size) +{ + voe->dir = EC_DIR_OUTPUT; + voe->datagram.data_size = size + 6; + voe->state = ec_voe_handler_state_write_start; + voe->request_state = EC_INT_REQUEST_QUEUED; +} + +/*****************************************************************************/ + +ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe) +{ + if (voe->config->slave) { + voe->state(voe); + if (voe->request_state == EC_REQUEST_BUSY) + ec_master_queue_datagram(voe->config->master, &voe->datagram); + } else { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + } + + return ec_request_state_translation_table[voe->request_state]; +} + +/****************************************************************************** + * State functions. + *****************************************************************************/ + +void ec_voe_handler_state_write_start(ec_voe_handler_t *voe) +{ + ec_slave_t *slave = voe->config->slave; + uint8_t *data; + + if (slave->master->debug_level) { + EC_DBG("Writing %u bytes of VoE data to slave %u.\n", + voe->data_size, slave->ring_position); + ec_print_data(ecrt_voe_handler_data(voe), voe->data_size); + } + + if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) { + EC_ERR("Slave %u does not support VoE!\n", slave->ring_position); + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + return; + } + + if (!(data = ec_slave_mbox_prepare_send( + slave, &voe->datagram, 0x01, voe->data_size))) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + return; + } + + voe->retries = EC_FSM_RETRIES; + voe->jiffies_start = jiffies; + voe->state = ec_voe_handler_state_write_response; +} + +/*****************************************************************************/ + +void ec_voe_handler_state_write_response(ec_voe_handler_t *voe) +{ + ec_datagram_t *datagram = &voe->datagram; + ec_slave_t *slave = voe->config->slave; + + if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) + return; + + if (datagram->state != EC_DATAGRAM_RECEIVED) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Failed to receive VoE write request datagram for" + " slave %u (datagram state %u).\n", + slave->ring_position, datagram->state); + return; + } + + if (datagram->working_counter != 1) { + if (!datagram->working_counter) { + unsigned long diff_ms = + (jiffies - voe->jiffies_start) * 1000 / HZ; + if (diff_ms < EC_VOE_RESPONSE_TIMEOUT) { + if (slave->master->debug_level) { + EC_DBG("Slave %u did not respond to VoE write request. " + "Retrying after %u ms...\n", + slave->ring_position, (u32) diff_ms); + } + // no response; send request datagram again + return; + } + } + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Reception of VoE write request failed on slave %u: ", + slave->ring_position); + ec_datagram_print_wc_error(datagram); + return; + } + + if (voe->config->master->debug_level) + EC_DBG("VoE write request successful.\n"); + + voe->request_state = EC_INT_REQUEST_SUCCESS; + voe->state = ec_voe_handler_state_end; +} + +/*****************************************************************************/ + +void ec_voe_handler_state_read_start(ec_voe_handler_t *voe) +{ + ec_datagram_t *datagram = &voe->datagram; + ec_slave_t *slave = voe->config->slave; + + if (slave->master->debug_level) + EC_DBG("Reading VoE data to slave %u.\n", slave->ring_position); + + if (!(slave->sii.mailbox_protocols & EC_MBOX_VOE)) { + EC_ERR("Slave %u does not support VoE!\n", slave->ring_position); + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + return; + } + + ec_slave_mbox_prepare_check(slave, datagram); // can not fail. + + voe->jiffies_start = jiffies; + voe->retries = EC_FSM_RETRIES; + voe->state = ec_voe_handler_state_read_check; +} + +/*****************************************************************************/ + +void ec_voe_handler_state_read_check(ec_voe_handler_t *voe) +{ + ec_datagram_t *datagram = &voe->datagram; + ec_slave_t *slave = voe->config->slave; + + if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) + return; + + if (datagram->state != EC_DATAGRAM_RECEIVED) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Failed to receive VoE mailbox check datagram from slave %u" + " (datagram state %u).\n", + slave->ring_position, datagram->state); + return; + } + + if (datagram->working_counter != 1) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Reception of VoE mailbox check" + " datagram failed on slave %u: ", slave->ring_position); + ec_datagram_print_wc_error(datagram); + return; + } + + if (!ec_slave_mbox_check(datagram)) { + unsigned long diff_ms = + (datagram->jiffies_received - voe->jiffies_start) * 1000 / HZ; + if (diff_ms >= EC_VOE_RESPONSE_TIMEOUT) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Timeout while waiting for VoE data on " + "slave %u.\n", slave->ring_position); + return; + } + + ec_slave_mbox_prepare_check(slave, datagram); // can not fail. + voe->retries = EC_FSM_RETRIES; + return; + } + + // Fetch response + ec_slave_mbox_prepare_fetch(slave, datagram); // can not fail. + voe->retries = EC_FSM_RETRIES; + voe->state = ec_voe_handler_state_read_response; +} + +/*****************************************************************************/ + +void ec_voe_handler_state_read_response(ec_voe_handler_t *voe) +{ + ec_datagram_t *datagram = &voe->datagram; + ec_slave_t *slave = voe->config->slave; + ec_master_t *master = voe->config->master; + uint8_t *data, mbox_prot; + size_t rec_size; + + if (datagram->state == EC_DATAGRAM_TIMED_OUT && voe->retries--) + return; + + if (datagram->state != EC_DATAGRAM_RECEIVED) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Failed to receive VoE read datagram for" + " slave %u (datagram state %u).\n", + slave->ring_position, datagram->state); + return; + } + + if (datagram->working_counter != 1) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_ERR("Reception of VoE read response failed on slave %u: ", + slave->ring_position); + ec_datagram_print_wc_error(datagram); + return; + } + + if (!(data = ec_slave_mbox_fetch(slave, datagram, + &mbox_prot, &rec_size))) { + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + return; + } + + if (mbox_prot != 0x01) { // VoE + voe->state = ec_voe_handler_state_error; + voe->request_state = EC_INT_REQUEST_FAILURE; + EC_WARN("Received mailbox protocol 0x%02X as response.\n", mbox_prot); + ec_print_data(data, rec_size); + return; + } + + if (master->debug_level) { + EC_DBG("VoE data:\n"); + ec_print_data(data, rec_size); + } + + voe->data_size = rec_size; + voe->request_state = EC_INT_REQUEST_SUCCESS; + voe->state = ec_voe_handler_state_end; // success +} + +/*****************************************************************************/ + +void ec_voe_handler_state_end(ec_voe_handler_t *voe) +{ +} + +/*****************************************************************************/ + +void ec_voe_handler_state_error(ec_voe_handler_t *voe) +{ +} + +/*****************************************************************************/ + +/** \cond */ + +EXPORT_SYMBOL(ecrt_voe_handler_data); +EXPORT_SYMBOL(ecrt_voe_handler_data_size); +EXPORT_SYMBOL(ecrt_voe_handler_read); +EXPORT_SYMBOL(ecrt_voe_handler_write); +EXPORT_SYMBOL(ecrt_voe_handler_execute); + +/** \endcond */ + +/*****************************************************************************/ diff -r 026e35646ab4 -r 8be462afb7f4 master/voe_handler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/voe_handler.h Mon Sep 01 14:17:18 2008 +0000 @@ -0,0 +1,74 @@ +/****************************************************************************** + * + * $Id$ + * + * Copyright (C) 2006 Florian Pose, Ingenieurgemeinschaft IgH + * + * This file is part of the IgH EtherCAT Master. + * + * The IgH EtherCAT Master is free software; you can redistribute it + * and/or modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The IgH EtherCAT Master is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with the IgH EtherCAT Master; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * The right to use EtherCAT Technology is granted and comes free of + * charge under condition of compatibility of product made by + * Licensee. People intending to distribute/sell products based on the + * code, have to sign an agreement to guarantee that products using + * software based on IgH EtherCAT master stay compatible with the actual + * EtherCAT specification (which are released themselves as an open + * standard) as the (only) precondition to have the right to use EtherCAT + * Technology, IP and trade marks. + * + *****************************************************************************/ + +/** + \file + Vendor-specific-over-EtherCAT protocol handler. +*/ + +/*****************************************************************************/ + +#ifndef __EC_VOE_HANDLER_H__ +#define __EC_VOE_HANDLER_H__ + +#include + +#include "globals.h" +#include "datagram.h" + +/*****************************************************************************/ + +/** Vendor-specific-over-EtherCAT handler. + */ +struct ec_voe_handler { + struct list_head list; /**< List item. */ + ec_slave_config_t *config; /**< Parent slave configuration. */ + ec_datagram_t datagram; /**< State machine datagram. */ + size_t data_size; /**< Size of Sdo data. */ + ec_direction_t dir; /**< Direction. EC_DIR_OUTPUT means writing to + the slave, EC_DIR_INPUT means reading from the + slave. */ + void (*state)(ec_voe_handler_t *); /**< State function */ + ec_internal_request_state_t request_state; /**< Handler state. */ + unsigned int retries; /**< retries upon datagram timeout */ + unsigned long jiffies_start; /**< Timestamp for timeout calculation. */ +}; + +/*****************************************************************************/ + +int ec_voe_handler_init(ec_voe_handler_t *, ec_slave_config_t *, size_t); +void ec_voe_handler_clear(ec_voe_handler_t *); + +/*****************************************************************************/ + +#endif