# HG changeset patch # User Florian Pose # Date 1152174204 0 # Node ID 14aeb79aa992f2632687e5dee527e7ae50d0cbdb # Parent 2cf6ae0a24197402d6f630d46056d215377c3167 Renamed command structure to datagram. diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/Makefile --- a/master/Makefile Tue Jun 27 20:24:32 2006 +0000 +++ b/master/Makefile Thu Jul 06 08:23:24 2006 +0000 @@ -42,7 +42,7 @@ obj-m := ec_master.o -ec_master-objs := module.o master.o device.o slave.o command.o types.o \ +ec_master-objs := module.o master.o device.o slave.o datagram.o types.o \ domain.o mailbox.o canopen.o ethernet.o debug.o fsm.o REV := $(shell svnversion $(src) 2>/dev/null || echo "unknown") diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/canopen.c --- a/master/canopen.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/canopen.c Thu Jul 06 08:23:24 2006 +0000 @@ -48,8 +48,8 @@ /*****************************************************************************/ void ec_canopen_abort_msg(uint32_t); -int ec_slave_fetch_sdo_descriptions(ec_slave_t *, ec_command_t *); -int ec_slave_fetch_sdo_entries(ec_slave_t *, ec_command_t *, +int ec_slave_fetch_sdo_descriptions(ec_slave_t *, ec_datagram_t *); +int ec_slave_fetch_sdo_entries(ec_slave_t *, ec_datagram_t *, ec_sdo_t *, uint8_t); /*****************************************************************************/ @@ -65,13 +65,13 @@ uint8_t *target /**< 4-byte memory */ ) { - ec_command_t command; + ec_datagram_t datagram; size_t rec_size; uint8_t *data; - ec_command_init(&command); - - if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 6))) + ec_datagram_init(&datagram); + + if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 6))) goto err; EC_WRITE_U16(data, 0x2 << 12); // SDO request @@ -80,7 +80,7 @@ EC_WRITE_U16(data + 3, sdo_index); EC_WRITE_U8 (data + 5, sdo_subindex); - if (!(data = ec_slave_mbox_simple_io(slave, &command, &rec_size))) + if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size))) goto err; if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request @@ -104,10 +104,10 @@ memcpy(target, data + 6, 4); - ec_command_clear(&command); + ec_datagram_clear(&datagram); return 0; err: - ec_command_clear(&command); + ec_datagram_clear(&datagram); return -1; } @@ -127,16 +127,16 @@ { uint8_t *data; size_t rec_size; - ec_command_t command; - - ec_command_init(&command); + ec_datagram_t datagram; + + ec_datagram_init(&datagram); if (size == 0 || size > 4) { EC_ERR("Invalid data size!\n"); goto err; } - if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 0x0A))) + if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 0x0A))) goto err; EC_WRITE_U16(data, 0x2 << 12); // SDO request @@ -149,7 +149,7 @@ memcpy(data + 6, sdo_data, size); if (size < 4) memset(data + 6 + size, 0x00, 4 - size); - if (!(data = ec_slave_mbox_simple_io(slave, &command, &rec_size))) + if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size))) goto err; if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request @@ -172,10 +172,10 @@ return -1; } - ec_command_clear(&command); + ec_datagram_clear(&datagram); return 0; err: - ec_command_clear(&command); + ec_datagram_clear(&datagram); return -1; } @@ -198,11 +198,11 @@ uint8_t *data; size_t rec_size, data_size; uint32_t complete_size; - ec_command_t command; - - ec_command_init(&command); - - if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 6))) + ec_datagram_t datagram; + + ec_datagram_init(&datagram); + + if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 6))) goto err; EC_WRITE_U16(data, 0x2 << 12); // SDO request @@ -210,7 +210,7 @@ EC_WRITE_U16(data + 3, sdo_index); EC_WRITE_U8 (data + 5, sdo_subindex); - if (!(data = ec_slave_mbox_simple_io(slave, &command, &rec_size))) + if (!(data = ec_slave_mbox_simple_io(slave, &datagram, &rec_size))) goto err; if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request @@ -253,10 +253,10 @@ memcpy(target, data + 10, data_size); - ec_command_clear(&command); + ec_datagram_clear(&datagram); return 0; err: - ec_command_clear(&command); + ec_datagram_clear(&datagram); return -1; } @@ -274,11 +274,11 @@ unsigned int i, sdo_count; ec_sdo_t *sdo; uint16_t sdo_index; - ec_command_t command; - - ec_command_init(&command); - - if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 8))) + ec_datagram_t datagram; + + ec_datagram_init(&datagram); + + if (!(data = ec_slave_mbox_prepare_send(slave, &datagram, 0x03, 8))) goto err; EC_WRITE_U16(data, 0x8 << 12); // SDO information @@ -287,13 +287,13 @@ EC_WRITE_U16(data + 4, 0x0000); EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs! - if (unlikely(ec_master_simple_io(slave->master, &command))) { + if (unlikely(ec_master_simple_io(slave->master, &datagram))) { EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position); goto err; } do { - if (!(data = ec_slave_mbox_simple_receive(slave, &command, + if (!(data = ec_slave_mbox_simple_receive(slave, &datagram, 0x03, &rec_size))) goto err; @@ -342,12 +342,12 @@ while (EC_READ_U8(data + 2) & 0x80); // Fetch all SDO descriptions - if (ec_slave_fetch_sdo_descriptions(slave, &command)) goto err; - - ec_command_clear(&command); + if (ec_slave_fetch_sdo_descriptions(slave, &datagram)) goto err; + + ec_datagram_clear(&datagram); return 0; err: - ec_command_clear(&command); + ec_datagram_clear(&datagram); return -1; } @@ -359,7 +359,7 @@ */ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, /**< EtherCAT slave */ - ec_command_t *command /**< command */ + ec_datagram_t *datagram /**< datagram */ ) { uint8_t *data; @@ -367,7 +367,7 @@ ec_sdo_t *sdo; list_for_each_entry(sdo, &slave->sdo_dictionary, list) { - if (!(data = ec_slave_mbox_prepare_send(slave, command, 0x03, 8))) + if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 8))) return -1; EC_WRITE_U16(data, 0x8 << 12); // SDO information EC_WRITE_U8 (data + 2, 0x03); // Get object description request @@ -375,7 +375,7 @@ EC_WRITE_U16(data + 4, 0x0000); EC_WRITE_U16(data + 6, sdo->index); // SDO index - if (!(data = ec_slave_mbox_simple_io(slave, command, &rec_size))) + if (!(data = ec_slave_mbox_simple_io(slave, datagram, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information @@ -428,7 +428,7 @@ } // Fetch all entries (subindices) - if (ec_slave_fetch_sdo_entries(slave, command, sdo, + if (ec_slave_fetch_sdo_entries(slave, datagram, sdo, EC_READ_U8(data + 10))) return -1; } @@ -444,7 +444,7 @@ */ int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */ - ec_command_t *command, /**< command */ + ec_datagram_t *datagram, /**< datagram */ ec_sdo_t *sdo, /**< SDO */ uint8_t subindices /**< number of subindices */ ) @@ -455,7 +455,7 @@ ec_sdo_entry_t *entry; for (i = 1; i <= subindices; i++) { - if (!(data = ec_slave_mbox_prepare_send(slave, command, 0x03, 10))) + if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, 10))) return -1; EC_WRITE_U16(data, 0x8 << 12); // SDO information @@ -466,7 +466,7 @@ EC_WRITE_U8 (data + 8, i); // SDO subindex EC_WRITE_U8 (data + 9, 0x00); // value info (no values) - if (!(data = ec_slave_mbox_simple_io(slave, command, &rec_size))) + if (!(data = ec_slave_mbox_simple_io(slave, datagram, &rec_size))) return -1; if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/command.c --- a/master/command.c Tue Jun 27 20:24:32 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,297 +0,0 @@ -/****************************************************************************** - * - * $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 - Methods of an EtherCAT command. -*/ - -/*****************************************************************************/ - -#include - -#include "command.h" -#include "master.h" - -/*****************************************************************************/ - -/** \cond */ - -#define EC_FUNC_HEADER \ - if (unlikely(ec_command_prealloc(command, data_size))) \ - return -1; \ - command->index = 0; \ - command->working_counter = 0; \ - command->state = EC_CMD_INIT; - -#define EC_FUNC_FOOTER \ - command->data_size = data_size; \ - memset(command->data, 0x00, data_size); \ - return 0; - -/** \endcond */ - -/*****************************************************************************/ - -/** - Command constructor. -*/ - -void ec_command_init(ec_command_t *command /**< EtherCAT command */) -{ - command->type = EC_CMD_NONE; - command->address.logical = 0x00000000; - command->data = NULL; - command->mem_size = 0; - command->data_size = 0; - command->index = 0x00; - command->working_counter = 0x00; - command->state = EC_CMD_INIT; - command->t_sent = 0; -} - -/*****************************************************************************/ - -/** - Command destructor. -*/ - -void ec_command_clear(ec_command_t *command /**< EtherCAT command */) -{ - if (command->data) kfree(command->data); -} - -/*****************************************************************************/ - -/** - Allocates command data memory. - If the allocated memory is already larger than requested, nothing ist done. - \return 0 in case of success, else < 0 -*/ - -int ec_command_prealloc(ec_command_t *command, /**< EtherCAT command */ - size_t size /**< New size in bytes */ - ) -{ - if (size <= command->mem_size) return 0; - - if (command->data) { - kfree(command->data); - command->data = NULL; - command->mem_size = 0; - } - - if (!(command->data = kmalloc(size, GFP_KERNEL))) { - EC_ERR("Failed to allocate %i bytes of command memory!\n", size); - return -1; - } - - command->mem_size = size; - return 0; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT NPRD command. - Node-adressed physical read. - \return 0 in case of success, else < 0 -*/ - -int ec_command_nprd(ec_command_t *command, - /**< EtherCAT command */ - uint16_t node_address, - /**< configured station address */ - uint16_t offset, - /**< physical memory address */ - size_t data_size - /**< number of bytes to read */ - ) -{ - if (unlikely(node_address == 0x0000)) - EC_WARN("Using node address 0x0000!\n"); - - EC_FUNC_HEADER; - command->type = EC_CMD_NPRD; - command->address.physical.slave = node_address; - command->address.physical.mem = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT NPWR command. - Node-adressed physical write. - \return 0 in case of success, else < 0 -*/ - -int ec_command_npwr(ec_command_t *command, - /**< EtherCAT command */ - uint16_t node_address, - /**< configured station address */ - uint16_t offset, - /**< physical memory address */ - size_t data_size - /**< number of bytes to write */ - ) -{ - if (unlikely(node_address == 0x0000)) - EC_WARN("Using node address 0x0000!\n"); - - EC_FUNC_HEADER; - command->type = EC_CMD_NPWR; - command->address.physical.slave = node_address; - command->address.physical.mem = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT APRD command. - Autoincrement physical read. - \return 0 in case of success, else < 0 -*/ - -int ec_command_aprd(ec_command_t *command, - /**< EtherCAT command */ - uint16_t ring_position, - /**< auto-increment position */ - uint16_t offset, - /**< physical memory address */ - size_t data_size - /**< number of bytes to read */ - ) -{ - EC_FUNC_HEADER; - command->type = EC_CMD_APRD; - command->address.physical.slave = (int16_t) ring_position * (-1); - command->address.physical.mem = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT APWR command. - Autoincrement physical write. - \return 0 in case of success, else < 0 -*/ - -int ec_command_apwr(ec_command_t *command, - /**< EtherCAT command */ - uint16_t ring_position, - /**< auto-increment position */ - uint16_t offset, - /**< physical memory address */ - size_t data_size - /**< number of bytes to write */ - ) -{ - EC_FUNC_HEADER; - command->type = EC_CMD_APWR; - command->address.physical.slave = (int16_t) ring_position * (-1); - command->address.physical.mem = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT BRD command. - Broadcast read. - \return 0 in case of success, else < 0 -*/ - -int ec_command_brd(ec_command_t *command, - /**< EtherCAT command */ - uint16_t offset, - /**< physical memory address */ - size_t data_size - /**< number of bytes to read */ - ) -{ - EC_FUNC_HEADER; - command->type = EC_CMD_BRD; - command->address.physical.slave = 0x0000; - command->address.physical.mem = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT BWR command. - Broadcast write. - \return 0 in case of success, else < 0 -*/ - -int ec_command_bwr(ec_command_t *command, - /**< EtherCAT command */ - uint16_t offset, - /**< physical memory address */ - size_t data_size - /**< number of bytes to write */ - ) -{ - EC_FUNC_HEADER; - command->type = EC_CMD_BWR; - command->address.physical.slave = 0x0000; - command->address.physical.mem = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ - -/** - Initializes an EtherCAT LRW command. - Logical read write. - \return 0 in case of success, else < 0 -*/ - -int ec_command_lrw(ec_command_t *command, - /**< EtherCAT command */ - uint32_t offset, - /**< logical address */ - size_t data_size - /**< number of bytes to read/write */ - ) -{ - EC_FUNC_HEADER; - command->type = EC_CMD_LRW; - command->address.logical = offset; - EC_FUNC_FOOTER; -} - -/*****************************************************************************/ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/command.h --- a/master/command.h Tue Jun 27 20:24:32 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/****************************************************************************** - * - * $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 - EtherCAT command structure. -*/ - -/*****************************************************************************/ - -#ifndef _EC_COMMAND_H_ -#define _EC_COMMAND_H_ - -#include -#include - -#include "globals.h" - -/*****************************************************************************/ - -/** - EtherCAT command type. -*/ - -typedef enum -{ - EC_CMD_NONE = 0x00, /**< Dummy */ - EC_CMD_APRD = 0x01, /**< Auto-increment physical read */ - EC_CMD_APWR = 0x02, /**< Auto-increment physical write */ - EC_CMD_NPRD = 0x04, /**< Node-addressed physical read */ - EC_CMD_NPWR = 0x05, /**< Node-addressed physical write */ - EC_CMD_BRD = 0x07, /**< Broadcast read */ - EC_CMD_BWR = 0x08, /**< Broadcast write */ - EC_CMD_LRW = 0x0C /**< Logical read/write */ -} -ec_command_type_t; - -/** - EtherCAT command state. -*/ - -typedef enum -{ - EC_CMD_INIT, /**< new command */ - EC_CMD_QUEUED, /**< command queued by master */ - EC_CMD_SENT, /**< command has been sent */ - EC_CMD_RECEIVED, /**< command has been received */ - EC_CMD_TIMEOUT, /**< command timed out */ - EC_CMD_ERROR /**< error while sending/receiving */ -} -ec_command_state_t; - -/*****************************************************************************/ - -/** - EtherCAT address. -*/ - -typedef union -{ - struct - { - uint16_t slave; /**< configured or autoincrement address */ - uint16_t mem; /**< physical memory address */ - } - physical; /**< physical address */ - - uint32_t logical; /**< logical address */ -} -ec_address_t; - -/*****************************************************************************/ - -/** - EtherCAT command. -*/ - -typedef struct -{ - struct list_head list; /**< needed by domain command lists */ - struct list_head queue; /**< master command queue item */ - ec_command_type_t type; /**< command type (APRD, BWR, etc) */ - ec_address_t address; /**< receipient address */ - uint8_t *data; /**< command data */ - size_t mem_size; /**< command \a data memory size */ - size_t data_size; /**< size of the data in \a data */ - uint8_t index; /**< command index (set by master) */ - uint16_t working_counter; /**< working counter */ - ec_command_state_t state; /**< command state */ - cycles_t t_sent; /**< time, the commands was sent */ -} -ec_command_t; - -/*****************************************************************************/ - -void ec_command_init(ec_command_t *); -void ec_command_clear(ec_command_t *); -int ec_command_prealloc(ec_command_t *, size_t); - -int ec_command_nprd(ec_command_t *, uint16_t, uint16_t, size_t); -int ec_command_npwr(ec_command_t *, uint16_t, uint16_t, size_t); -int ec_command_aprd(ec_command_t *, uint16_t, uint16_t, size_t); -int ec_command_apwr(ec_command_t *, uint16_t, uint16_t, size_t); -int ec_command_brd(ec_command_t *, uint16_t, size_t); -int ec_command_bwr(ec_command_t *, uint16_t, size_t); -int ec_command_lrw(ec_command_t *, uint32_t, size_t); - -/*****************************************************************************/ - -#endif diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/datagram.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/datagram.c Thu Jul 06 08:23:24 2006 +0000 @@ -0,0 +1,297 @@ +/****************************************************************************** + * + * $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 + Methods of an EtherCAT datagram. +*/ + +/*****************************************************************************/ + +#include + +#include "datagram.h" +#include "master.h" + +/*****************************************************************************/ + +/** \cond */ + +#define EC_FUNC_HEADER \ + if (unlikely(ec_datagram_prealloc(datagram, data_size))) \ + return -1; \ + datagram->index = 0; \ + datagram->working_counter = 0; \ + datagram->state = EC_CMD_INIT; + +#define EC_FUNC_FOOTER \ + datagram->data_size = data_size; \ + memset(datagram->data, 0x00, data_size); \ + return 0; + +/** \endcond */ + +/*****************************************************************************/ + +/** + Datagram constructor. +*/ + +void ec_datagram_init(ec_datagram_t *datagram /**< EtherCAT datagram */) +{ + datagram->type = EC_CMD_NONE; + datagram->address.logical = 0x00000000; + datagram->data = NULL; + datagram->mem_size = 0; + datagram->data_size = 0; + datagram->index = 0x00; + datagram->working_counter = 0x00; + datagram->state = EC_CMD_INIT; + datagram->t_sent = 0; +} + +/*****************************************************************************/ + +/** + Datagram destructor. +*/ + +void ec_datagram_clear(ec_datagram_t *datagram /**< EtherCAT datagram */) +{ + if (datagram->data) kfree(datagram->data); +} + +/*****************************************************************************/ + +/** + Allocates datagram data memory. + If the allocated memory is already larger than requested, nothing ist done. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_prealloc(ec_datagram_t *datagram, /**< EtherCAT datagram */ + size_t size /**< New size in bytes */ + ) +{ + if (size <= datagram->mem_size) return 0; + + if (datagram->data) { + kfree(datagram->data); + datagram->data = NULL; + datagram->mem_size = 0; + } + + if (!(datagram->data = kmalloc(size, GFP_KERNEL))) { + EC_ERR("Failed to allocate %i bytes of datagram memory!\n", size); + return -1; + } + + datagram->mem_size = size; + return 0; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT NPRD datagram. + Node-adressed physical read. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_nprd(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint16_t node_address, + /**< configured station address */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to read */ + ) +{ + if (unlikely(node_address == 0x0000)) + EC_WARN("Using node address 0x0000!\n"); + + EC_FUNC_HEADER; + datagram->type = EC_CMD_NPRD; + datagram->address.physical.slave = node_address; + datagram->address.physical.mem = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT NPWR datagram. + Node-adressed physical write. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_npwr(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint16_t node_address, + /**< configured station address */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to write */ + ) +{ + if (unlikely(node_address == 0x0000)) + EC_WARN("Using node address 0x0000!\n"); + + EC_FUNC_HEADER; + datagram->type = EC_CMD_NPWR; + datagram->address.physical.slave = node_address; + datagram->address.physical.mem = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT APRD datagram. + Autoincrement physical read. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_aprd(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint16_t ring_position, + /**< auto-increment position */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to read */ + ) +{ + EC_FUNC_HEADER; + datagram->type = EC_CMD_APRD; + datagram->address.physical.slave = (int16_t) ring_position * (-1); + datagram->address.physical.mem = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT APWR datagram. + Autoincrement physical write. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_apwr(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint16_t ring_position, + /**< auto-increment position */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to write */ + ) +{ + EC_FUNC_HEADER; + datagram->type = EC_CMD_APWR; + datagram->address.physical.slave = (int16_t) ring_position * (-1); + datagram->address.physical.mem = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT BRD datagram. + Broadcast read. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_brd(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to read */ + ) +{ + EC_FUNC_HEADER; + datagram->type = EC_CMD_BRD; + datagram->address.physical.slave = 0x0000; + datagram->address.physical.mem = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT BWR datagram. + Broadcast write. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_bwr(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint16_t offset, + /**< physical memory address */ + size_t data_size + /**< number of bytes to write */ + ) +{ + EC_FUNC_HEADER; + datagram->type = EC_CMD_BWR; + datagram->address.physical.slave = 0x0000; + datagram->address.physical.mem = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ + +/** + Initializes an EtherCAT LRW datagram. + Logical read write. + \return 0 in case of success, else < 0 +*/ + +int ec_datagram_lrw(ec_datagram_t *datagram, + /**< EtherCAT datagram */ + uint32_t offset, + /**< logical address */ + size_t data_size + /**< number of bytes to read/write */ + ) +{ + EC_FUNC_HEADER; + datagram->type = EC_CMD_LRW; + datagram->address.logical = offset; + EC_FUNC_FOOTER; +} + +/*****************************************************************************/ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/datagram.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/master/datagram.h Thu Jul 06 08:23:24 2006 +0000 @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * $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 + EtherCAT datagram structure. +*/ + +/*****************************************************************************/ + +#ifndef _EC_DATAGRAM_H_ +#define _EC_DATAGRAM_H_ + +#include +#include + +#include "globals.h" + +/*****************************************************************************/ + +/** + EtherCAT datagram type. +*/ + +typedef enum +{ + EC_CMD_NONE = 0x00, /**< Dummy */ + EC_CMD_APRD = 0x01, /**< Auto-increment physical read */ + EC_CMD_APWR = 0x02, /**< Auto-increment physical write */ + EC_CMD_NPRD = 0x04, /**< Node-addressed physical read */ + EC_CMD_NPWR = 0x05, /**< Node-addressed physical write */ + EC_CMD_BRD = 0x07, /**< Broadcast read */ + EC_CMD_BWR = 0x08, /**< Broadcast write */ + EC_CMD_LRW = 0x0C /**< Logical read/write */ +} +ec_datagram_type_t; + +/** + EtherCAT datagram state. +*/ + +typedef enum +{ + EC_CMD_INIT, /**< new datagram */ + EC_CMD_QUEUED, /**< datagram queued by master */ + EC_CMD_SENT, /**< datagram has been sent */ + EC_CMD_RECEIVED, /**< datagram has been received */ + EC_CMD_TIMEOUT, /**< datagram timed out */ + EC_CMD_ERROR /**< error while sending/receiving */ +} +ec_datagram_state_t; + +/*****************************************************************************/ + +/** + EtherCAT address. +*/ + +typedef union +{ + struct + { + uint16_t slave; /**< configured or autoincrement address */ + uint16_t mem; /**< physical memory address */ + } + physical; /**< physical address */ + + uint32_t logical; /**< logical address */ +} +ec_address_t; + +/*****************************************************************************/ + +/** + EtherCAT datagram. +*/ + +typedef struct +{ + struct list_head list; /**< needed by domain datagram lists */ + struct list_head queue; /**< master datagram queue item */ + ec_datagram_type_t type; /**< datagram type (APRD, BWR, etc) */ + ec_address_t address; /**< receipient address */ + uint8_t *data; /**< datagram data */ + size_t mem_size; /**< datagram \a data memory size */ + size_t data_size; /**< size of the data in \a data */ + uint8_t index; /**< datagram index (set by master) */ + uint16_t working_counter; /**< working counter */ + ec_datagram_state_t state; /**< datagram state */ + cycles_t t_sent; /**< time, the datagrams was sent */ +} +ec_datagram_t; + +/*****************************************************************************/ + +void ec_datagram_init(ec_datagram_t *); +void ec_datagram_clear(ec_datagram_t *); +int ec_datagram_prealloc(ec_datagram_t *, size_t); + +int ec_datagram_nprd(ec_datagram_t *, uint16_t, uint16_t, size_t); +int ec_datagram_npwr(ec_datagram_t *, uint16_t, uint16_t, size_t); +int ec_datagram_aprd(ec_datagram_t *, uint16_t, uint16_t, size_t); +int ec_datagram_apwr(ec_datagram_t *, uint16_t, uint16_t, size_t); +int ec_datagram_brd(ec_datagram_t *, uint16_t, size_t); +int ec_datagram_bwr(ec_datagram_t *, uint16_t, size_t); +int ec_datagram_lrw(ec_datagram_t *, uint32_t, size_t); + +/*****************************************************************************/ + +#endif diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/domain.c --- a/master/domain.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/domain.c Thu Jul 06 08:23:24 2006 +0000 @@ -90,7 +90,7 @@ domain->response_count = 0xFFFFFFFF; INIT_LIST_HEAD(&domain->field_regs); - INIT_LIST_HEAD(&domain->commands); + INIT_LIST_HEAD(&domain->datagrams); // init kobject and add it to the hierarchy memset(&domain->kobj, 0x00, sizeof(struct kobject)); @@ -113,16 +113,16 @@ void ec_domain_clear(struct kobject *kobj /**< kobject of the domain */) { - ec_command_t *command, *next; + ec_datagram_t *datagram, *next; ec_domain_t *domain; domain = container_of(kobj, ec_domain_t, kobj); EC_INFO("Clearing domain %i.\n", domain->index); - list_for_each_entry_safe(command, next, &domain->commands, list) { - ec_command_clear(command); - kfree(command); + list_for_each_entry_safe(datagram, next, &domain->datagrams, list) { + ec_datagram_clear(datagram); + kfree(datagram); } ec_domain_clear_field_regs(domain); @@ -187,30 +187,30 @@ /*****************************************************************************/ /** - Allocates a process data command and appends it to the list. + Allocates a process data datagram and appends it to the list. \return 0 in case of success, else < 0 */ -int ec_domain_add_command(ec_domain_t *domain, /**< EtherCAT domain */ - uint32_t offset, /**< logical offset */ - size_t data_size /**< size of the command data */ - ) -{ - ec_command_t *command; - - if (!(command = kmalloc(sizeof(ec_command_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate domain command!\n"); +int ec_domain_add_datagram(ec_domain_t *domain, /**< EtherCAT domain */ + uint32_t offset, /**< logical offset */ + size_t data_size /**< size of the datagram data */ + ) +{ + ec_datagram_t *datagram; + + if (!(datagram = kmalloc(sizeof(ec_datagram_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate domain datagram!\n"); return -1; } - ec_command_init(command); - - if (ec_command_lrw(command, offset, data_size)) { - kfree(command); + ec_datagram_init(datagram); + + if (ec_datagram_lrw(datagram, offset, data_size)) { + kfree(datagram); return -1; } - list_add_tail(&command->list, &domain->commands); + list_add_tail(&datagram->list, &domain->datagrams); return 0; } @@ -235,7 +235,7 @@ uint32_t field_off, field_off_cmd; uint32_t cmd_offset; size_t cmd_data_size, sync_size; - ec_command_t *command; + ec_datagram_t *datagram; domain->base_address = base_address; @@ -252,8 +252,8 @@ sync_size = ec_slave_calc_sync_size(slave, fmmu->sync); domain->data_size += sync_size; if (cmd_data_size + sync_size > EC_MAX_DATA_SIZE) { - if (ec_domain_add_command(domain, cmd_offset, - cmd_data_size)) return -1; + if (ec_domain_add_datagram(domain, cmd_offset, + cmd_data_size)) return -1; cmd_offset += cmd_data_size; cmd_data_size = 0; cmd_count++; @@ -263,9 +263,9 @@ } } - // allocate last command + // allocate last datagram if (cmd_data_size) { - if (ec_domain_add_command(domain, cmd_offset, cmd_data_size)) + if (ec_domain_add_datagram(domain, cmd_offset, cmd_data_size)) return -1; cmd_count++; } @@ -283,12 +283,12 @@ if (fmmu->domain == domain && fmmu->sync == field_reg->sync) { field_off = fmmu->logical_start_address + field_reg->field_offset; - // search command - list_for_each_entry(command, &domain->commands, list) { - field_off_cmd = field_off - command->address.logical; - if (field_off >= command->address.logical && - field_off_cmd < command->mem_size) { - *field_reg->data_ptr = command->data + field_off_cmd; + // search datagram + list_for_each_entry(datagram, &domain->datagrams, list) { + field_off_cmd = field_off - datagram->address.logical; + if (field_off >= datagram->address.logical && + field_off_cmd < datagram->mem_size) { + *field_reg->data_ptr = datagram->data + field_off_cmd; } } if (!field_reg->data_ptr) { @@ -300,7 +300,7 @@ } } - EC_INFO("Domain %i - Allocated %i bytes in %i command%s\n", + EC_INFO("Domain %i - Allocated %i bytes in %i datagram%s\n", domain->index, domain->data_size, cmd_count, cmd_count == 1 ? "" : "s"); @@ -314,7 +314,7 @@ /** Sets the number of responding slaves and outputs it on demand. This number isn't really the number of responding slaves, but the sum of - the working counters of all domain commands. Some slaves increase the + the working counters of all domain datagrams. Some slaves increase the working counter by 2, some by 1. */ @@ -479,16 +479,16 @@ /*****************************************************************************/ /** - Places all process data commands in the masters command queue. + Places all process data datagrams in the masters datagram queue. \ingroup RealtimeInterface */ void ecrt_domain_queue(ec_domain_t *domain /**< EtherCAT domain */) { - ec_command_t *command; - - list_for_each_entry(command, &domain->commands, list) { - ec_master_queue_command(domain->master, command); + ec_datagram_t *datagram; + + list_for_each_entry(datagram, &domain->datagrams, list) { + ec_master_queue_datagram(domain->master, datagram); } } @@ -502,13 +502,13 @@ void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */) { unsigned int working_counter_sum; - ec_command_t *command; + ec_datagram_t *datagram; working_counter_sum = 0; - list_for_each_entry(command, &domain->commands, list) { - if (command->state == EC_CMD_RECEIVED) { - working_counter_sum += command->working_counter; + list_for_each_entry(datagram, &domain->datagrams, list) { + if (datagram->state == EC_CMD_RECEIVED) { + working_counter_sum += datagram->working_counter; } } @@ -519,16 +519,16 @@ /** Returns the state of a domain. - \return 0 if all commands were received, else -1. + \return 0 if all datagrams were received, else -1. \ingroup RealtimeInterface */ int ecrt_domain_state(ec_domain_t *domain /**< EtherCAT domain */) { - ec_command_t *command; - - list_for_each_entry(command, &domain->commands, list) { - if (command->state != EC_CMD_RECEIVED) return -1; + ec_datagram_t *datagram; + + list_for_each_entry(datagram, &domain->datagrams, list) { + if (datagram->state != EC_CMD_RECEIVED) return -1; } return 0; diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/domain.h --- a/master/domain.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/domain.h Thu Jul 06 08:23:24 2006 +0000 @@ -46,7 +46,7 @@ #include "globals.h" #include "slave.h" -#include "command.h" +#include "datagram.h" /*****************************************************************************/ @@ -68,7 +68,7 @@ /** EtherCAT domain. - Handles the process data and the therefore needed commands of a certain + Handles the process data and the therefore needed datagrams of a certain group of slaves. */ @@ -79,7 +79,7 @@ unsigned int index; /**< domain index (just a number) */ ec_master_t *master; /**< EtherCAT master owning the domain */ size_t data_size; /**< size of the process data */ - struct list_head commands; /**< process data commands */ + struct list_head datagrams; /**< process data datagrams */ uint32_t base_address; /**< logical offset address of the process data */ unsigned int response_count; /**< number of responding slaves */ struct list_head field_regs; /**< data field registrations */ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/ethernet.c --- a/master/ethernet.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/ethernet.c Thu Jul 06 08:23:24 2006 +0000 @@ -87,7 +87,7 @@ int result, i; eoe->slave = NULL; - ec_command_init(&eoe->command); + ec_datagram_init(&eoe->datagram); eoe->state = ec_eoe_state_rx_start; eoe->opened = 0; eoe->rx_skb = NULL; @@ -169,7 +169,7 @@ if (eoe->rx_skb) dev_kfree_skb(eoe->rx_skb); - ec_command_clear(&eoe->command); + ec_datagram_clear(&eoe->datagram); } /*****************************************************************************/ @@ -246,7 +246,7 @@ printk("\n"); #endif - if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->command, + if (!(data = ec_slave_mbox_prepare_send(eoe->slave, &eoe->datagram, 0x02, current_size + 4))) return -1; @@ -257,7 +257,7 @@ (eoe->tx_frame_number & 0x0F) << 12)); memcpy(data + 4, eoe->tx_frame->skb->data + eoe->tx_offset, current_size); - ec_master_queue_command(eoe->slave->master, &eoe->command); + ec_master_queue_datagram(eoe->slave->master, &eoe->datagram); eoe->tx_offset += current_size; eoe->tx_fragment_number++; @@ -312,8 +312,8 @@ /** State: RX_START. - Starts a new receiving sequence by queueing a command that checks the - slave's mailbox for a new EoE command. + Starts a new receiving sequence by queueing a datagram that checks the + slave's mailbox for a new EoE datagram. */ void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */) @@ -321,8 +321,8 @@ if (!eoe->slave->online || !eoe->slave->master->device->link_state) return; - ec_slave_mbox_prepare_check(eoe->slave, &eoe->command); - ec_master_queue_command(eoe->slave->master, &eoe->command); + ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram); + ec_master_queue_datagram(eoe->slave->master, &eoe->datagram); eoe->state = ec_eoe_state_rx_check; } @@ -330,25 +330,25 @@ /** State: RX_CHECK. - Processes the checking command sent in RX_START and issues a receive - command, if new data is available. + Processes the checking datagram sent in RX_START and issues a receive + datagram, if new data is available. */ void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */) { - if (eoe->command.state != EC_CMD_RECEIVED) { + if (eoe->datagram.state != EC_CMD_RECEIVED) { eoe->stats.rx_errors++; eoe->state = ec_eoe_state_tx_start; return; } - if (!ec_slave_mbox_check(&eoe->command)) { + if (!ec_slave_mbox_check(&eoe->datagram)) { eoe->state = ec_eoe_state_tx_start; return; } - ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->command); - ec_master_queue_command(eoe->slave->master, &eoe->command); + ec_slave_mbox_prepare_fetch(eoe->slave, &eoe->datagram); + ec_master_queue_datagram(eoe->slave->master, &eoe->datagram); eoe->state = ec_eoe_state_rx_fetch; } @@ -357,7 +357,7 @@ /** State: RX_FETCH. Checks if the requested data of RX_CHECK was received and processes the - EoE command. + EoE datagram. */ void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */) @@ -367,13 +367,13 @@ uint8_t frame_number, fragment_offset, fragment_number; off_t offset; - if (eoe->command.state != EC_CMD_RECEIVED) { + if (eoe->datagram.state != EC_CMD_RECEIVED) { eoe->stats.rx_errors++; eoe->state = ec_eoe_state_tx_start; return; } - if (!(data = ec_slave_mbox_fetch(eoe->slave, &eoe->command, + if (!(data = ec_slave_mbox_fetch(eoe->slave, &eoe->datagram, 0x02, &rec_size))) { eoe->stats.rx_errors++; eoe->state = ec_eoe_state_tx_start; @@ -560,19 +560,19 @@ /** State: TX SENT. - Checks is the previous transmit command succeded and sends the next + Checks is the previous transmit datagram succeded and sends the next fragment, if necessary. */ void ec_eoe_state_tx_sent(ec_eoe_t *eoe /**< EoE handler */) { - if (eoe->command.state != EC_CMD_RECEIVED) { + if (eoe->datagram.state != EC_CMD_RECEIVED) { eoe->stats.tx_errors++; eoe->state = ec_eoe_state_rx_start; return; } - if (eoe->command.working_counter != 1) { + if (eoe->datagram.working_counter != 1) { eoe->stats.tx_errors++; eoe->state = ec_eoe_state_rx_start; return; diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/ethernet.h --- a/master/ethernet.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/ethernet.h Thu Jul 06 08:23:24 2006 +0000 @@ -44,7 +44,7 @@ #include "../include/ecrt.h" #include "globals.h" #include "slave.h" -#include "command.h" +#include "datagram.h" /*****************************************************************************/ @@ -73,7 +73,7 @@ { struct list_head list; /**< list item */ ec_slave_t *slave; /**< pointer to the corresponding slave */ - ec_command_t command; /**< command */ + ec_datagram_t datagram; /**< datagram */ void (*state)(ec_eoe_t *); /**< state function for the state machine */ struct net_device *dev; /**< net_device for virtual ethernet device */ struct net_device_stats stats; /**< device statistics */ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/fsm.c --- a/master/fsm.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/fsm.c Thu Jul 06 08:23:24 2006 +0000 @@ -107,9 +107,9 @@ fsm->master_slave_states = EC_SLAVE_STATE_UNKNOWN; fsm->master_validation = 0; - ec_command_init(&fsm->command); - if (ec_command_prealloc(&fsm->command, EC_MAX_DATA_SIZE)) { - EC_ERR("Failed to allocate FSM command.\n"); + ec_datagram_init(&fsm->datagram); + if (ec_datagram_prealloc(&fsm->datagram, EC_MAX_DATA_SIZE)) { + EC_ERR("Failed to allocate FSM datagram.\n"); return -1; } @@ -124,7 +124,7 @@ void ec_fsm_clear(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_clear(&fsm->command); + ec_datagram_clear(&fsm->datagram); } /*****************************************************************************/ @@ -162,8 +162,8 @@ void ec_fsm_master_start(ec_fsm_t *fsm) { - ec_command_brd(&fsm->command, 0x0130, 2); - ec_master_queue_command(fsm->master, &fsm->command); + ec_datagram_brd(&fsm->datagram, 0x0130, 2); + ec_master_queue_datagram(fsm->master, &fsm->datagram); fsm->master_state = ec_fsm_master_broadcast; } @@ -176,12 +176,12 @@ void ec_fsm_master_broadcast(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; unsigned int topology_change, states_change, i; ec_slave_t *slave; ec_master_t *master = fsm->master; - if (command->state != EC_CMD_RECEIVED) { + if (datagram->state != EC_CMD_RECEIVED) { if (!master->device->link_state) { fsm->master_slaves_responding = 0; list_for_each_entry(slave, &master->slaves, list) { @@ -193,12 +193,12 @@ return; } - topology_change = (command->working_counter != + topology_change = (datagram->working_counter != fsm->master_slaves_responding); - states_change = (EC_READ_U8(command->data) != fsm->master_slave_states); - - fsm->master_slave_states = EC_READ_U8(command->data); - fsm->master_slaves_responding = command->working_counter; + states_change = (EC_READ_U8(datagram->data) != fsm->master_slave_states); + + fsm->master_slave_states = EC_READ_U8(datagram->data); + fsm->master_slaves_responding = datagram->working_counter; if (topology_change) { EC_INFO("%i slave%s responding.\n", @@ -272,8 +272,8 @@ // fetch state from each slave fsm->slave = list_entry(master->slaves.next, ec_slave_t, list); - ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2); - ec_master_queue_command(master, &fsm->command); + ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, 0x0130, 2); + ec_master_queue_datagram(master, &fsm->datagram); fsm->master_state = ec_fsm_master_states; } @@ -293,8 +293,9 @@ if (slave->list.next != &master->slaves) { // process next slave fsm->slave = list_entry(fsm->slave->list.next, ec_slave_t, list); - ec_command_nprd(&fsm->command, fsm->slave->station_address, 0x0130, 2); - ec_master_queue_command(master, &fsm->command); + ec_datagram_nprd(&fsm->datagram, fsm->slave->station_address, + 0x0130, 2); + ec_master_queue_datagram(master, &fsm->datagram); fsm->master_state = ec_fsm_master_states; return; } @@ -331,17 +332,17 @@ void ec_fsm_master_states(ec_fsm_t *fsm /**< finite state machine */) { ec_slave_t *slave = fsm->slave; - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; uint8_t new_state; - if (command->state != EC_CMD_RECEIVED) { + if (datagram->state != EC_CMD_RECEIVED) { fsm->master_state = ec_fsm_master_start; fsm->master_state(fsm); // execute immediately return; } // did the slave not respond to its station address? - if (command->working_counter != 1) { + if (datagram->working_counter != 1) { if (slave->online) { slave->online = 0; EC_INFO("Slave %i: offline.\n", slave->ring_position); @@ -351,7 +352,7 @@ } // slave responded - new_state = EC_READ_U8(command->data); + new_state = EC_READ_U8(datagram->data); if (!slave->online) { // slave was offline before slave->online = 1; slave->error_flag = 0; // clear error flag @@ -535,7 +536,7 @@ void ec_fsm_master_reconfigure(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; while (fsm->slave->online) { if (fsm->slave->list.next == &fsm->master->slaves) { // last slave? @@ -550,9 +551,9 @@ EC_INFO("Reinitializing slave %i.\n", fsm->slave->ring_position); // write station address - ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2); - EC_WRITE_U16(command->data, fsm->slave->station_address); - ec_master_queue_command(fsm->master, command); + ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2); + EC_WRITE_U16(datagram->data, fsm->slave->station_address); + ec_master_queue_datagram(fsm->master, datagram); fsm->master_state = ec_fsm_master_address; } @@ -566,9 +567,9 @@ void ec_fsm_master_address(ec_fsm_t *fsm /**< finite state machine */) { ec_slave_t *slave = fsm->slave; - ec_command_t *command = &fsm->command; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { EC_ERR("Failed to write station address on slave %i.\n", slave->ring_position); } @@ -752,12 +753,12 @@ void ec_fsm_slave_start_reading(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; // write station address - ec_command_apwr(command, fsm->slave->ring_position, 0x0010, 2); - EC_WRITE_U16(command->data, fsm->slave->station_address); - ec_master_queue_command(fsm->master, command); + ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x0010, 2); + EC_WRITE_U16(datagram->data, fsm->slave->station_address); + ec_master_queue_datagram(fsm->master, datagram); fsm->slave_state = ec_fsm_slave_read_state; } @@ -769,9 +770,9 @@ void ec_fsm_slave_read_state(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to write station address of slave %i.\n", @@ -780,8 +781,8 @@ } // Read AL state - ec_command_nprd(command, fsm->slave->station_address, 0x0130, 2); - ec_master_queue_command(fsm->master, command); + ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0130, 2); + ec_master_queue_datagram(fsm->master, datagram); fsm->slave_state = ec_fsm_slave_read_base; } @@ -793,10 +794,10 @@ void ec_fsm_slave_read_base(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to read AL state of slave %i.\n", @@ -804,7 +805,7 @@ return; } - slave->current_state = EC_READ_U8(command->data); + slave->current_state = EC_READ_U8(datagram->data); if (slave->current_state & EC_ACK) { EC_WARN("Slave %i has state error bit set (0x%02X)!\n", slave->ring_position, slave->current_state); @@ -812,8 +813,8 @@ } // read base data - ec_command_nprd(command, fsm->slave->station_address, 0x0000, 6); - ec_master_queue_command(fsm->master, command); + ec_datagram_nprd(datagram, fsm->slave->station_address, 0x0000, 6); + ec_master_queue_datagram(fsm->master, datagram); fsm->slave_state = ec_fsm_slave_read_dl; } @@ -825,10 +826,10 @@ void ec_fsm_slave_read_dl(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to read base data of slave %i.\n", @@ -836,18 +837,18 @@ return; } - slave->base_type = EC_READ_U8 (command->data); - slave->base_revision = EC_READ_U8 (command->data + 1); - slave->base_build = EC_READ_U16(command->data + 2); - slave->base_fmmu_count = EC_READ_U8 (command->data + 4); - slave->base_sync_count = EC_READ_U8 (command->data + 5); + slave->base_type = EC_READ_U8 (datagram->data); + slave->base_revision = EC_READ_U8 (datagram->data + 1); + slave->base_build = EC_READ_U16(datagram->data + 2); + slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4); + slave->base_sync_count = EC_READ_U8 (datagram->data + 5); if (slave->base_fmmu_count > EC_MAX_FMMUS) slave->base_fmmu_count = EC_MAX_FMMUS; // read data link status - ec_command_nprd(command, slave->station_address, 0x0110, 2); - ec_master_queue_command(slave->master, command); + ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2); + ec_master_queue_datagram(slave->master, datagram); fsm->slave_state = ec_fsm_slave_eeprom_size; } @@ -860,12 +861,12 @@ void ec_fsm_slave_eeprom_size(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; ec_slave_t *slave = fsm->slave; uint16_t dl_status; unsigned int i; - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to read DL status of slave %i.\n", @@ -873,7 +874,7 @@ return; } - dl_status = EC_READ_U16(command->data); + dl_status = EC_READ_U16(datagram->data); for (i = 0; i < 4; i++) { slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0; slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0; @@ -1068,7 +1069,7 @@ { ec_slave_t *slave = fsm->slave; ec_master_t *master = fsm->master; - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; fsm->change_state(fsm); // execute state change state machine @@ -1101,10 +1102,10 @@ } // reset FMMUs - ec_command_npwr(command, slave->station_address, 0x0600, - EC_FMMU_SIZE * slave->base_fmmu_count); - memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); - ec_master_queue_command(master, command); + ec_datagram_npwr(datagram, slave->station_address, 0x0600, + EC_FMMU_SIZE * slave->base_fmmu_count); + memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); + ec_master_queue_datagram(master, datagram); fsm->slave_state = ec_fsm_slave_sync; } @@ -1117,13 +1118,13 @@ void ec_fsm_slave_sync(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; ec_slave_t *slave = fsm->slave; unsigned int j; const ec_sync_t *sync; ec_eeprom_sync_t *eeprom_sync, mbox_sync; - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to reset FMMUs of slave %i.\n", @@ -1138,15 +1139,15 @@ } // configure sync managers - ec_command_npwr(command, slave->station_address, 0x0800, - EC_SYNC_SIZE * slave->base_sync_count); - memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); + ec_datagram_npwr(datagram, slave->station_address, 0x0800, + EC_SYNC_SIZE * slave->base_sync_count); + memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); // known slave type, take type's SM information if (slave->type) { for (j = 0; slave->type->sync_managers[j] && j < EC_MAX_SYNC; j++) { sync = slave->type->sync_managers[j]; - ec_sync_config(sync, slave, command->data + EC_SYNC_SIZE * j); + ec_sync_config(sync, slave, datagram->data + EC_SYNC_SIZE * j); } } @@ -1163,7 +1164,7 @@ return; } ec_eeprom_sync_config(eeprom_sync, - command->data + EC_SYNC_SIZE + datagram->data + EC_SYNC_SIZE * eeprom_sync->index); } } @@ -1175,7 +1176,7 @@ mbox_sync.length = slave->sii_rx_mailbox_size; mbox_sync.control_register = 0x26; mbox_sync.enable = 1; - ec_eeprom_sync_config(&mbox_sync, command->data); + ec_eeprom_sync_config(&mbox_sync, datagram->data); mbox_sync.physical_start_address = slave->sii_tx_mailbox_offset; @@ -1183,14 +1184,14 @@ mbox_sync.control_register = 0x22; mbox_sync.enable = 1; ec_eeprom_sync_config(&mbox_sync, - command->data + EC_SYNC_SIZE); + datagram->data + EC_SYNC_SIZE); } EC_INFO("Mailbox configured for unknown slave %i\n", slave->ring_position); } - ec_master_queue_command(fsm->master, command); + ec_master_queue_datagram(fsm->master, datagram); fsm->slave_state = ec_fsm_slave_preop; } @@ -1203,10 +1204,10 @@ void ec_fsm_slave_preop(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to set sync managers on slave %i.\n", @@ -1231,7 +1232,7 @@ { ec_slave_t *slave = fsm->slave; ec_master_t *master = fsm->master; - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; unsigned int j; fsm->change_state(fsm); // execute state change state machine @@ -1263,15 +1264,15 @@ } // configure FMMUs - ec_command_npwr(command, slave->station_address, - 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); - memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); + ec_datagram_npwr(datagram, slave->station_address, + 0x0600, EC_FMMU_SIZE * slave->base_fmmu_count); + memset(datagram->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); for (j = 0; j < slave->fmmu_count; j++) { ec_fmmu_config(&slave->fmmus[j], slave, - command->data + EC_FMMU_SIZE * j); - } - - ec_master_queue_command(master, command); + datagram->data + EC_FMMU_SIZE * j); + } + + ec_master_queue_datagram(master, datagram); fsm->slave_state = ec_fsm_slave_saveop; } @@ -1284,10 +1285,10 @@ void ec_fsm_slave_saveop(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - - if (fsm->slave->base_fmmu_count && (command->state != EC_CMD_RECEIVED || - command->working_counter != 1)) { + ec_datagram_t *datagram = &fsm->datagram; + + if (fsm->slave->base_fmmu_count && (datagram->state != EC_CMD_RECEIVED || + datagram->working_counter != 1)) { fsm->slave->error_flag = 1; fsm->slave_state = ec_fsm_slave_end; EC_ERR("Failed to set FMMUs on slave %i.\n", @@ -1379,20 +1380,20 @@ void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; // initiate read operation if (fsm->sii_mode) { - ec_command_npwr(command, fsm->slave->station_address, 0x502, 4); + ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 4); } else { - ec_command_apwr(command, fsm->slave->ring_position, 0x502, 4); - } - - EC_WRITE_U8 (command->data, 0x00); // read-only access - EC_WRITE_U8 (command->data + 1, 0x01); // request read operation - EC_WRITE_U16(command->data + 2, fsm->sii_offset); - ec_master_queue_command(fsm->master, command); + ec_datagram_apwr(datagram, fsm->slave->ring_position, 0x502, 4); + } + + EC_WRITE_U8 (datagram->data, 0x00); // read-only access + EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation + EC_WRITE_U16(datagram->data + 2, fsm->sii_offset); + ec_master_queue_datagram(fsm->master, datagram); fsm->sii_state = ec_fsm_sii_read_check; } @@ -1400,30 +1401,30 @@ /** SII state: READ_CHECK. - Checks, if the SII-read-command has been sent and issues a fetch command. + Checks, if the SII-read-datagram has been sent and issues a fetch datagram. */ void ec_fsm_sii_read_check(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { - EC_ERR("SII: Reception of read command failed.\n"); + ec_datagram_t *datagram = &fsm->datagram; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { + EC_ERR("SII: Reception of read datagram failed.\n"); fsm->sii_state = ec_fsm_sii_error; return; } fsm->sii_start = get_cycles(); - // issue check/fetch command + // issue check/fetch datagram if (fsm->sii_mode) { - ec_command_nprd(command, fsm->slave->station_address, 0x502, 10); + ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10); } else { - ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10); - } - - ec_master_queue_command(fsm->master, command); + ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10); + } + + ec_master_queue_datagram(fsm->master, datagram); fsm->sii_state = ec_fsm_sii_read_fetch; } @@ -1431,55 +1432,55 @@ /** SII state: READ_FETCH. - Fetches the result of an SII-read command. + Fetches the result of an SII-read datagram. */ void ec_fsm_sii_read_fetch(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { - EC_ERR("SII: Reception of check/fetch command failed.\n"); + ec_datagram_t *datagram = &fsm->datagram; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { + EC_ERR("SII: Reception of check/fetch datagram failed.\n"); fsm->sii_state = ec_fsm_sii_error; return; } // check "busy bit" - if (EC_READ_U8(command->data + 1) & 0x81) { + if (EC_READ_U8(datagram->data + 1) & 0x81) { // still busy... timeout? if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) { EC_ERR("SII: Timeout.\n"); fsm->sii_state = ec_fsm_sii_error; #if 0 EC_DBG("SII busy: %02X %02X %02X %02X\n", - EC_READ_U8(command->data + 0), - EC_READ_U8(command->data + 1), - EC_READ_U8(command->data + 2), - EC_READ_U8(command->data + 3)); + EC_READ_U8(datagram->data + 0), + EC_READ_U8(datagram->data + 1), + EC_READ_U8(datagram->data + 2), + EC_READ_U8(datagram->data + 3)); #endif } - // issue check/fetch command again + // issue check/fetch datagram again if (fsm->sii_mode) { - ec_command_nprd(command, fsm->slave->station_address, 0x502, 10); + ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 10); } else { - ec_command_aprd(command, fsm->slave->ring_position, 0x502, 10); + ec_datagram_aprd(datagram, fsm->slave->ring_position, 0x502, 10); } - ec_master_queue_command(fsm->master, command); + ec_master_queue_datagram(fsm->master, datagram); return; } #if 0 EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n", - EC_READ_U8(command->data + 0), EC_READ_U8(command->data + 1), - EC_READ_U8(command->data + 2), EC_READ_U8(command->data + 3), - EC_READ_U8(command->data + 6), EC_READ_U8(command->data + 7), - EC_READ_U8(command->data + 8), EC_READ_U8(command->data + 9)); + EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1), + EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3), + EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7), + EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9)); #endif // SII value received. - memcpy(fsm->sii_value, command->data + 6, 4); + memcpy(fsm->sii_value, datagram->data + 6, 4); fsm->sii_state = ec_fsm_sii_end; } @@ -1492,15 +1493,15 @@ void ec_fsm_sii_start_writing(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; // initiate write operation - ec_command_npwr(command, fsm->slave->station_address, 0x502, 8); - EC_WRITE_U8 (command->data, 0x01); // enable write access - EC_WRITE_U8 (command->data + 1, 0x02); // request write operation - EC_WRITE_U32(command->data + 2, fsm->sii_offset); - memcpy(command->data + 6, fsm->sii_value, 2); - ec_master_queue_command(fsm->master, command); + ec_datagram_npwr(datagram, fsm->slave->station_address, 0x502, 8); + EC_WRITE_U8 (datagram->data, 0x01); // enable write access + EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation + EC_WRITE_U32(datagram->data + 2, fsm->sii_offset); + memcpy(datagram->data + 6, fsm->sii_value, 2); + ec_master_queue_datagram(fsm->master, datagram); fsm->sii_state = ec_fsm_sii_write_check; } @@ -1512,19 +1513,19 @@ void ec_fsm_sii_write_check(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { - EC_ERR("SII: Reception of write command failed.\n"); + ec_datagram_t *datagram = &fsm->datagram; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { + EC_ERR("SII: Reception of write datagram failed.\n"); fsm->sii_state = ec_fsm_sii_error; return; } fsm->sii_start = get_cycles(); - // issue check/fetch command - ec_command_nprd(command, fsm->slave->station_address, 0x502, 2); - ec_master_queue_command(fsm->master, command); + // issue check/fetch datagram + ec_datagram_nprd(datagram, fsm->slave->station_address, 0x502, 2); + ec_master_queue_datagram(fsm->master, datagram); fsm->sii_state = ec_fsm_sii_write_check2; } @@ -1536,25 +1537,25 @@ void ec_fsm_sii_write_check2(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { - EC_ERR("SII: Reception of write check command failed.\n"); + ec_datagram_t *datagram = &fsm->datagram; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { + EC_ERR("SII: Reception of write check datagram failed.\n"); fsm->sii_state = ec_fsm_sii_error; return; } - if (EC_READ_U8(command->data + 1) & 0x82) { + if (EC_READ_U8(datagram->data + 1) & 0x82) { // still busy... timeout? if (get_cycles() - fsm->sii_start >= (cycles_t) 10 * cpu_khz) { EC_ERR("SII: Write timeout.\n"); fsm->sii_state = ec_fsm_sii_error; } - // issue check/fetch command again - ec_master_queue_command(fsm->master, command); - } - else if (EC_READ_U8(command->data + 1) & 0x40) { + // issue check/fetch datagram again + ec_master_queue_datagram(fsm->master, datagram); + } + else if (EC_READ_U8(datagram->data + 1) & 0x40) { EC_ERR("SII: Write operation failed!\n"); fsm->sii_state = ec_fsm_sii_error; } @@ -1595,13 +1596,13 @@ void ec_fsm_change_start(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; ec_slave_t *slave = fsm->slave; // write new state to slave - ec_command_npwr(command, slave->station_address, 0x0120, 2); - EC_WRITE_U16(command->data, fsm->change_new); - ec_master_queue_command(fsm->master, command); + ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); + EC_WRITE_U16(datagram->data, fsm->change_new); + ec_master_queue_datagram(fsm->master, datagram); fsm->change_state = ec_fsm_change_check; } @@ -1613,17 +1614,17 @@ void ec_fsm_change_check(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED) { fsm->change_state = ec_fsm_change_error; - EC_ERR("Failed to send state command to slave %i!\n", + EC_ERR("Failed to send state datagram to slave %i!\n", fsm->slave->ring_position); return; } - if (command->working_counter != 1) { + if (datagram->working_counter != 1) { fsm->change_state = ec_fsm_change_error; EC_ERR("Failed to set state 0x%02X on slave %i: Slave did not" " respond.\n", fsm->change_new, fsm->slave->ring_position); @@ -1633,8 +1634,8 @@ fsm->change_start = get_cycles(); // read AL status from slave - ec_command_nprd(command, slave->station_address, 0x0130, 2); - ec_master_queue_command(fsm->master, command); + ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); + ec_master_queue_datagram(fsm->master, datagram); fsm->change_state = ec_fsm_change_status; } @@ -1646,17 +1647,17 @@ void ec_fsm_change_status(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->change_state = ec_fsm_change_error; EC_ERR("Failed to check state 0x%02X on slave %i.\n", fsm->change_new, slave->ring_position); return; } - slave->current_state = EC_READ_U8(command->data); + slave->current_state = EC_READ_U8(datagram->data); if (slave->current_state == fsm->change_new) { // state has been set successfully @@ -1671,8 +1672,8 @@ " (code 0x%02X)!\n", fsm->change_new, slave->ring_position, slave->current_state); // fetch AL status error code - ec_command_nprd(command, slave->station_address, 0x0134, 2); - ec_master_queue_command(fsm->master, command); + ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2); + ec_master_queue_datagram(fsm->master, datagram); fsm->change_state = ec_fsm_change_code; return; } @@ -1686,8 +1687,8 @@ } // still old state: check again - ec_command_nprd(command, slave->station_address, 0x0130, 2); - ec_master_queue_command(fsm->master, command); + ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); + ec_master_queue_datagram(fsm->master, datagram); } /*****************************************************************************/ @@ -1724,18 +1725,18 @@ void ec_fsm_change_code(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; + ec_datagram_t *datagram = &fsm->datagram; ec_slave_t *slave = fsm->slave; uint32_t code; const ec_code_msg_t *al_msg; - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->change_state = ec_fsm_change_error; - EC_ERR("Reception of AL status code command failed.\n"); - return; - } - - if ((code = EC_READ_U16(command->data))) { + EC_ERR("Reception of AL status code datagram failed.\n"); + return; + } + + if ((code = EC_READ_U16(datagram->data))) { for (al_msg = al_status_messages; al_msg->code; al_msg++) { if (al_msg->code != code) continue; EC_ERR("AL status message 0x%04X: \"%s\".\n", @@ -1747,9 +1748,9 @@ } // acknowledge "old" slave state - ec_command_npwr(command, slave->station_address, 0x0120, 2); - EC_WRITE_U16(command->data, slave->current_state); - ec_master_queue_command(fsm->master, command); + ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2); + EC_WRITE_U16(datagram->data, slave->current_state); + ec_master_queue_datagram(fsm->master, datagram); fsm->change_state = ec_fsm_change_ack; } @@ -1761,18 +1762,18 @@ void ec_fsm_change_ack(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->change_state = ec_fsm_change_error; - EC_ERR("Reception of state ack command failed.\n"); + EC_ERR("Reception of state ack datagram failed.\n"); return; } // read new AL status - ec_command_nprd(command, slave->station_address, 0x0130, 2); - ec_master_queue_command(fsm->master, command); + ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2); + ec_master_queue_datagram(fsm->master, datagram); fsm->change_state = ec_fsm_change_ack2; } @@ -1785,16 +1786,16 @@ void ec_fsm_change_ack2(ec_fsm_t *fsm /**< finite state machine */) { - ec_command_t *command = &fsm->command; - ec_slave_t *slave = fsm->slave; - - if (command->state != EC_CMD_RECEIVED || command->working_counter != 1) { + ec_datagram_t *datagram = &fsm->datagram; + ec_slave_t *slave = fsm->slave; + + if (datagram->state != EC_CMD_RECEIVED || datagram->working_counter != 1) { fsm->change_state = ec_fsm_change_error; - EC_ERR("Reception of state ack check command failed.\n"); - return; - } - - slave->current_state = EC_READ_U8(command->data); + EC_ERR("Reception of state ack check datagram failed.\n"); + return; + } + + slave->current_state = EC_READ_U8(datagram->data); if (slave->current_state == fsm->change_new) { fsm->change_state = ec_fsm_change_error; diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/fsm.h --- a/master/fsm.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/fsm.h Thu Jul 06 08:23:24 2006 +0000 @@ -42,7 +42,7 @@ #define __EC_STATES__ #include "../include/ecrt.h" -#include "command.h" +#include "datagram.h" #include "slave.h" /*****************************************************************************/ @@ -57,7 +57,7 @@ { ec_master_t *master; /**< master the FSM runs on */ ec_slave_t *slave; /**< slave the FSM runs on */ - ec_command_t command; /**< command used in the state machine */ + ec_datagram_t datagram; /**< datagram used in the state machine */ void (*master_state)(ec_fsm_t *); /**< master state function */ unsigned int master_slaves_responding; /**< number of responding slaves */ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/globals.h --- a/master/globals.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/globals.h Thu Jul 06 08:23:24 2006 +0000 @@ -72,11 +72,11 @@ /** size of an EtherCAT frame header */ #define EC_FRAME_HEADER_SIZE 2 -/** size of an EtherCAT command header */ -#define EC_COMMAND_HEADER_SIZE 10 +/** size of an EtherCAT datagram header */ +#define EC_DATAGRAM_HEADER_SIZE 10 -/** size of an EtherCAT command footer */ -#define EC_COMMAND_FOOTER_SIZE 2 +/** size of an EtherCAT datagram footer */ +#define EC_DATAGRAM_FOOTER_SIZE 2 /** size of a sync manager configuration page */ #define EC_SYNC_SIZE 8 @@ -84,9 +84,9 @@ /** size of an FMMU configuration page */ #define EC_FMMU_SIZE 16 -/** resulting maximum data size of a single command in a frame */ +/** resulting maximum data size of a single datagram in a frame */ #define EC_MAX_DATA_SIZE (ETH_DATA_LEN - EC_FRAME_HEADER_SIZE \ - - EC_COMMAND_HEADER_SIZE - EC_COMMAND_FOOTER_SIZE) + - EC_DATAGRAM_HEADER_SIZE - EC_DATAGRAM_FOOTER_SIZE) /*****************************************************************************/ @@ -178,7 +178,7 @@ /** Code - Message pair. - Some EtherCAT commands support reading a status code to display a certain + Some EtherCAT datagrams support reading a status code to display a certain message. This type allows to map a code to a message string. */ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/mailbox.c --- a/master/mailbox.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/mailbox.c Thu Jul 06 08:23:24 2006 +0000 @@ -42,18 +42,18 @@ #include #include "mailbox.h" -#include "command.h" +#include "datagram.h" #include "master.h" /*****************************************************************************/ /** - Prepares a mailbox-send command. - \return pointer to mailbox command data + Prepares a mailbox-send datagram. + \return pointer to mailbox datagram data */ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */ - ec_command_t *command, /**< command */ + ec_datagram_t *datagram, /**< datagram */ uint8_t type, /**< mailbox protocol */ size_t size /**< size of the data */ ) @@ -72,32 +72,32 @@ return NULL; } - if (ec_command_npwr(command, slave->station_address, - slave->sii_rx_mailbox_offset, - slave->sii_rx_mailbox_size)) - return NULL; - - EC_WRITE_U16(command->data, size); // mailbox service data length - EC_WRITE_U16(command->data + 2, slave->station_address); // station address - EC_WRITE_U8 (command->data + 4, 0x00); // channel & priority - EC_WRITE_U8 (command->data + 5, type); // underlying protocol type - - return command->data + 6; -} - -/*****************************************************************************/ - -/** - Prepares a command for checking the mailbox state. + if (ec_datagram_npwr(datagram, slave->station_address, + slave->sii_rx_mailbox_offset, + slave->sii_rx_mailbox_size)) + return NULL; + + EC_WRITE_U16(datagram->data, size); // mailbox service data length + EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr. + EC_WRITE_U8 (datagram->data + 4, 0x00); // channel & priority + EC_WRITE_U8 (datagram->data + 5, type); // underlying protocol type + + return datagram->data + 6; +} + +/*****************************************************************************/ + +/** + Prepares a datagram for checking the mailbox state. \return 0 in case of success, else < 0 */ int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */ - ec_command_t *command /**< command */ + ec_datagram_t *datagram /**< datagram */ ) { // FIXME: second sync manager? - if (ec_command_nprd(command, slave->station_address, 0x808, 8)) + if (ec_datagram_nprd(datagram, slave->station_address, 0x808, 8)) return -1; return 0; @@ -106,29 +106,29 @@ /*****************************************************************************/ /** - Processes a mailbox state checking command. + Processes a mailbox state checking datagram. \return 0 in case of success, else < 0 */ -int ec_slave_mbox_check(const ec_command_t *command /**< command */) -{ - return EC_READ_U8(command->data + 5) & 8 ? 1 : 0; -} - -/*****************************************************************************/ - -/** - Prepares a command to fetch mailbox data. +int ec_slave_mbox_check(const ec_datagram_t *datagram /**< datagram */) +{ + return EC_READ_U8(datagram->data + 5) & 8 ? 1 : 0; +} + +/*****************************************************************************/ + +/** + Prepares a datagram to fetch mailbox data. \return 0 in case of success, else < 0 */ int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */ - ec_command_t *command /**< command */ + ec_datagram_t *datagram /**< datagram */ ) { - if (ec_command_nprd(command, slave->station_address, - slave->sii_tx_mailbox_offset, - slave->sii_tx_mailbox_size)) return -1; + if (ec_datagram_nprd(datagram, slave->station_address, + slave->sii_tx_mailbox_offset, + slave->sii_tx_mailbox_size)) return -1; return 0; } @@ -140,64 +140,64 @@ */ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */ - ec_command_t *command, /**< command */ + ec_datagram_t *datagram, /**< datagram */ uint8_t type, /**< expected mailbox protocol */ size_t *size /**< size of the received data */ ) { size_t data_size; - if ((EC_READ_U8(command->data + 5) & 0x0F) != type) { + if ((EC_READ_U8(datagram->data + 5) & 0x0F) != type) { EC_ERR("Unexpected mailbox protocol 0x%02X (exp.: 0x%02X) at" - " slave %i!\n", EC_READ_U8(command->data + 5), type, - slave->ring_position); - return NULL; - } - - if ((data_size = EC_READ_U16(command->data)) > + " slave %i!\n", EC_READ_U8(datagram->data + 5), type, + slave->ring_position); + return NULL; + } + + if ((data_size = EC_READ_U16(datagram->data)) > slave->sii_tx_mailbox_size - 6) { EC_ERR("Currupt mailbox response detected!\n"); return NULL; } *size = data_size; - return command->data + 6; -} - -/*****************************************************************************/ - -/** - Sends a mailbox command and waits for its reception. + return datagram->data + 6; +} + +/*****************************************************************************/ + +/** + Sends a mailbox datagram and waits for its reception. \return pointer to the received data */ uint8_t *ec_slave_mbox_simple_io(const ec_slave_t *slave, /**< slave */ - ec_command_t *command, /**< command */ + ec_datagram_t *datagram, /**< datagram */ size_t *size /**< size of the received data */ ) { uint8_t type; - type = EC_READ_U8(command->data + 5); - - if (unlikely(ec_master_simple_io(slave->master, command))) { + type = EC_READ_U8(datagram->data + 5); + + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position); return NULL; } - return ec_slave_mbox_simple_receive(slave, command, type, size); -} - -/*****************************************************************************/ - -/** - Waits for the reception of a mailbox command. + return ec_slave_mbox_simple_receive(slave, datagram, type, size); +} + +/*****************************************************************************/ + +/** + Waits for the reception of a mailbox datagram. \return pointer to the received data */ uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */ - ec_command_t *command, /**< command */ + ec_datagram_t *datagram, /**< datagram */ uint8_t type, /**< expected protocol */ size_t *size /**< received data size */ ) @@ -209,8 +209,8 @@ while (1) { - if (ec_slave_mbox_prepare_check(slave, command)) return NULL; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_slave_mbox_prepare_check(slave, datagram)) return NULL; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position); return NULL; @@ -218,7 +218,7 @@ end = get_cycles(); - if (ec_slave_mbox_check(command)) + if (ec_slave_mbox_check(datagram)) break; // proceed with receiving data if ((end - start) >= timeout) { @@ -230,8 +230,8 @@ udelay(100); } - if (ec_slave_mbox_prepare_fetch(slave, command)) return NULL; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_slave_mbox_prepare_fetch(slave, datagram)) return NULL; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Mailbox receiving failed on slave %i!\n", slave->ring_position); return NULL; @@ -241,7 +241,7 @@ EC_DBG("Mailbox receive took %ius.\n", ((u32) (end - start) * 1000 / cpu_khz)); - return ec_slave_mbox_fetch(slave, command, type, size); -} - -/*****************************************************************************/ + return ec_slave_mbox_fetch(slave, datagram, type, size); +} + +/*****************************************************************************/ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/mailbox.h --- a/master/mailbox.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/mailbox.h Thu Jul 06 08:23:24 2006 +0000 @@ -45,16 +45,17 @@ /*****************************************************************************/ -uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *, ec_command_t *, +uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *, ec_datagram_t *, uint8_t, size_t); -int ec_slave_mbox_prepare_check(const ec_slave_t *, ec_command_t *); -int ec_slave_mbox_check(const ec_command_t *); -int ec_slave_mbox_prepare_fetch(const ec_slave_t *, ec_command_t *); -uint8_t *ec_slave_mbox_fetch(const ec_slave_t *, ec_command_t *, +int ec_slave_mbox_prepare_check(const ec_slave_t *, ec_datagram_t *); +int ec_slave_mbox_check(const ec_datagram_t *); +int ec_slave_mbox_prepare_fetch(const ec_slave_t *, ec_datagram_t *); +uint8_t *ec_slave_mbox_fetch(const ec_slave_t *, ec_datagram_t *, uint8_t, size_t *); -uint8_t *ec_slave_mbox_simple_io(const ec_slave_t *, ec_command_t *, size_t *); -uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *, ec_command_t *, +uint8_t *ec_slave_mbox_simple_io(const ec_slave_t *, ec_datagram_t *, + size_t *); +uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *, ec_datagram_t *, uint8_t, size_t *); /*****************************************************************************/ diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/master.c --- a/master/master.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/master.c Thu Jul 06 08:23:24 2006 +0000 @@ -50,7 +50,7 @@ #include "slave.h" #include "types.h" #include "device.h" -#include "command.h" +#include "datagram.h" #include "ethernet.h" /*****************************************************************************/ @@ -110,10 +110,10 @@ master->device = NULL; master->reserved = 0; INIT_LIST_HEAD(&master->slaves); - INIT_LIST_HEAD(&master->command_queue); + INIT_LIST_HEAD(&master->datagram_queue); INIT_LIST_HEAD(&master->domains); INIT_LIST_HEAD(&master->eoe_handlers); - ec_command_init(&master->simple_command); + ec_datagram_init(&master->simple_datagram); INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master); init_timer(&master->eoe_timer); master->eoe_timer.function = ec_master_eoe_run; @@ -171,7 +171,7 @@ /** Master destructor. - Removes all pending commands, clears the slave list, clears all domains + Removes all pending datagrams, clears the slave list, clears all domains and frees the device. */ @@ -184,7 +184,7 @@ ec_master_reset(master); ec_fsm_clear(&master->fsm); - ec_command_clear(&master->simple_command); + ec_datagram_clear(&master->simple_datagram); destroy_workqueue(master->workqueue); // clear EoE objects @@ -212,17 +212,18 @@ void ec_master_reset(ec_master_t *master /**< EtherCAT master */) { - ec_command_t *command, *next_c; + ec_datagram_t *datagram, *next_c; ec_domain_t *domain, *next_d; ec_master_eoe_stop(master); ec_master_freerun_stop(master); ec_master_clear_slaves(master); - // empty command queue - list_for_each_entry_safe(command, next_c, &master->command_queue, queue) { - list_del_init(&command->queue); - command->state = EC_CMD_ERROR; + // empty datagram queue + list_for_each_entry_safe(datagram, next_c, + &master->datagram_queue, queue) { + list_del_init(&datagram->queue); + datagram->state = EC_CMD_ERROR; } // clear domains @@ -232,7 +233,7 @@ kobject_put(&domain->kobj); } - master->command_index = 0; + master->datagram_index = 0; master->debug_level = 0; master->timeout = 500; // 500us @@ -274,97 +275,97 @@ /*****************************************************************************/ /** - Places a command in the command queue. -*/ - -void ec_master_queue_command(ec_master_t *master, /**< EtherCAT master */ - ec_command_t *command /**< command */ - ) -{ - ec_command_t *queued_command; - - // check, if the command is already queued - list_for_each_entry(queued_command, &master->command_queue, queue) { - if (queued_command == command) { - command->state = EC_CMD_QUEUED; + Places a datagram in the datagram queue. +*/ + +void ec_master_queue_datagram(ec_master_t *master, /**< EtherCAT master */ + ec_datagram_t *datagram /**< datagram */ + ) +{ + ec_datagram_t *queued_datagram; + + // check, if the datagram is already queued + list_for_each_entry(queued_datagram, &master->datagram_queue, queue) { + if (queued_datagram == datagram) { + datagram->state = EC_CMD_QUEUED; if (unlikely(master->debug_level)) - EC_WARN("command already queued.\n"); + EC_WARN("datagram already queued.\n"); return; } } - list_add_tail(&command->queue, &master->command_queue); - command->state = EC_CMD_QUEUED; -} - -/*****************************************************************************/ - -/** - Sends the commands in the queue. + list_add_tail(&datagram->queue, &master->datagram_queue); + datagram->state = EC_CMD_QUEUED; +} + +/*****************************************************************************/ + +/** + Sends the datagrams in the queue. \return 0 in case of success, else < 0 */ -void ec_master_send_commands(ec_master_t *master /**< EtherCAT master */) -{ - ec_command_t *command; - size_t command_size; +void ec_master_send_datagrams(ec_master_t *master /**< EtherCAT master */) +{ + ec_datagram_t *datagram; + size_t datagram_size; uint8_t *frame_data, *cur_data; void *follows_word; cycles_t t_start, t_end; - unsigned int frame_count, more_commands_waiting; + unsigned int frame_count, more_datagrams_waiting; frame_count = 0; t_start = get_cycles(); if (unlikely(master->debug_level > 0)) - EC_DBG("ec_master_send_commands\n"); + EC_DBG("ec_master_send_datagrams\n"); do { // fetch pointer to transmit socket buffer frame_data = ec_device_tx_data(master->device); cur_data = frame_data + EC_FRAME_HEADER_SIZE; follows_word = NULL; - more_commands_waiting = 0; - - // fill current frame with commands - list_for_each_entry(command, &master->command_queue, queue) { - if (command->state != EC_CMD_QUEUED) continue; - - // does the current command fit in the frame? - command_size = EC_COMMAND_HEADER_SIZE + command->data_size - + EC_COMMAND_FOOTER_SIZE; - if (cur_data - frame_data + command_size > ETH_DATA_LEN) { - more_commands_waiting = 1; + more_datagrams_waiting = 0; + + // fill current frame with datagrams + list_for_each_entry(datagram, &master->datagram_queue, queue) { + if (datagram->state != EC_CMD_QUEUED) continue; + + // does the current datagram fit in the frame? + datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size + + EC_DATAGRAM_FOOTER_SIZE; + if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) { + more_datagrams_waiting = 1; break; } - command->state = EC_CMD_SENT; - command->t_sent = t_start; - command->index = master->command_index++; + datagram->state = EC_CMD_SENT; + datagram->t_sent = t_start; + datagram->index = master->datagram_index++; if (unlikely(master->debug_level > 0)) - EC_DBG("adding command 0x%02X\n", command->index); - - // set "command following" flag in previous frame + EC_DBG("adding datagram 0x%02X\n", datagram->index); + + // set "datagram following" flag in previous frame if (follows_word) EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000); - // EtherCAT command header - EC_WRITE_U8 (cur_data, command->type); - EC_WRITE_U8 (cur_data + 1, command->index); - EC_WRITE_U32(cur_data + 2, command->address.logical); - EC_WRITE_U16(cur_data + 6, command->data_size & 0x7FF); + // EtherCAT datagram header + EC_WRITE_U8 (cur_data, datagram->type); + EC_WRITE_U8 (cur_data + 1, datagram->index); + EC_WRITE_U32(cur_data + 2, datagram->address.logical); + EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF); EC_WRITE_U16(cur_data + 8, 0x0000); follows_word = cur_data + 6; - cur_data += EC_COMMAND_HEADER_SIZE; - - // EtherCAT command data - memcpy(cur_data, command->data, command->data_size); - cur_data += command->data_size; - - // EtherCAT command footer + cur_data += EC_DATAGRAM_HEADER_SIZE; + + // EtherCAT datagram data + memcpy(cur_data, datagram->data, datagram->data_size); + cur_data += datagram->data_size; + + // EtherCAT datagram footer EC_WRITE_U16(cur_data, 0x0000); // reset working counter - cur_data += EC_COMMAND_FOOTER_SIZE; + cur_data += EC_DATAGRAM_FOOTER_SIZE; } if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) { @@ -388,11 +389,11 @@ ec_device_send(master->device, cur_data - frame_data); frame_count++; } - while (more_commands_waiting); + while (more_datagrams_waiting); if (unlikely(master->debug_level > 0)) { t_end = get_cycles(); - EC_DBG("ec_master_send_commands sent %i frames in %ius.\n", + EC_DBG("ec_master_send_datagrams sent %i frames in %ius.\n", frame_count, (u32) (t_end - t_start) * 1000 / cpu_khz); } } @@ -411,10 +412,10 @@ ) { size_t frame_size, data_size; - uint8_t command_type, command_index; + uint8_t datagram_type, datagram_index; unsigned int cmd_follows, matched; const uint8_t *cur_data; - ec_command_t *command; + ec_datagram_t *datagram; if (unlikely(size < EC_FRAME_HEADER_SIZE)) { master->stats.corrupted++; @@ -436,64 +437,64 @@ cmd_follows = 1; while (cmd_follows) { - // process command header - command_type = EC_READ_U8 (cur_data); - command_index = EC_READ_U8 (cur_data + 1); - data_size = EC_READ_U16(cur_data + 6) & 0x07FF; - cmd_follows = EC_READ_U16(cur_data + 6) & 0x8000; - cur_data += EC_COMMAND_HEADER_SIZE; + // process datagram header + datagram_type = EC_READ_U8 (cur_data); + datagram_index = EC_READ_U8 (cur_data + 1); + data_size = EC_READ_U16(cur_data + 6) & 0x07FF; + cmd_follows = EC_READ_U16(cur_data + 6) & 0x8000; + cur_data += EC_DATAGRAM_HEADER_SIZE; if (unlikely(cur_data - frame_data - + data_size + EC_COMMAND_FOOTER_SIZE > size)) { + + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) { master->stats.corrupted++; ec_master_output_stats(master); return; } - // search for matching command in the queue + // search for matching datagram in the queue matched = 0; - list_for_each_entry(command, &master->command_queue, queue) { - if (command->state == EC_CMD_SENT - && command->type == command_type - && command->index == command_index - && command->data_size == data_size) { + list_for_each_entry(datagram, &master->datagram_queue, queue) { + if (datagram->state == EC_CMD_SENT + && datagram->type == datagram_type + && datagram->index == datagram_index + && datagram->data_size == data_size) { matched = 1; break; } } - // no matching command was found + // no matching datagram was found if (!matched) { master->stats.unmatched++; ec_master_output_stats(master); - cur_data += data_size + EC_COMMAND_FOOTER_SIZE; + cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE; continue; } - // copy received data in the command memory - memcpy(command->data, cur_data, data_size); + // copy received data in the datagram memory + memcpy(datagram->data, cur_data, data_size); cur_data += data_size; - // set the command's working counter - command->working_counter = EC_READ_U16(cur_data); - cur_data += EC_COMMAND_FOOTER_SIZE; - - // dequeue the received command - command->state = EC_CMD_RECEIVED; - list_del_init(&command->queue); - } -} - -/*****************************************************************************/ - -/** - Sends a single command and waits for its reception. - If the slave doesn't respond, the command is sent again. + // set the datagram's working counter + datagram->working_counter = EC_READ_U16(cur_data); + cur_data += EC_DATAGRAM_FOOTER_SIZE; + + // dequeue the received datagram + datagram->state = EC_CMD_RECEIVED; + list_del_init(&datagram->queue); + } +} + +/*****************************************************************************/ + +/** + Sends a single datagram and waits for its reception. + If the slave doesn't respond, the datagram is sent again. \return 0 in case of success, else < 0 */ int ec_master_simple_io(ec_master_t *master, /**< EtherCAT master */ - ec_command_t *command /**< command */ + ec_datagram_t *datagram /**< datagram */ ) { unsigned int response_tries_left; @@ -502,19 +503,19 @@ while (1) { - ec_master_queue_command(master, command); + ec_master_queue_datagram(master, datagram); ecrt_master_sync_io(master); - if (command->state == EC_CMD_RECEIVED) { - if (likely(command->working_counter)) + if (datagram->state == EC_CMD_RECEIVED) { + if (likely(datagram->working_counter)) return 0; } - else if (command->state == EC_CMD_TIMEOUT) { + else if (datagram->state == EC_CMD_TIMEOUT) { EC_ERR("Simple-IO TIMEOUT!\n"); return -1; } - else if (command->state == EC_CMD_ERROR) { - EC_ERR("Simple-IO command error!\n"); + else if (datagram->state == EC_CMD_ERROR) { + EC_ERR("Simple-IO datagram error!\n"); return -1; } @@ -540,7 +541,7 @@ { ec_slave_t *slave; ec_slave_ident_t *ident; - ec_command_t *command; + ec_datagram_t *datagram; unsigned int i; uint16_t coupler_index, coupler_subindex; uint16_t reverse_coupler_index, current_coupler_index; @@ -550,12 +551,12 @@ return -1; } - command = &master->simple_command; + datagram = &master->simple_datagram; // determine number of slaves on bus - if (ec_command_brd(command, 0x0000, 4)) return -1; - if (unlikely(ec_master_simple_io(master, command))) return -1; - master->slave_count = command->working_counter; + if (ec_datagram_brd(datagram, 0x0000, 4)) return -1; + if (unlikely(ec_master_simple_io(master, datagram))) return -1; + master->slave_count = datagram->working_counter; EC_INFO("Found %i slaves on bus.\n", master->slave_count); if (!master->slave_count) return 0; @@ -588,10 +589,10 @@ list_for_each_entry(slave, &master->slaves, list) { // write station address - if (ec_command_apwr(command, slave->ring_position, 0x0010, + if (ec_datagram_apwr(datagram, slave->ring_position, 0x0010, sizeof(uint16_t))) goto out_free; - EC_WRITE_U16(command->data, slave->station_address); - if (unlikely(ec_master_simple_io(master, command))) { + EC_WRITE_U16(datagram->data, slave->station_address); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Writing station address failed on slave %i!\n", slave->ring_position); goto out_free; @@ -650,7 +651,7 @@ if (unlikely((u32) (t_now - master->stats.t_last) / cpu_khz > 1000)) { if (master->stats.timeouts) { - EC_WARN("%i commands TIMED OUT!\n", master->stats.timeouts); + EC_WARN("%i datagrams TIMED OUT!\n", master->stats.timeouts); master->stats.timeouts = 0; } if (master->stats.delayed) { @@ -662,7 +663,7 @@ master->stats.corrupted = 0; } if (master->stats.unmatched) { - EC_WARN("%i command(s) UNMATCHED!\n", master->stats.unmatched); + EC_WARN("%i datagram(s) UNMATCHED!\n", master->stats.unmatched); master->stats.unmatched = 0; } master->stats.t_last = t_now; @@ -1075,7 +1076,7 @@ { unsigned int j; ec_slave_t *slave; - ec_command_t *command; + ec_datagram_t *datagram; const ec_sync_t *sync; const ec_slave_type_t *type; const ec_fmmu_t *fmmu; @@ -1083,7 +1084,7 @@ ec_domain_t *domain; ec_eeprom_sync_t *eeprom_sync, mbox_sync; - command = &master->simple_command; + datagram = &master->simple_datagram; // allocate all domains domain_offset = 0; @@ -1112,11 +1113,12 @@ // reset FMMUs if (slave->base_fmmu_count) { - if (ec_command_npwr(command, slave->station_address, 0x0600, - EC_FMMU_SIZE * slave->base_fmmu_count)) + if (ec_datagram_npwr(datagram, slave->station_address, 0x0600, + EC_FMMU_SIZE * slave->base_fmmu_count)) return -1; - memset(command->data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); - if (unlikely(ec_master_simple_io(master, command))) { + memset(datagram->data, 0x00, + EC_FMMU_SIZE * slave->base_fmmu_count); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Resetting FMMUs failed on slave %i!\n", slave->ring_position); return -1; @@ -1125,11 +1127,11 @@ // reset sync managers if (slave->base_sync_count) { - if (ec_command_npwr(command, slave->station_address, 0x0800, + if (ec_datagram_npwr(datagram, slave->station_address, 0x0800, EC_SYNC_SIZE * slave->base_sync_count)) return -1; - memset(command->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); - if (unlikely(ec_master_simple_io(master, command))) { + memset(datagram->data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Resetting sync managers failed on slave %i!\n", slave->ring_position); return -1; @@ -1140,11 +1142,11 @@ if (type) { // known slave type, take type's SM information for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) { sync = type->sync_managers[j]; - if (ec_command_npwr(command, slave->station_address, + if (ec_datagram_npwr(datagram, slave->station_address, 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) return -1; - ec_sync_config(sync, slave, command->data); - if (unlikely(ec_master_simple_io(master, command))) { + ec_sync_config(sync, slave, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Setting sync manager %i failed on slave %i!\n", j, slave->ring_position); return -1; @@ -1156,12 +1158,12 @@ if (!list_empty(&slave->eeprom_syncs)) { list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { EC_INFO("Sync manager %i...\n", eeprom_sync->index); - if (ec_command_npwr(command, slave->station_address, - 0x800 + eeprom_sync->index * - EC_SYNC_SIZE, - EC_SYNC_SIZE)) return -1; - ec_eeprom_sync_config(eeprom_sync, command->data); - if (unlikely(ec_master_simple_io(master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, + 0x800 + eeprom_sync->index * + EC_SYNC_SIZE, + EC_SYNC_SIZE)) return -1; + ec_eeprom_sync_config(eeprom_sync, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Setting sync manager %i failed on slave %i!\n", eeprom_sync->index, slave->ring_position); return -1; @@ -1174,10 +1176,10 @@ mbox_sync.length = slave->sii_rx_mailbox_size; mbox_sync.control_register = 0x26; mbox_sync.enable = 1; - if (ec_command_npwr(command, slave->station_address, - 0x800,EC_SYNC_SIZE)) return -1; - ec_eeprom_sync_config(&mbox_sync, command->data); - if (unlikely(ec_master_simple_io(master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, + 0x800,EC_SYNC_SIZE)) return -1; + ec_eeprom_sync_config(&mbox_sync, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Setting sync manager 0 failed on slave %i!\n", slave->ring_position); return -1; @@ -1188,10 +1190,10 @@ mbox_sync.length = slave->sii_tx_mailbox_size; mbox_sync.control_register = 0x22; mbox_sync.enable = 1; - if (ec_command_npwr(command, slave->station_address, - 0x808, EC_SYNC_SIZE)) return -1; - ec_eeprom_sync_config(&mbox_sync, command->data); - if (unlikely(ec_master_simple_io(master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, + 0x808, EC_SYNC_SIZE)) return -1; + ec_eeprom_sync_config(&mbox_sync, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Setting sync manager 1 failed on slave %i!\n", slave->ring_position); return -1; @@ -1218,11 +1220,11 @@ // configure FMMUs for (j = 0; j < slave->fmmu_count; j++) { fmmu = &slave->fmmus[j]; - if (ec_command_npwr(command, slave->station_address, - 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) + if (ec_datagram_npwr(datagram, slave->station_address, + 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) return -1; - ec_fmmu_config(fmmu, slave, command->data); - if (unlikely(ec_master_simple_io(master, command))) { + ec_fmmu_config(fmmu, slave, datagram->data); + if (unlikely(ec_master_simple_io(master, datagram))) { EC_ERR("Setting FMMU %i failed on slave %i!\n", j, slave->ring_position); return -1; @@ -1288,17 +1290,17 @@ /*****************************************************************************/ /** - Sends queued commands and waits for their reception. + Sends queued datagrams and waits for their reception. \ingroup RealtimeInterface */ void ecrt_master_sync_io(ec_master_t *master /**< EtherCAT master */) { - ec_command_t *command, *n; - unsigned int commands_sent; + ec_datagram_t *datagram, *n; + unsigned int datagrams_sent; cycles_t t_start, t_end, t_timeout; - // send commands + // send datagrams ecrt_master_async_send(master); t_start = get_cycles(); // measure io time @@ -1310,23 +1312,23 @@ t_end = get_cycles(); // take current time if (t_end - t_start >= t_timeout) break; // timeout! - commands_sent = 0; - list_for_each_entry_safe(command, n, &master->command_queue, queue) { - if (command->state == EC_CMD_RECEIVED) - list_del_init(&command->queue); - else if (command->state == EC_CMD_SENT) - commands_sent++; - } - - if (!commands_sent) break; - } - - // timeout; dequeue all commands - list_for_each_entry_safe(command, n, &master->command_queue, queue) { - switch (command->state) { + datagrams_sent = 0; + list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { + if (datagram->state == EC_CMD_RECEIVED) + list_del_init(&datagram->queue); + else if (datagram->state == EC_CMD_SENT) + datagrams_sent++; + } + + if (!datagrams_sent) break; + } + + // timeout; dequeue all datagrams + list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { + switch (datagram->state) { case EC_CMD_SENT: case EC_CMD_QUEUED: - command->state = EC_CMD_TIMEOUT; + datagram->state = EC_CMD_TIMEOUT; master->stats.timeouts++; ec_master_output_stats(master); break; @@ -1337,26 +1339,26 @@ default: break; } - list_del_init(&command->queue); - } -} - -/*****************************************************************************/ - -/** - Asynchronous sending of commands. + list_del_init(&datagram->queue); + } +} + +/*****************************************************************************/ + +/** + Asynchronous sending of datagrams. \ingroup RealtimeInterface */ void ecrt_master_async_send(ec_master_t *master /**< EtherCAT master */) { - ec_command_t *command, *n; + ec_datagram_t *datagram, *n; if (unlikely(!master->device->link_state)) { - // link is down, no command can be sent - list_for_each_entry_safe(command, n, &master->command_queue, queue) { - command->state = EC_CMD_ERROR; - list_del_init(&command->queue); + // link is down, no datagram can be sent + list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { + datagram->state = EC_CMD_ERROR; + list_del_init(&datagram->queue); } // query link state @@ -1365,19 +1367,19 @@ } // send frames - ec_master_send_commands(master); -} - -/*****************************************************************************/ - -/** - Asynchronous receiving of commands. + ec_master_send_datagrams(master); +} + +/*****************************************************************************/ + +/** + Asynchronous receiving of datagrams. \ingroup RealtimeInterface */ void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */) { - ec_command_t *command, *next; + ec_datagram_t *datagram, *next; cycles_t t_received, t_timeout; ec_device_call_isr(master->device); @@ -1385,18 +1387,19 @@ t_received = get_cycles(); t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); - // dequeue all received commands - list_for_each_entry_safe(command, next, &master->command_queue, queue) - if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue); - - // dequeue all commands that timed out - list_for_each_entry_safe(command, next, &master->command_queue, queue) { - switch (command->state) { + // dequeue all received datagrams + list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) + if (datagram->state == EC_CMD_RECEIVED) + list_del_init(&datagram->queue); + + // dequeue all datagrams that timed out + list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { + switch (datagram->state) { case EC_CMD_SENT: case EC_CMD_QUEUED: - if (t_received - command->t_sent > t_timeout) { - list_del_init(&command->queue); - command->state = EC_CMD_TIMEOUT; + if (t_received - datagram->t_sent > t_timeout) { + list_del_init(&datagram->queue); + datagram->state = EC_CMD_TIMEOUT; master->stats.timeouts++; ec_master_output_stats(master); } @@ -1411,7 +1414,7 @@ /** Prepares synchronous IO. - Queues all domain commands and sends them. Then waits a certain time, so + Queues all domain datagrams and sends them. Then waits a certain time, so that ecrt_master_sasync_receive() can be called securely. \ingroup RealtimeInterface */ @@ -1421,7 +1424,7 @@ ec_domain_t *domain; cycles_t t_start, t_end, t_timeout; - // queue commands of all domains + // queue datagrams of all domains list_for_each_entry(domain, &master->domains, list) ecrt_domain_queue(domain); diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/master.h --- a/master/master.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/master.h Thu Jul 06 08:23:24 2006 +0000 @@ -71,10 +71,10 @@ typedef struct { - unsigned int timeouts; /**< command timeouts */ - unsigned int delayed; /**< delayed commands */ + unsigned int timeouts; /**< datagram timeouts */ + unsigned int delayed; /**< delayed datagrams */ unsigned int corrupted; /**< corrupted frames */ - unsigned int unmatched; /**< unmatched commands */ + unsigned int unmatched; /**< unmatched datagrams */ cycles_t t_last; /**< time of last output */ } ec_stats_t; @@ -99,12 +99,12 @@ ec_device_t *device; /**< EtherCAT device */ - struct list_head command_queue; /**< command queue */ - uint8_t command_index; /**< current command index */ + struct list_head datagram_queue; /**< datagram queue */ + uint8_t datagram_index; /**< current datagram index */ struct list_head domains; /**< list of domains */ - ec_command_t simple_command; /**< command structure for initialization */ + ec_datagram_t simple_datagram; /**< datagram structure for initialization */ unsigned int timeout; /**< timeout in synchronous IO */ int debug_level; /**< master debug level */ @@ -143,8 +143,8 @@ // IO void ec_master_receive(ec_master_t *, const uint8_t *, size_t); -void ec_master_queue_command(ec_master_t *, ec_command_t *); -int ec_master_simple_io(ec_master_t *, ec_command_t *); +void ec_master_queue_datagram(ec_master_t *, ec_datagram_t *); +int ec_master_simple_io(ec_master_t *, ec_datagram_t *); // slave management int ec_master_bus_scan(ec_master_t *); diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/slave.c --- a/master/slave.c Tue Jun 27 20:24:32 2006 +0000 +++ b/master/slave.c Thu Jul 06 08:23:24 2006 +0000 @@ -43,7 +43,7 @@ #include "globals.h" #include "slave.h" -#include "command.h" +#include "datagram.h" #include "master.h" /*****************************************************************************/ @@ -259,38 +259,40 @@ int ec_slave_fetch(ec_slave_t *slave /**< EtherCAT slave */) { - ec_command_t *command; + ec_datagram_t *datagram; unsigned int i; uint16_t dl_status; - command = &slave->master->simple_command; + datagram = &slave->master->simple_datagram; // read base data - if (ec_command_nprd(command, slave->station_address, 0x0000, 6)) return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_nprd(datagram, slave->station_address, 0x0000, 6)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Reading base data from slave %i failed!\n", slave->ring_position); return -1; } - slave->base_type = EC_READ_U8 (command->data); - slave->base_revision = EC_READ_U8 (command->data + 1); - slave->base_build = EC_READ_U16(command->data + 2); - slave->base_fmmu_count = EC_READ_U8 (command->data + 4); - slave->base_sync_count = EC_READ_U8 (command->data + 5); + slave->base_type = EC_READ_U8 (datagram->data); + slave->base_revision = EC_READ_U8 (datagram->data + 1); + slave->base_build = EC_READ_U16(datagram->data + 2); + slave->base_fmmu_count = EC_READ_U8 (datagram->data + 4); + slave->base_sync_count = EC_READ_U8 (datagram->data + 5); if (slave->base_fmmu_count > EC_MAX_FMMUS) slave->base_fmmu_count = EC_MAX_FMMUS; // read data link status - if (ec_command_nprd(command, slave->station_address, 0x0110, 2)) return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_nprd(datagram, slave->station_address, 0x0110, 2)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Reading DL status from slave %i failed!\n", slave->ring_position); return -1; } - dl_status = EC_READ_U16(command->data); + dl_status = EC_READ_U16(datagram->data); for (i = 0; i < 4; i++) { slave->dl_link[i] = dl_status & (1 << (4 + i)) ? 1 : 0; slave->dl_loop[i] = dl_status & (1 << (8 + i * 2)) ? 1 : 0; @@ -342,17 +344,18 @@ /**< target memory */ ) { - ec_command_t *command; + ec_datagram_t *datagram; cycles_t start, end, timeout; - command = &slave->master->simple_command; + datagram = &slave->master->simple_datagram; // initiate read operation - if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1; - EC_WRITE_U8 (command->data, 0x00); // read-only access - EC_WRITE_U8 (command->data + 1, 0x01); // request read operation - EC_WRITE_U32(command->data + 2, offset); - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6)) + return -1; + EC_WRITE_U8 (datagram->data, 0x00); // read-only access + EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation + EC_WRITE_U32(datagram->data + 2, offset); + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("SII-read failed on slave %i!\n", slave->ring_position); return -1; } @@ -364,9 +367,9 @@ { udelay(10); - if (ec_command_nprd(command, slave->station_address, 0x502, 10)) - return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Getting SII-read status failed on slave %i!\n", slave->ring_position); return -1; @@ -375,8 +378,8 @@ end = get_cycles(); // check for "busy bit" - if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) { - *target = EC_READ_U16(command->data + 6); + if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) { + *target = EC_READ_U16(datagram->data + 6); return 0; } @@ -402,17 +405,18 @@ /**< target memory */ ) { - ec_command_t *command; + ec_datagram_t *datagram; cycles_t start, end, timeout; - command = &slave->master->simple_command; + datagram = &slave->master->simple_datagram; // initiate read operation - if (ec_command_npwr(command, slave->station_address, 0x502, 6)) return -1; - EC_WRITE_U8 (command->data, 0x00); // read-only access - EC_WRITE_U8 (command->data + 1, 0x01); // request read operation - EC_WRITE_U32(command->data + 2, offset); - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 6)) + return -1; + EC_WRITE_U8 (datagram->data, 0x00); // read-only access + EC_WRITE_U8 (datagram->data + 1, 0x01); // request read operation + EC_WRITE_U32(datagram->data + 2, offset); + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("SII-read failed on slave %i!\n", slave->ring_position); return -1; } @@ -424,9 +428,9 @@ { udelay(10); - if (ec_command_nprd(command, slave->station_address, 0x502, 10)) - return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Getting SII-read status failed on slave %i!\n", slave->ring_position); return -1; @@ -435,8 +439,8 @@ end = get_cycles(); // check "busy bit" - if (likely((EC_READ_U8(command->data + 1) & 0x81) == 0)) { - *target = EC_READ_U32(command->data + 6); + if (likely((EC_READ_U8(datagram->data + 1) & 0x81) == 0)) { + *target = EC_READ_U32(datagram->data + 6); return 0; } @@ -462,21 +466,22 @@ /**< new value */ ) { - ec_command_t *command; + ec_datagram_t *datagram; cycles_t start, end, timeout; - command = &slave->master->simple_command; + datagram = &slave->master->simple_datagram; EC_INFO("SII-write (slave %i, offset 0x%04X, value 0x%04X)\n", slave->ring_position, offset, value); // initiate write operation - if (ec_command_npwr(command, slave->station_address, 0x502, 8)) return -1; - EC_WRITE_U8 (command->data, 0x01); // enable write access - EC_WRITE_U8 (command->data + 1, 0x02); // request write operation - EC_WRITE_U32(command->data + 2, offset); - EC_WRITE_U16(command->data + 6, value); - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, 0x502, 8)) + return -1; + EC_WRITE_U8 (datagram->data, 0x01); // enable write access + EC_WRITE_U8 (datagram->data + 1, 0x02); // request write operation + EC_WRITE_U32(datagram->data + 2, offset); + EC_WRITE_U16(datagram->data + 6, value); + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("SII-write failed on slave %i!\n", slave->ring_position); return -1; } @@ -488,9 +493,9 @@ { udelay(10); - if (ec_command_nprd(command, slave->station_address, 0x502, 2)) - return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 2)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Getting SII-write status failed on slave %i!\n", slave->ring_position); return -1; @@ -499,8 +504,8 @@ end = get_cycles(); // check "busy bit" - if (likely((EC_READ_U8(command->data + 1) & 0x82) == 0)) { - if (EC_READ_U8(command->data + 1) & 0x40) { + if (likely((EC_READ_U8(datagram->data + 1) & 0x82) == 0)) { + if (EC_READ_U8(datagram->data + 1) & 0x40) { EC_ERR("SII-write failed!\n"); return -1; } @@ -834,14 +839,14 @@ uint8_t state /**< previous state */ ) { - ec_command_t *command; + ec_datagram_t *datagram; cycles_t start, end, timeout; - command = &slave->master->simple_command; - - if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return; - EC_WRITE_U16(command->data, state | EC_ACK); - if (unlikely(ec_master_simple_io(slave->master, command))) { + datagram = &slave->master->simple_datagram; + + if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) return; + EC_WRITE_U16(datagram->data, state | EC_ACK); + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_WARN("Acknowledge sending failed on slave %i!\n", slave->ring_position); return; @@ -854,9 +859,9 @@ { udelay(100); // wait a little bit... - if (ec_command_nprd(command, slave->station_address, 0x0130, 2)) + if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2)) return; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (unlikely(ec_master_simple_io(slave->master, datagram))) { slave->current_state = EC_SLAVE_STATE_UNKNOWN; EC_WARN("Acknowledge checking failed on slave %i!\n", slave->ring_position); @@ -865,7 +870,7 @@ end = get_cycles(); - if (likely(EC_READ_U8(command->data) == state)) { + if (likely(EC_READ_U8(datagram->data) == state)) { slave->current_state = state; EC_INFO("Acknowleged state 0x%02X on slave %i.\n", state, slave->ring_position); @@ -891,20 +896,20 @@ void ec_slave_read_al_status_code(ec_slave_t *slave /**< EtherCAT slave */) { - ec_command_t *command; + ec_datagram_t *datagram; uint16_t code; const ec_code_msg_t *al_msg; - command = &slave->master->simple_command; - - if (ec_command_nprd(command, slave->station_address, 0x0134, 2)) return; - if (unlikely(ec_master_simple_io(slave->master, command))) { + datagram = &slave->master->simple_datagram; + + if (ec_datagram_nprd(datagram, slave->station_address, 0x0134, 2)) return; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_WARN("Failed to read AL status code on slave %i!\n", slave->ring_position); return; } - if (!(code = EC_READ_U16(command->data))) return; + if (!(code = EC_READ_U16(datagram->data))) return; for (al_msg = al_status_messages; al_msg->code; al_msg++) { if (al_msg->code == code) { @@ -928,16 +933,17 @@ uint8_t state /**< new state */ ) { - ec_command_t *command; + ec_datagram_t *datagram; cycles_t start, end, timeout; - command = &slave->master->simple_command; + datagram = &slave->master->simple_datagram; slave->requested_state = state; - if (ec_command_npwr(command, slave->station_address, 0x0120, 2)) return -1; - EC_WRITE_U16(command->data, state); - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, 0x0120, 2)) + return -1; + EC_WRITE_U16(datagram->data, state); + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_ERR("Failed to set state 0x%02X on slave %i!\n", state, slave->ring_position); return -1; @@ -950,9 +956,9 @@ { udelay(100); // wait a little bit - if (ec_command_nprd(command, slave->station_address, 0x0130, 2)) - return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_nprd(datagram, slave->station_address, 0x0130, 2)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { slave->current_state = EC_SLAVE_STATE_UNKNOWN; EC_ERR("Failed to check state 0x%02X on slave %i!\n", state, slave->ring_position); @@ -961,18 +967,19 @@ end = get_cycles(); - if (unlikely(EC_READ_U8(command->data) & 0x10)) { // state change error + if (unlikely(EC_READ_U8(datagram->data) & 0x10)) { + // state change error EC_ERR("Failed to set state 0x%02X - Slave %i refused state change" " (code 0x%02X)!\n", state, slave->ring_position, - EC_READ_U8(command->data)); - slave->current_state = EC_READ_U8(command->data); + EC_READ_U8(datagram->data)); + slave->current_state = EC_READ_U8(datagram->data); state = slave->current_state & 0x0F; ec_slave_read_al_status_code(slave); ec_slave_state_ack(slave, state); return -1; } - if (likely(EC_READ_U8(command->data) == (state & 0x0F))) { + if (likely(EC_READ_U8(datagram->data) == (state & 0x0F))) { slave->current_state = state; return 0; // state change successful } @@ -1205,44 +1212,46 @@ int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */) { - ec_command_t *command; - - command = &slave->master->simple_command; - - if (ec_command_nprd(command, slave->station_address, 0x0300, 4)) return -1; - if (unlikely(ec_master_simple_io(slave->master, command))) { + ec_datagram_t *datagram; + + datagram = &slave->master->simple_datagram; + + if (ec_datagram_nprd(datagram, slave->station_address, 0x0300, 4)) + return -1; + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_WARN("Reading CRC fault counters failed on slave %i!\n", slave->ring_position); return -1; } - if (!EC_READ_U32(command->data)) return 0; // no CRC faults - - if (EC_READ_U8(command->data)) + if (!EC_READ_U32(datagram->data)) return 0; // no CRC faults + + if (EC_READ_U8(datagram->data)) EC_WARN("%3i RX-error%s on slave %i, channel A.\n", - EC_READ_U8(command->data), - EC_READ_U8(command->data) == 1 ? "" : "s", + EC_READ_U8(datagram->data), + EC_READ_U8(datagram->data) == 1 ? "" : "s", slave->ring_position); - if (EC_READ_U8(command->data + 1)) + if (EC_READ_U8(datagram->data + 1)) EC_WARN("%3i invalid frame%s on slave %i, channel A.\n", - EC_READ_U8(command->data + 1), - EC_READ_U8(command->data + 1) == 1 ? "" : "s", + EC_READ_U8(datagram->data + 1), + EC_READ_U8(datagram->data + 1) == 1 ? "" : "s", slave->ring_position); - if (EC_READ_U8(command->data + 2)) + if (EC_READ_U8(datagram->data + 2)) EC_WARN("%3i RX-error%s on slave %i, channel B.\n", - EC_READ_U8(command->data + 2), - EC_READ_U8(command->data + 2) == 1 ? "" : "s", + EC_READ_U8(datagram->data + 2), + EC_READ_U8(datagram->data + 2) == 1 ? "" : "s", slave->ring_position); - if (EC_READ_U8(command->data + 3)) + if (EC_READ_U8(datagram->data + 3)) EC_WARN("%3i invalid frame%s on slave %i, channel B.\n", - EC_READ_U8(command->data + 3), - EC_READ_U8(command->data + 3) == 1 ? "" : "s", + EC_READ_U8(datagram->data + 3), + EC_READ_U8(datagram->data + 3) == 1 ? "" : "s", slave->ring_position); // reset CRC counters - if (ec_command_npwr(command, slave->station_address, 0x0300, 4)) return -1; - EC_WRITE_U32(command->data, 0x00000000); - if (unlikely(ec_master_simple_io(slave->master, command))) { + if (ec_datagram_npwr(datagram, slave->station_address, 0x0300, 4)) + return -1; + EC_WRITE_U32(datagram->data, 0x00000000); + if (unlikely(ec_master_simple_io(slave->master, datagram))) { EC_WARN("Resetting CRC fault counters failed on slave %i!\n", slave->ring_position); return -1; diff -r 2cf6ae0a2419 -r 14aeb79aa992 master/slave.h --- a/master/slave.h Tue Jun 27 20:24:32 2006 +0000 +++ b/master/slave.h Thu Jul 06 08:23:24 2006 +0000 @@ -45,7 +45,7 @@ #include #include "globals.h" -#include "command.h" +#include "datagram.h" #include "types.h" /*****************************************************************************/