Commit 999e7277 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Split up ethercat slave code into seperate parts (coe, esi, mailbox).

Everything else stays in esc.c

Also add a lot of code for reading the ESCs eeprom with configuration
parameters. Also provide 'struct esc_device' for generic device creation
and handling based on the eeprom configuration.

The el1xxx, el2xxx and el3xxx now use this generic device.
Also the el3xxx module now properly supports the EL3102 device.
parent 56d3de7d
......@@ -10,7 +10,9 @@ LDFLAGS+= -ldl
endif
LIBSRCS= ec.c esc.c canopen.c ec_stoeber.c block_ec.c eth_linux.c
LIBSRCS= ec.c \
esc.c esc_coe.c esc_esi.c esc_mailbox.c \
canopen.c ec_stoeber.c block_ec.c
ifeq ($(OS), FreeBSD)
LIBSRCS+= eth_bsd.c
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2011
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2011, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009, 2011
Copyright Daan Vreeken <Daan@Vitsch.nl> - Vitsch Electronics, 2010
......@@ -39,7 +39,8 @@ struct controller_block_private {
bool input8;
unsigned char *rx_buffer;
int inputs;
struct esc_device *dev;
};
static void calculate_8(struct controller_block *block)
......@@ -49,13 +50,13 @@ static void calculate_8(struct controller_block *block)
ec_rx_pdo(controller_samplenr);
priv->input1 = (priv->rx_buffer[0] & 1);
priv->input2 = (priv->rx_buffer[0] & 2) >> 1;
priv->input3 = (priv->rx_buffer[0] & 4) >> 2;
priv->input4 = (priv->rx_buffer[0] & 8) >> 3;
priv->input5 = (priv->rx_buffer[0] & 16) >> 4;
priv->input6 = (priv->rx_buffer[0] & 32) >> 5;
priv->input7 = (priv->rx_buffer[0] & 64) >> 6;
priv->input8 = (priv->rx_buffer[0] & 128) >> 7;
priv->input2 = (priv->rx_buffer[0] & 2);
priv->input3 = (priv->rx_buffer[0] & 4);
priv->input4 = (priv->rx_buffer[0] & 8);
priv->input5 = (priv->rx_buffer[0] & 16);
priv->input6 = (priv->rx_buffer[0] & 32);
priv->input7 = (priv->rx_buffer[0] & 64);
priv->input8 = (priv->rx_buffer[0] & 128);
}
static void calculate_4(struct controller_block *block)
......@@ -65,9 +66,9 @@ static void calculate_4(struct controller_block *block)
ec_rx_pdo(controller_samplenr);
priv->input1 = (priv->rx_buffer[0] & 1);
priv->input2 = (priv->rx_buffer[0] & 2) >> 1;
priv->input3 = (priv->rx_buffer[0] & 4) >> 2;
priv->input4 = (priv->rx_buffer[0] & 8) >> 3;
priv->input2 = (priv->rx_buffer[0] & 2);
priv->input3 = (priv->rx_buffer[0] & 4);
priv->input4 = (priv->rx_buffer[0] & 8);
}
static void calculate_2(struct controller_block *block)
......@@ -77,7 +78,7 @@ static void calculate_2(struct controller_block *block)
ec_rx_pdo(controller_samplenr);
priv->input1 = (priv->rx_buffer[0] & 1);
priv->input2 = (priv->rx_buffer[0] & 2) >> 1;
priv->input2 = (priv->rx_buffer[0] & 2);
}
struct beckhoff_el1xxx_type {
......@@ -143,10 +144,7 @@ struct controller_block * block_beckhoff_el1xxx_create(char *name, va_list ap)
{
struct controller_block *block;
struct ec_dgram_addr addr;
struct esc_syncmanager_info pdo_rx;
int slaves;
int i;
bool found;
int dev = -1;
char *eltype;
int devno;
......@@ -166,24 +164,14 @@ struct controller_block * block_beckhoff_el1xxx_create(char *name, va_list ap)
goto err_ethercat;
if (!sim) {
slaves = ec_slave_count();
found = false;
for (i = 0; i < slaves; i++) {
struct ec_dgram_addr devaddr;
uint32_t vendor, product;
ec_addr_set_auto_inc_nr(&devaddr, i);
vendor = esc_esi_vendorid_get(&devaddr);
product = esc_esi_productcode_get(&devaddr);
if (vendor == ESC_ESI_VENDORID_BECKHOFF &&
product == devlist[dev].productcode) {
if (!devno || devno == i) {
found = true;
addr = devaddr;
}
}
}
if (!found) {
uint32_t vendor, product;
ec_addr_set_auto_inc_nr(&addr, devno);
vendor = esc_esi_vendorid_get(&addr);
product = esc_esi_productcode_get(&addr);
if (vendor != ESC_ESI_VENDORID_BECKHOFF ||
product != devlist[dev].productcode) {
log_send(LOG_T_ERROR, "%s: Device not found\n", name);
goto err_ethercat;
}
......@@ -194,18 +182,10 @@ struct controller_block * block_beckhoff_el1xxx_create(char *name, va_list ap)
name, sizeof(struct controller_block_private));
if (!sim) {
esc_init(&addr);
pdo_rx.start = 0x1000;
pdo_rx.len = 1;
pdo_rx.sm = 0;
block->private->dev = esc_esi_device_create(&addr);
esc_pdo_rx_set(&addr, &pdo_rx, &block->private->rx_buffer);
block->private->rx_buffer = block->private->dev->rx_data;
if (esc_al_state_set(&addr, ESC_AL_STATE_INIT, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state init\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_PRE_OPERATIONAL, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state pre operational\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_SAFE_OPERATIONAL, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state safe operational\n");
}
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2011
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2011, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009, 2011
+ Copyright Daan Vreeken <Daan@Vitsch.nl> - Vitsch Electronics, 2010
Copyright Daan Vreeken <Daan@Vitsch.nl> - Vitsch Electronics, 2010
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -39,7 +39,8 @@ struct controller_block_private {
bool *output8;
unsigned char *tx_buffer;
int outputs;
struct esc_device *dev;
};
static void calculate_8(struct controller_block *block)
......@@ -144,10 +145,7 @@ struct controller_block * block_beckhoff_el2xxx_create(char *name, va_list ap)
{
struct controller_block *block;
struct ec_dgram_addr addr;
struct esc_syncmanager_info pdo_tx;
int slaves;
int i;
bool found;
int dev = -1;
char *eltype;
int devno;
......@@ -167,24 +165,14 @@ struct controller_block * block_beckhoff_el2xxx_create(char *name, va_list ap)
goto err_ethercat;
if (!sim) {
slaves = ec_slave_count();
found = false;
for (i = 0; i < slaves; i++) {
struct ec_dgram_addr devaddr;
uint32_t vendor, product;
ec_addr_set_auto_inc_nr(&devaddr, i);
vendor = esc_esi_vendorid_get(&devaddr);
product = esc_esi_productcode_get(&devaddr);
if (vendor == ESC_ESI_VENDORID_BECKHOFF &&
product == devlist[dev].productcode) {
if (!devno || devno == i) {
found = true;
addr = devaddr;
}
}
}
if (!found) {
uint32_t vendor, product;
ec_addr_set_auto_inc_nr(&addr, devno);
vendor = esc_esi_vendorid_get(&addr);
product = esc_esi_productcode_get(&addr);
if (vendor != ESC_ESI_VENDORID_BECKHOFF ||
product != devlist[dev].productcode) {
log_send(LOG_T_ERROR, "%s: Device not found\n", name);
goto err_ethercat;
}
......@@ -195,24 +183,16 @@ struct controller_block * block_beckhoff_el2xxx_create(char *name, va_list ap)
name, sizeof(struct controller_block_private));
if (!sim) {
esc_init(&addr);
pdo_tx.start = 0x0f00;
pdo_tx.len = 0x1;
pdo_tx.sm = 0;
esc_pdo_tx_set(&addr, &pdo_tx, &block->private->tx_buffer, true);
block->private->dev = esc_esi_device_create(&addr);
block->private->tx_buffer = block->private->dev->tx_data;
if (esc_al_state_set(&addr, ESC_AL_STATE_INIT, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state init\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_PRE_OPERATIONAL, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state pre operational\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_SAFE_OPERATIONAL, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state safe operational\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_OPERATIONAL, &timeout) < 0)
log_send(LOG_T_ERROR, "Could not go to state safe operational\n");
log_send(LOG_T_DEBUG, "state: %d\n", esc_al_state_get(&addr));
log_send(LOG_T_DEBUG, "statuscode: %d\n", esc_al_status_code_get(&addr));
log_send(LOG_T_DEBUG, "state: %d", esc_al_state_get(&addr));
log_send(LOG_T_DEBUG, "statuscode: %d", esc_al_status_code_get(&addr));
}
/* Outputs on the hardware are inputs on this software block */
......
/*
Copyright Daan Vreeken <Daan@Vitsch.nl> - Vitsch Electronics, 2012
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2009, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2009
This program is free software: you can redistribute it and/or modify
......@@ -43,6 +43,8 @@ struct controller_block_private {
unsigned char *rx_buffer;
int inputs;
struct esc_device *dev;
};
struct el3_24bit_ch {
......@@ -71,9 +73,6 @@ static void calculate_2s(struct controller_block *block)
priv->input[ch_idx] = (float)value * priv->gain +
priv->offset;
}
log_send(LOG_T_DEBUG, "el3xxx(%s): _s2: TEST ME! %f %f",
block->name, priv->input[0], priv->input[1]);
}
static void calculate_2u(struct controller_block *block)
......@@ -244,31 +243,30 @@ static struct controller_block_outterm_list outterms_8[] = {
};
static struct beckhoff_el3xxx_type devlist[] = {
/*
* name, productcode, inputs, gain, offset, sign, pdo_bits_per_ch,
* driver_verified
* name, productcode, inputs, gain, offset, sign, pdo_bits_per_ch, driver_verified
*/
{ "EL3001", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3001, 1, 10.0/32767, 0.0, true, 24, 0, outterms_1 },
{ "EL3002", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3002, 2, 10.0/32767, 0.0, true, 24, 0, outterms_2 },
{ "EL3004", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3004, 4, 10.0/32767, 0.0, true, 24, 0, outterms_4 },
{ "EL3008", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3008, 8, 10.0/32767, 0.0, true, 24, 0, outterms_8 },
{ "EL3041", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3041, 1, 0.02/65536, 0.0, false, 24, 0, outterms_1 },
{ "EL3042", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3042, 2, 0.02/65536, 0.0, false, 24, 0, outterms_2 },
{ "EL3044", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3044, 4, 0.02/65536, 0.0, false, 24, 0, outterms_4 },
{ "EL3048", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3048, 8, 0.02/65536, 0.0, false, 24, 0, outterms_8 },
{ "EL3051", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3051, 1, 0.02/65536, 0.004, false, 24, 0, outterms_1 },
{ "EL3052", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3052, 2, 0.02/65536, 0.004, false, 24, 0, outterms_2 },
{ "EL3054", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3054, 4, 0.02/65536, 0.004, false, 24, 0, outterms_4 },
{ "EL3058", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3058, 8, 0.02/65536, 0.004, false, 24, 0, outterms_8 },
{ "EL3061", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3061, 1, 10.0/65536, 0.0, false, 24, 0, outterms_1 },
{ "EL3062", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3062, 2, 10.0/65536, 0.0, false, 24, 0, outterms_2 },
{ "EL3064", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3064, 4, 10.0/65536, 0.0, false, 24, 0, outterms_4 },
{ "EL3068", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3068, 8, 10.0/65536, 0.0, false, 24, 0, outterms_8 },
{ "EL3102", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3102, 2, 10.0 / 32767, 0.0, true, 24, 0, outterms_2 },
{ "EL3001", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3001, 1, 10.0/32767, 0.0, true, 24, 0, outterms_1 },
{ "EL3002", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3002, 2, 10.0/32767, 0.0, true, 24, 0, outterms_2 },
{ "EL3004", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3004, 4, 10.0/32767, 0.0, true, 24, 0, outterms_4 },
{ "EL3008", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3008, 8, 10.0/32767, 0.0, true, 24, 0, outterms_8 },
{ "EL3041", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3041, 1, 0.02/65536, 0.0, false, 24, 0, outterms_1 },
{ "EL3042", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3042, 2, 0.02/65536, 0.0, false, 24, 0, outterms_2 },
{ "EL3044", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3044, 4, 0.02/65536, 0.0, false, 24, 0, outterms_4 },
{ "EL3048", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3048, 8, 0.02/65536, 0.0, false, 24, 0, outterms_8 },
{ "EL3051", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3051, 1, 0.02/65536, 0.004, false, 24, 0, outterms_1 },
{ "EL3052", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3052, 2, 0.02/65536, 0.004, false, 24, 0, outterms_2 },
{ "EL3054", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3054, 4, 0.02/65536, 0.004, false, 24, 0, outterms_4 },
{ "EL3058", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3058, 8, 0.02/65536, 0.004, false, 24, 0, outterms_8 },
{ "EL3061", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3061, 1, 10.0/65536, 0.0, false, 24, 0, outterms_1 },
{ "EL3062", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3062, 2, 10.0/65536, 0.0, false, 24, 0, outterms_2 },
{ "EL3064", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3064, 4, 10.0/65536, 0.0, false, 24, 0, outterms_4 },
{ "EL3068", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3068, 8, 10.0/65536, 0.0, false, 24, 0, outterms_8 },
{ "EL3102", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3102, 2, 10.0/32767, 0.0, true, 24, 1, outterms_2 },
/* current inputs 4..20mA */
{ "EL3124", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3124, 4, 0.016 / 32767, 0.004, false, 32, 1, outterms_4 },
{ "EL3124", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3124, 4, 0.016/32767, 0.004, false, 32, 1, outterms_4 },
/* temperature sensors (PT100/1000 etc) */
{ "EL3204", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3204, 4, 0.1, 0.0, true, 32, 1, outterms_4 },
{ "EL3204", ESC_ESI_PRODUCTCODE_BECKHOFF_EL3204, 4, 0.1, 0.0, true, 32, 1, outterms_4 },
};
#define DEVLIST_LEN (sizeof(devlist) / sizeof(struct beckhoff_el3xxx_type))
......@@ -288,7 +286,7 @@ static struct controller_block_param_list params[] = {
{ NULL },
};
#define NR_OF_PARAMS (sizeof(params) / sizeof(struct controller_block_param_list))
#define NR_OF_PARAMS (sizeof(params) / sizeof(struct controller_block_param_list) - 1)
static void param_get(struct controller_block *block, int param, void *val)
{
......@@ -331,15 +329,10 @@ struct controller_block * block_beckhoff_el3xxx_create(char *name, va_list ap)
{
struct controller_block *block;
struct ec_dgram_addr addr;
struct esc_syncmanager_info pdo_rx, pdo_tx;
int slaves;
int i;
bool found;
struct beckhoff_el3xxx_type *dev;
char *eltype;
int devno;
struct esc_mailbox *mb;
struct esc_syncmanager_info mb_rd, mb_wr;
struct timespec timeout = { 1, 0 };
......@@ -356,31 +349,22 @@ struct controller_block * block_beckhoff_el3xxx_create(char *name, va_list ap)
if (dev == NULL)
return NULL;
slaves = ec_slave_count();
found = false;
for (i = 0; i < slaves; i++) {
struct ec_dgram_addr devaddr;
uint32_t vendor, product;
uint32_t vendor, product;
ec_addr_set_auto_inc_nr(&devaddr, i);
vendor = esc_esi_vendorid_get(&devaddr);
product = esc_esi_productcode_get(&devaddr);
if (vendor == ESC_ESI_VENDORID_BECKHOFF &&
product == dev->productcode) {
if (!devno || devno == i) {
found = true;
addr = devaddr;
}
}
}
if (!found) {
ec_addr_set_auto_inc_nr(&addr, devno);
vendor = esc_esi_vendorid_get(&addr);
product = esc_esi_productcode_get(&addr);
if (vendor != ESC_ESI_VENDORID_BECKHOFF ||
product != dev->productcode) {
log_send(LOG_T_ERROR, "%s: Device not found\n", name);
return NULL;
}
if (! dev->driver_verified) {
log_send(LOG_T_ERROR,
log_send(LOG_T_WARNING,
"el3xxx: This driver hasn't (yet) been verified to "
"with the %s. Be very careful!", dev->name);
"work with the %s. Be very careful!", dev->name);
}
block = controller_block_alloc("beckhoff_el3xxx", name,
......@@ -388,37 +372,12 @@ struct controller_block * block_beckhoff_el3xxx_create(char *name, va_list ap)
if (!block)
return NULL;
esc_init(&addr);
pdo_rx.start = 0x1180;
pdo_rx.len = dev->pdo_bits_per_ch * dev->inputs / 8;
pdo_rx.sm = 3;
pdo_tx.start = 0x1100;
pdo_tx.len = 0;
pdo_tx.sm = 2;
esc_pdo_tx_set(&addr, &pdo_tx, NULL, false);
esc_pdo_rx_set(&addr, &pdo_rx, &block->private->rx_buffer);
block->private->dev = esc_esi_device_create(&addr);
if (esc_al_state_set(&addr, ESC_AL_STATE_INIT, &timeout) < 0)
printf("Could not go to state init\n");
block->private->rx_buffer = block->private->dev->rx_data;
/* mailbox read (slave->master) @0x1080 */
mb_rd.start = 0x1080;
mb_rd.len = 128;
mb_rd.sm = 1;
/* mailbox write (master->slave) @0x1000 */
mb_wr.start = 0x1000;
mb_wr.len = 128;
mb_wr.sm = 0;
mb = esc_mailbox_create(&addr, &mb_rd, &mb_wr);
esc_coe_create(mb);
esc_coe_create(block->private->dev->mailbox);
if (esc_al_state_set(&addr, ESC_AL_STATE_PRE_OPERATIONAL, &timeout) < 0)
printf("Could not go to state pre operational\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_SAFE_OPERATIONAL, &timeout) < 0)
printf("Could not go to state safe operational\n");
if (esc_al_state_set(&addr, ESC_AL_STATE_OPERATIONAL, &timeout) < 0)
......@@ -433,7 +392,7 @@ struct controller_block * block_beckhoff_el3xxx_create(char *name, va_list ap)
switch (dev->inputs) {
case 2:
if (dev->pdo_bits_per_ch == 16) {
if (dev->pdo_bits_per_ch == 24) {
if (dev->sign)
block->calculate = calculate_2s;
else
......
......@@ -74,10 +74,15 @@ struct controller_block * block_ec_create(char *name, va_list ap)
while ((ret = ec_slave_count()) != nr_slaves) {
if (ret == -1) {
log_send(LOG_T_ERROR, "Error counting slaves");
} else {
} else if (ret < nr_slaves) {
log_send(LOG_T_ERROR,
"Found only %d slaves, waiting for %d.",
ret, nr_slaves);
} else {
log_send(LOG_T_WARNING,
"More slaves found (%d) than expected (%d).",
ret, nr_slaves);
break;
}
sleep(10);
}
......
......@@ -83,7 +83,7 @@ static int ec_rx_pdo_add_time(void)
struct ec_dgram_hdr *prev;
struct unaligned_uint16_t *wkc;
rx_pdo.rx_users = ec_slave_count();
// rx_pdo.rx_users = ec_slave_count();
dgram = (struct ec_dgram_hdr *)(rx_pdo.tx_frame + rx_pdo.flen);
rx_pdo.time = (struct unaligned_uint64_t *)
......@@ -148,7 +148,8 @@ int ec_rx_pdo_add(struct ec_dgram_addr *addr, unsigned char **data, size_t len)
rx_pdo.flen += sizeof(struct ec_dgram_hdr);
rx_pdo.flen += len + 2;
printf("Adding %zu bytes data to rx_pdo, total pdo is now: %zu bytes\n",
log_send(LOG_T_DEBUG,
"Adding %zu bytes data to rx_pdo, total pdo is now: %zu bytes",
len, rx_pdo.flen);
wkc = (struct unaligned_uint16_t*)(rx_pdo.tx_frame + rx_pdo.flen - 2);
......@@ -165,8 +166,8 @@ int ec_rx_pdo_add(struct ec_dgram_addr *addr, unsigned char **data, size_t len)
dgram->cmd = EC_DGRAM_HDR_CMD_APRD;
dgram->addr.position.pos = addr->addr.position.pos;
dgram->addr.position.off = addr->addr.position.off;
printf("Address: %x.%x\n", addr->addr.position.pos,
addr->addr.position.off);
log_send(LOG_T_DEBUG, "Address: %x.%x",
addr->addr.position.pos, addr->addr.position.off);
break;
default:
printf("Addressing mode not implemented!\n");
......@@ -211,9 +212,10 @@ int ec_tx_pdo_add(struct ec_dgram_addr *addr, unsigned char **data, size_t len)
tx_pdo->tx_users++;
printf("Adding %zu bytes data to tx_pdo, total pdo is now: %zu bytes\n",
log_send(LOG_T_DEBUG,
"Adding %zu bytes data to tx_pdo, total pdo is now: %zu bytes",
len, tx_pdo->flen);
printf("tx_pdo has %d users\n", tx_pdo->tx_users);
log_send(LOG_T_DEBUG, "tx_pdo has %d users", tx_pdo->tx_users);
wkc = (struct unaligned_uint16_t*)(tx_pdo->tx_frame + tx_pdo->flen - 2);
wkc->u16 = 0;
......@@ -307,6 +309,7 @@ int ec_rx_pdo(uint32_t nr)
{
ssize_t ret;
struct timespec t;
int r = 0;
if (!rx_pdo_enabled)
return 1;
......@@ -327,15 +330,23 @@ int ec_rx_pdo(uint32_t nr)
return ret;
}
if (le16toh(rx_pdo.time_wkc->u16) < rx_pdo.rx_users) {
log_send(LOG_T_ERROR,
"Only received ack from %d ethercat slaves! (%d expected)",
le16toh(rx_pdo.time_wkc->u16), rx_pdo.rx_users);
return 1;
if (le16toh(rx_pdo.time_wkc->u16) != rx_pdo.rx_users) {
if (!rx_pdo.rx_users) {
/* First response, keep it as reference for future */
log_send(LOG_T_DEBUG,
"%d slaves responded to clock write",
le16toh(rx_pdo.time_wkc->u16));
rx_pdo.rx_users = rx_pdo.time_wkc->u16;
} else {
log_send(LOG_T_ERROR,
"Only received clock ack from %d ethercat slaves! (%d expected)",
le16toh(rx_pdo.time_wkc->u16), rx_pdo.rx_users);
r = 1;
}
}
rx_pdo.nr = nr;
return 0;
return r;
}
struct ec_pdo_hook {
......
......@@ -30,10 +30,14 @@ void describe_esc(struct ec_dgram_addr *ec_addr)
int r, r2;
uint8_t val8;
uint16_t val16;
uint8_t eeprom[128*2];
uint8_t eeprom[1024/8];
uint32_t vendorid, productcode;
char *vendorid_str, *productcode_str;
int i;
size_t eeprom_size;
uint16_t eeprom_version;
struct esc_device *dev;
struct esc_esi_category *cat;
ec_addr->addr.position.off = ESC_ADDR_MAP_TYPE;
r = ec_datagram_read(ec_addr, &val8, 1);
......@@ -113,6 +117,52 @@ void describe_esc(struct ec_dgram_addr *ec_addr)
printf("\t\tEnhanced DC sync activation\n");
}
vendorid = esc_esi_vendorid_get(ec_addr);
productcode = esc_esi_productcode_get(ec_addr);
vendorid_str = "unknown vendorid";
productcode_str = "unkown productcode";
for (i = 0; i < esc_vendor_list_len; i++)
if (esc_vendor_list[i].vendorid == vendorid)
vendorid_str = esc_vendor_list[i].name;
for (i = 0; i < esc_device_list_len; i++)
if (esc_device_list[i].vendorid == vendorid &&
esc_device_list[i].productcode == productcode)
productcode_str = esc_device_list[i].name;
printf("\tESI VendorId: 0x%04x\n", vendorid);
printf("\t\tVendor: %s\n", vendorid_str);
printf("\tESI ProductCode: 0x%04x\n", productcode);
printf("\t\tProduct: %s\n", productcode_str);
printf("\tESI RevisionNo: 0x%04x\n", esc_esi_revisionno_get(ec_addr));
printf("\tESI SerialNo: 0x%04x\n", esc_esi_serialno_get(ec_addr));
eeprom_size = esc_esi_read16(ec_addr, ESC_ESI_ADDR_SIZE);
printf("\tESI Size: 0x%08zx\n", eeprom_size);
eeprom_version = esc_esi_read16(ec_addr, ESC_ESI_ADDR_VERSION);
printf("\tESI Version: 0x%08x\n", eeprom_version);
val16 = esc_esi_read16(ec_addr, ESC_ESI_BOOTSTRAP_RX_MAILBOX_OFFSET);
printf("\tESI Bootstrap RX mailbox offset: 0x%04x\n", val16);
val16 = esc_esi_read16(ec_addr, ESC_ESI_BOOTSTRAP_RX_MAILBOX_SIZE);
printf("\tESI Bootstrap RX mailbox size: 0x%04x\n", val16);
val16 = esc_esi_read16(ec_addr, ESC_ESI_BOOTSTRAP_TX_MAILBOX_OFFSET);
printf("\tESI Bootstrap TX mailbox offset: 0x%04x\n", val16);
val16 = esc_esi_read16(ec_addr, ESC_ESI_BOOTSTRAP_TX_MAILBOX_SIZE);
printf("\tESI Bootstrap TX mailbox size: 0x%04x\n", val16);
printf("\tESI Standard RX mailbox offset: 0x%04zx\n",
esc_esi_standard_rx_mailbox_offset_get(ec_addr));
printf("\tESI Standard RX mailbox size: 0x%04zx\n",
esc_esi_standard_rx_mailbox_size_get(ec_addr));
printf("\tESI Standard TX mailbox offset: 0x%04zx\n",
esc_esi_standard_tx_mailbox_offset_get(ec_addr));
printf("\tESI Standard TX mailbox size: 0x%04zx\n",
esc_esi_standard_rx_mailbox_size_get(ec_addr));
val16 = esc_esi_read16(ec_addr, ESC_ESI_MAILBOX_PROTOCOL);
printf("\tESI Mailbox Protocol: 0x%04x\n", val16);
r = esc_esi_eeprom_read(ec_addr, &eeprom, 0, sizeof(eeprom));
if (r == sizeof(eeprom)) {
printf("\tESI EEPROM:\n");
......@@ -120,17 +170,17 @@ void describe_esc(struct ec_dgram_addr *ec_addr)
char *c;
int j;
printf("\t\t%02x: "
printf("\t\t0x%04x (0x%04x): "