ecrt_domain_register_pdo_range() implemented.
This commit is contained in:
parent
95e186804e
commit
5d90e96f72
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
130
master/domain.c
130
master/domain.c
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue