ecrt_domain_register_pdo_range() implemented.
--- a/examples/mini/mini.c Wed Oct 18 13:10:06 2006 +0000
+++ b/examples/mini/mini.c Wed Oct 18 13:11:48 2006 +0000
@@ -56,23 +56,23 @@
spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
// data fields
-void *r_ana_out;
-
-// channels
-uint32_t k_pos;
-uint8_t k_stat;
-
+void *r_inputs;
+void *r_outputs;
+
+#if 0
ec_pdo_reg_t domain1_pdos[] = {
{"2", Beckhoff_EL4132_Output1, &r_ana_out},
{"3", Beckhoff_EL5001_Value, NULL},
{}
};
+#endif
/*****************************************************************************/
void run(unsigned long data)
{
static unsigned int counter = 0;
+ static unsigned int einaus = 0;
spin_lock(&master_lock);
@@ -82,6 +82,8 @@
// process data
//k_pos = EC_READ_U32(r_ssi);
+ EC_WRITE_U8(r_outputs + 2, einaus ? 0xFF : 0x00);
+
// send
ecrt_master_run(master);
@@ -94,10 +96,7 @@
}
else {
counter = FREQUENCY;
- //printk(KERN_INFO "input = ");
- //for (i = 0; i < 22; i++)
- // printk("%02X ", *((uint8_t *) r_kbus_in + i));
- //printk("\n");
+ einaus = !einaus;
}
// restart timer
@@ -124,7 +123,7 @@
int __init init_mini_module(void)
{
- ec_slave_t *slave;
+ // ec_slave_t *slave;
printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n");
@@ -143,16 +142,30 @@
}
printk(KERN_INFO "Registering PDOs...\n");
+#if 0
if (ecrt_domain_register_pdo_list(domain1, domain1_pdos)) {
printk(KERN_ERR "PDO registration failed!\n");
goto out_release_master;
}
-
+#endif
+ if (!ecrt_domain_register_pdo_range(domain1, "0", Beckhoff_BK1120,
+ EC_DIR_OUTPUT, 0, 4, &r_outputs)) {
+ printk(KERN_ERR "PDO registration failed!\n");
+ goto out_release_master;
+ }
+ if (!ecrt_domain_register_pdo_range(domain1, "0", Beckhoff_BK1120,
+ EC_DIR_INPUT, 0, 4, &r_inputs)) {
+ printk(KERN_ERR "PDO registration failed!\n");
+ goto out_release_master;
+ }
+
+#if 0
if (!(slave = ecrt_master_get_slave(master, "3")))
goto out_release_master;
if (ecrt_slave_conf_sdo8(slave, 0x4061, 1, 0))
goto out_release_master;
+#endif
printk(KERN_INFO "Activating master...\n");
if (ecrt_master_activate(master)) {
--- a/include/ecdb.h Wed Oct 18 13:10:06 2006 +0000
+++ b/include/ecdb.h Wed Oct 18 13:11:48 2006 +0000
@@ -45,6 +45,8 @@
/** \cond */
+#define Beckhoff_BK1120 0x00000002, 0x04602C22
+
#define Beckhoff_EL1004_Inputs 0x00000002, 0x03EC3052, 0x3101, 1
#define Beckhoff_EL1014_Inputs 0x00000002, 0x03F63052, 0x3101, 1
--- a/include/ecrt.h Wed Oct 18 13:10:06 2006 +0000
+++ b/include/ecrt.h Wed Oct 18 13:11:48 2006 +0000
@@ -86,6 +86,12 @@
}
ec_pdo_reg_t;
+/**
+ Direction type for ec_domain_register_pdo_range()
+*/
+
+typedef enum {EC_DIR_INPUT, EC_DIR_OUTPUT} ec_direction_t;
+
/******************************************************************************
* Master request functions
*****************************************************************************/
@@ -127,9 +133,19 @@
uint16_t pdo_index,
uint8_t pdo_subindex,
void **data_ptr);
+
int ecrt_domain_register_pdo_list(ec_domain_t *domain,
const ec_pdo_reg_t *pdos);
+ec_slave_t *ecrt_domain_register_pdo_range(ec_domain_t *domain,
+ const char *address,
+ uint32_t vendor_id,
+ uint32_t product_code,
+ ec_direction_t direction,
+ uint16_t offset,
+ uint16_t length,
+ void **data_ptr);
+
void ecrt_domain_process(ec_domain_t *domain);
int ecrt_domain_state(const ec_domain_t *domain);
--- a/master/domain.c Wed Oct 18 13:10:06 2006 +0000
+++ b/master/domain.c Wed Oct 18 13:11:48 2006 +0000
@@ -188,7 +188,7 @@
return -1;
}
- // Calculate offset for process data pointer
+ // Calculate offset (in sync manager) for process data pointer
bit_offset = 0;
byte_offset = 0;
list_for_each_entry(other_pdo, &slave->sii_pdos, list) {
@@ -228,6 +228,81 @@
/*****************************************************************************/
/**
+ Registeres a PDO range.
+ \return 0 in case of success, else < 0
+*/
+
+int ec_domain_reg_pdo_range(ec_domain_t *domain, /**< EtherCAT domain */
+ ec_slave_t *slave, /**< slave */
+ ec_direction_t dir, /**< data direction */
+ uint16_t offset, /**< offset */
+ uint16_t length, /**< length */
+ void **data_ptr /**< pointer to the process data
+ pointer */
+ )
+{
+ ec_data_reg_t *data_reg;
+ ec_sii_sync_t *sync;
+ unsigned int sync_found, sync_index;
+ uint16_t sync_length;
+
+ switch (dir) {
+ case EC_DIR_OUTPUT: sync_index = 2; break;
+ case EC_DIR_INPUT: sync_index = 3; break;
+ default:
+ EC_ERR("Invalid direction!\n");
+ return -1;
+ }
+
+ // Find sync manager
+ sync_found = 0;
+ list_for_each_entry(sync, &slave->sii_syncs, list) {
+ if (sync->index == sync_index) {
+ sync_found = 1;
+ break;
+ }
+ }
+
+ if (!sync_found) {
+ EC_ERR("No sync manager found for PDO range.\n");
+ return -1;
+ }
+
+ // Allocate memory for data registration object
+ if (!(data_reg =
+ (ec_data_reg_t *) kmalloc(sizeof(ec_data_reg_t), GFP_KERNEL))) {
+ EC_ERR("Failed to allocate data registration.\n");
+ return -1;
+ }
+
+ if (ec_slave_prepare_fmmu(slave, domain, sync)) {
+ EC_ERR("FMMU configuration failed.\n");
+ kfree(data_reg);
+ return -1;
+ }
+
+ data_reg->slave = slave;
+ data_reg->sync = sync;
+ data_reg->sync_offset = offset;
+ data_reg->data_ptr = data_ptr;
+
+ // estimate sync manager length
+ sync_length = offset + length;
+ if (sync->est_length < sync_length) {
+ sync->est_length = sync_length;
+ if (domain->master->debug_level) {
+ EC_DBG("Estimating length of sync manager %i of slave %i to %i.\n",
+ sync->index, slave->ring_position, sync_length);
+ }
+ }
+
+ list_add_tail(&data_reg->list, &domain->data_regs);
+ return 0;
+}
+
+/*****************************************************************************/
+
+/**
Clears the list of the data registrations.
*/
@@ -499,6 +574,58 @@
/*****************************************************************************/
/**
+ Registers a PDO range in a domain.
+ - If \a data_ptr is NULL, the slave is only validated.
+ \return pointer to the slave on success, else NULL
+ \ingroup RealtimeInterface
+*/
+
+ec_slave_t *ecrt_domain_register_pdo_range(ec_domain_t *domain,
+ /**< EtherCAT domain */
+ const char *address,
+ /**< ASCII address of the slave,
+ see ecrt_master_get_slave() */
+ uint32_t vendor_id,
+ /**< vendor ID */
+ uint32_t product_code,
+ /**< product code */
+ ec_direction_t direction,
+ /**< data direction */
+ uint16_t offset,
+ /**< offset in slave's PDO range */
+ uint16_t length,
+ /**< length of this range */
+ void **data_ptr
+ /**< address of the process data
+ pointer */
+ )
+{
+ ec_slave_t *slave;
+ ec_master_t *master;
+
+ master = domain->master;
+
+ // translate address and validate slave
+ if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
+ if (ec_slave_validate(slave, vendor_id, product_code)) return NULL;
+
+ if (!data_ptr) {
+ // data_ptr is NULL => mark slave as "registered" (do not warn)
+ slave->registered = 1;
+ return slave;
+ }
+
+ if (ec_domain_reg_pdo_range(domain, slave,
+ direction, offset, length, data_ptr)) {
+ return NULL;
+ }
+
+ return slave;
+}
+
+/*****************************************************************************/
+
+/**
Processes received process data and requeues the domain datagram(s).
\ingroup RealtimeInterface
*/
@@ -561,6 +688,7 @@
EXPORT_SYMBOL(ecrt_domain_register_pdo);
EXPORT_SYMBOL(ecrt_domain_register_pdo_list);
+EXPORT_SYMBOL(ecrt_domain_register_pdo_range);
EXPORT_SYMBOL(ecrt_domain_process);
EXPORT_SYMBOL(ecrt_domain_state);
--- a/master/slave.c Wed Oct 18 13:10:06 2006 +0000
+++ b/master/slave.c Wed Oct 18 13:11:48 2006 +0000
@@ -327,6 +327,8 @@
sync->control_register = EC_READ_U8 (data + 4);
sync->enable = EC_READ_U8 (data + 6);
+ sync->est_length = 0;
+
list_add_tail(&sync->list, &slave->sii_syncs);
}
@@ -825,9 +827,10 @@
{
ec_sii_pdo_t *pdo;
ec_sii_pdo_entry_t *pdo_entry;
- unsigned int bit_size;
+ unsigned int bit_size, byte_size;
if (sync->length) return sync->length;
+ if (sync->est_length) return sync->est_length;
bit_size = 0;
list_for_each_entry(pdo, &slave->sii_pdos, list) {
@@ -839,9 +842,11 @@
}
if (bit_size % 8) // round up to full bytes
- return bit_size / 8 + 1;
+ byte_size = bit_size / 8 + 1;
else
- return bit_size / 8;
+ byte_size = bit_size / 8;
+
+ return byte_size;
}
/*****************************************************************************/
--- a/master/slave.h Wed Oct 18 13:10:06 2006 +0000
+++ b/master/slave.h Wed Oct 18 13:11:48 2006 +0000
@@ -116,6 +116,9 @@
uint16_t length; /**< data length in bytes */
uint8_t control_register; /**< control register value */
uint8_t enable; /**< enable bit */
+ uint16_t est_length; /**< Estimated length. This is no field of the SII,
+ but it is used to calculate the length via
+ PDO ranges */
}
ec_sii_sync_t;