Renamed command structure to datagram.

This commit is contained in:
Florian Pose
2006-07-06 08:23:24 +00:00
parent 4a72709aa1
commit 6fdf205382
18 changed files with 932 additions and 918 deletions

View File

@@ -42,7 +42,7 @@ ifneq ($(KERNELRELEASE),)
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")

View File

@@ -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 @@ int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT slave */
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);
ec_datagram_init(&datagram);
if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 6)))
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 @@ int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT slave */
{
uint8_t *data;
size_t rec_size;
ec_command_t command;
ec_datagram_t datagram;
ec_command_init(&command);
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 @@ int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT slave */
uint8_t *data;
size_t rec_size, data_size;
uint32_t complete_size;
ec_command_t command;
ec_datagram_t datagram;
ec_command_init(&command);
ec_datagram_init(&datagram);
if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 6)))
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 @@ int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT slave */)
unsigned int i, sdo_count;
ec_sdo_t *sdo;
uint16_t sdo_index;
ec_command_t command;
ec_datagram_t datagram;
ec_command_init(&command);
ec_datagram_init(&datagram);
if (!(data = ec_slave_mbox_prepare_send(slave, &command, 0x03, 8)))
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 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT slave */)
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 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT slave */)
while (EC_READ_U8(data + 2) & 0x80);
// Fetch all SDO descriptions
if (ec_slave_fetch_sdo_descriptions(slave, &command)) goto err;
if (ec_slave_fetch_sdo_descriptions(slave, &datagram)) goto err;
ec_command_clear(&command);
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_list(ec_slave_t *slave /**< EtherCAT slave */)
*/
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 @@ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave, /**< EtherCAT slave */
}
// 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_descriptions(ec_slave_t *slave, /**< EtherCAT slave */
*/
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 @@ int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */
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

View File

@@ -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 <linux/slab.h>
#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;
}
/*****************************************************************************/

297
master/datagram.c Normal file
View File

@@ -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 <linux/slab.h>
#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;
}
/*****************************************************************************/

View File

@@ -33,13 +33,13 @@
/**
\file
EtherCAT command structure.
EtherCAT datagram structure.
*/
/*****************************************************************************/
#ifndef _EC_COMMAND_H_
#define _EC_COMMAND_H_
#ifndef _EC_DATAGRAM_H_
#define _EC_DATAGRAM_H_
#include <linux/list.h>
#include <linux/timex.h>
@@ -49,7 +49,7 @@
/*****************************************************************************/
/**
EtherCAT command type.
EtherCAT datagram type.
*/
typedef enum
@@ -63,22 +63,22 @@ typedef enum
EC_CMD_BWR = 0x08, /**< Broadcast write */
EC_CMD_LRW = 0x0C /**< Logical read/write */
}
ec_command_type_t;
ec_datagram_type_t;
/**
EtherCAT command state.
EtherCAT datagram 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_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_command_state_t;
ec_datagram_state_t;
/*****************************************************************************/
@@ -102,38 +102,38 @@ ec_address_t;
/*****************************************************************************/
/**
EtherCAT command.
EtherCAT datagram.
*/
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) */
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; /**< command data */
size_t mem_size; /**< command \a data memory size */
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; /**< command index (set by master) */
uint8_t index; /**< datagram 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_datagram_state_t state; /**< datagram state */
cycles_t t_sent; /**< time, the datagrams was sent */
}
ec_command_t;
ec_datagram_t;
/*****************************************************************************/
void ec_command_init(ec_command_t *);
void ec_command_clear(ec_command_t *);
int ec_command_prealloc(ec_command_t *, size_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_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);
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);
/*****************************************************************************/

View File

