ecrt_domain_register_pdo_range() implemented.

This commit is contained in:
Florian Pose 2006-10-18 13:11:48 +00:00
parent 95e186804e
commit 5d90e96f72
6 changed files with 181 additions and 14 deletions

View File

@ -56,23 +56,23 @@ ec_domain_t *domain1 = NULL;
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 @@ void run(unsigned long data)
// 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 @@ void run(unsigned long data)
}
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 @@ void release_lock(void *data)
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 @@ int __init init_mini_module(void)
}
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)) {

View File

@ -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

View File

@ -86,6 +86,12 @@ typedef struct
}
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 @@ ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain,
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);

View File

@ -188,7 +188,7 @@ int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */
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) {
@ -227,6 +227,81 @@ int ec_domain_reg_pdo_entry(ec_domain_t *domain, /**< EtherCAT domain */
/*****************************************************************************/
/**
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.
*/
@ -498,6 +573,58 @@ int ecrt_domain_register_pdo_list(ec_domain_t *domain,
/*****************************************************************************/
/**
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 @@ int ecrt_domain_state(const ec_domain_t *domain /**< EtherCAT domain */)
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);

View File

@ -327,6 +327,8 @@ int ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT slave */
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 @@ uint16_t ec_slave_calc_sync_size(const ec_slave_t *slave,
{
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 @@ uint16_t ec_slave_calc_sync_size(const ec_slave_t *slave,
}
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;
}
/*****************************************************************************/

View File

@ -116,6 +116,9 @@ typedef struct
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;