@@ -90,7 +90,7 @@ int ec_domain_init(ec_domain_t *domain, /**< EtherCAT domain */
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 @@ int ec_domain_init(ec_domain_t *domain, /**< EtherCAT domain */
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 @@ void ec_domain_clear_field_regs(ec_domain_t *domain /**< EtherCAT domain */)
/*****************************************************************************/
/**
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 */
)
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_command_t *command;
ec_datagram_t *datagram;
if (!(command = kmalloc(sizeof(ec_command_t), GFP_KERNEL))) {
EC_ERR("Failed to allocate domain command!\n");
if (!(datagram = kmalloc(sizeof(ec_datagram_t), GFP_KERNEL))) {
EC_ERR("Failed to allocate domain datagram!\n");
return -1;
}
ec_command_init(command);
ec_datagram_init(datagram);
if (ec_command_lrw(command, offset, data_size)) {
kfree(command);
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 @@ int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
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 @@ int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
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 @@ int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
}
}
// 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 @@ int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
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 @@ int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
}
}
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 @@ int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
/**
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 @@ int ecrt_domain_register_field_list(ec_domain_t *domain,
/*****************************************************************************/
/**
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;
ec_datagram_t *datagram;
list_for_each_entry(command, &domain->commands, list) {
ec_master_queue_command(domain->master, command);
list_for_each_entry(datagram, &domain->datagrams, list) {
ec_master_queue_datagram(domain->master, datagram);
}
}
@@ -502,13 +502,13 @@ void ecrt_domain_queue(ec_domain_t *domain /**< EtherCAT domain */)
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 @@ void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
/**
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;
ec_datagram_t *datagram;
list_for_each_entry(command, &domain->commands, list) {
if (command->state != EC_CMD_RECEIVED) return -1;
list_for_each_entry(datagram, &domain->datagrams, list) {
if (datagram->state != EC_CMD_RECEIVED) return -1;
}
return 0;

View File

@@ -46,7 +46,7 @@
#include "globals.h"
#include "slave.h"
#include "command.h"
#include "datagram.h"
/*****************************************************************************/
@@ -68,7 +68,7 @@ ec_field_reg_t;
/**
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 @@ struct ec_domain
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 */

View File

@@ -87,7 +87,7 @@ int ec_eoe_init(ec_eoe_t *eoe /**< EoE handler */)
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 @@ void ec_eoe_clear(ec_eoe_t *eoe /**< EoE handler */)
if (eoe->rx_skb) dev_kfree_skb(eoe->rx_skb);
ec_command_clear(&eoe->command);
ec_datagram_clear(&eoe->datagram);
}
/*****************************************************************************/
@@ -246,7 +246,7 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
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 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
(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 @@ void ec_eoe_print(const ec_eoe_t *eoe /**< EoE handler */)
/**
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 @@ void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
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 @@ void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
/**
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 @@ void ec_eoe_state_rx_check(ec_eoe_t *eoe /**< EoE handler */)
/**
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 @@ void ec_eoe_state_rx_fetch(ec_eoe_t *eoe /**< EoE handler */)
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 @@ void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */)
/**
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;

View File

@@ -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 ec_eoe
{
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 */

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,7 @@
#define __EC_STATES__
#include "../include/ecrt.h"
#include "command.h"
#include "datagram.h"
#include "slave.h"
/*****************************************************************************/
@@ -57,7 +57,7 @@ struct ec_fsm
{
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 */

View File

@@ -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 @@ extern void ec_print_states(uint8_t);
/**
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.
*/

View File

@@ -42,18 +42,18 @@
#include <linux/delay.h>
#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 @@ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
return NULL;
}
if (ec_command_npwr(command, slave->station_address,
slave->sii_rx_mailbox_offset,
slave->sii_rx_mailbox_size))
if (ec_datagram_npwr(datagram, 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
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 command->data + 6;
return datagram->data + 6;
}
/*****************************************************************************/
/**
Prepares a command for checking the mailbox state.
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 @@ int ec_slave_mbox_prepare_check(const ec_slave_t *slave, /**< slave */
/*****************************************************************************/
/**
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 */)
int ec_slave_mbox_check(const ec_datagram_t *datagram /**< datagram */)
{
return EC_READ_U8(command->data + 5) & 8 ? 1 : 0;
return EC_READ_U8(datagram->data + 5) & 8 ? 1 : 0;
}
/*****************************************************************************/
/**
Prepares a command to fetch mailbox data.
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 @@ int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
*/
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 %i!\n", EC_READ_U8(datagram->data + 5), type,
slave->ring_position);
return NULL;
}
if ((data_size = EC_READ_U16(command->data)) >
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;
return datagram->data + 6;
}
/*****************************************************************************/
/**
Sends a mailbox command and waits for its reception.
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);
type = EC_READ_U8(datagram->data + 5);
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);
return NULL;
}
return ec_slave_mbox_simple_receive(slave, command, type, size);
return ec_slave_mbox_simple_receive(slave, datagram, type, size);
}
/*****************************************************************************/
/**
Waits for the reception of a mailbox command.
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 @@ uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */
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 @@ uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */
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 @@ uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */
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 @@ uint8_t *ec_slave_mbox_simple_receive(const ec_slave_t *slave, /**< slave */
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);
}
/*****************************************************************************/

View File

@@ -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 *);
/*****************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -71,10 +71,10 @@ ec_master_mode_t;
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 @@ struct ec_master
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 @@ void ec_master_eoe_stop(ec_master_t *);
// 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 *);

View File

@@ -43,7 +43,7 @@
#include "globals.h"
#include "slave.h"
#include "command.h"
#include "datagram.h"
#include "master.h"
/*****************************************************************************/
@@ -259,38 +259,40 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
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 @@ int ec_slave_sii_read16(ec_slave_t *slave,
/**< 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 @@ int ec_slave_sii_read16(ec_slave_t *slave,
{
udelay(10);
if (ec_command_nprd(command, slave->station_address, 0x502, 10))
if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
return -1;
if (unlikely(ec_master_simple_io(slave->master, command))) {
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 @@ int ec_slave_sii_read16(ec_slave_t *slave,
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 @@ int ec_slave_sii_read32(ec_slave_t *slave,
/**< 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 @@ int ec_slave_sii_read32(ec_slave_t *slave,
{
udelay(10);
if (ec_command_nprd(command, slave->station_address, 0x502, 10))
if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 10))
return -1;
if (unlikely(ec_master_simple_io(slave->master, command))) {
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 @@ int ec_slave_sii_read32(ec_slave_t *slave,
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 @@ int ec_slave_sii_write16(ec_slave_t *slave,
/**< 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 @@ int ec_slave_sii_write16(ec_slave_t *slave,
{
udelay(10);
if (ec_command_nprd(command, slave->station_address, 0x502, 2))
if (ec_datagram_nprd(datagram, slave->station_address, 0x502, 2))
return -1;
if (unlikely(ec_master_simple_io(slave->master, command))) {
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 @@ int ec_slave_sii_write16(ec_slave_t *slave,
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 @@ void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
uint8_t state /**< previous state */
)
{
ec_command_t *command;
ec_datagram_t *datagram;
cycles_t start, end, timeout;
command = &slave->master->simple_command;
datagram = &slave->master->simple_datagram;
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))) {
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 @@ void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
{
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 @@ void ec_slave_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
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_state_ack(ec_slave_t *slave, /**< EtherCAT slave */
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;
datagram = &slave->master->simple_datagram;
if (ec_command_nprd(command, slave->station_address, 0x0134, 2)) return;
if (unlikely(ec_master_simple_io(slave->master, command))) {
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 @@ int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */
{
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 -1;
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_ERR("Failed to check state 0x%02X on slave %i!\n",
state, slave->ring_position);
@@ -961,18 +967,19 @@ int ec_slave_state_change(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ void ec_slave_print(const ec_slave_t *slave, /**< EtherCAT slave */
int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */)
{
ec_command_t *command;
ec_datagram_t *datagram;
command = &slave->master->simple_command;
datagram = &slave->master->simple_datagram;
if (ec_command_nprd(command, slave->station_address, 0x0300, 4)) return -1;
if (unlikely(ec_master_simple_io(slave->master, command))) {
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_U32(datagram->data)) return 0; // no CRC faults
if (EC_READ_U8(command->data))
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;

View File

@@ -45,7 +45,7 @@
#include <linux/kobject.h>
#include "globals.h"
#include "command.h"
#include "datagram.h"
#include "types.h"
/*****************************************************************************/