[etherlab-users] Slaves in PREOP state

carlos_jimenez at encopim.com carlos_jimenez at encopim.com
Fri Sep 23 16:42:00 CEST 2011


Hello everybody,

I've just started now with EtherCAT stuff and I'm having several  
problems. I have some Beckhoff modules to make tests, but when I try  
to run the example program, included in its code, I can't make it work  
all of them correctly.

I have a digital outputs module (EL2004), another one of digital  
inputs (EL1004). One module of analog outputs (EL41342) and an other  
of analog inputs (EL3102). I also have the bus coupler (EK1101).

I've modified rtai example to make them work, but I found problems in  
OP mode, not all of them get's slave status, and it doesn't work.

Does somebody knows what it happens? I can't find where is the error.  
Thank you in advance.

Here there is my code and my modules configuration:

----------------------------------------------------------------
#define BusCouplerPos  0, 0
#define DigOutSlavePos 0, 1
#define DigInSlavePos  0, 2
#define AnaOutSlavePos 0, 3
#define AnaInSlavePos  0, 4

#define Beckhoff_EK1101 0x00000002, 0x044D2C52
#define Beckhoff_EL2004 0x00000002, 0x07D43052
#define Beckhoff_EL1004 0x00000002, 0x03EC3052
#define Beckhoff_EL4132 0x00000002, 0x10243052
#define Beckhoff_EL3102 0x00000002, 0x0C1E3052

static unsigned int off_dig_in; // offsets for PDO entries
static unsigned int off_dig_out;
static unsigned int off_ana_out;
static unsigned int off_ana_in_status;
static unsigned int off_ana_in_value;

const static ec_pdo_entry_reg_t domain1_regs[] = {
     {DigOutSlavePos, Beckhoff_EL2004, 0x7000, 1, &off_dig_out},
     {DigInSlavePos, Beckhoff_EL1004, 0x6000, 1, &off_dig_in},
     {AnaOutSlavePos, Beckhoff_EL4132, 0x3001, 1, &off_ana_out},
     {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 1, &off_ana_in_status},
     {AnaInSlavePos, Beckhoff_EL3102, 0x3101, 2, &off_ana_in_value},
     {}
};

/* Analog Input ***************************/
static ec_pdo_entry_info_t el3102_pdo_entries[] = {
     {0x3101, 1,  8}, // status
     {0x3101, 2, 16},  // value
     {0x3101, 2,  8}, // status
     {0x3101, 2, 16}  // value
};

static ec_pdo_info_t el3102_pdos[] = {
     {0x1A00, 2, el3102_pdo_entries},
     {0x1A01, 2, el3102_pdo_entries + 2}
};

static ec_sync_info_t el3102_syncs[] = {
     {2, EC_DIR_OUTPUT},
     {3, EC_DIR_INPUT, 2, el3102_pdos},
     {0xff}
};

/* Digital Input ***************************/
static ec_pdo_entry_info_t el1004_channels[] = {
	{0x6000, 1, 1},
	{0x6010, 2, 1},
	{0x6020, 3, 1},
	{0x6030, 4, 1}
};

static ec_pdo_info_t el1004_pdos[] = {
	{0x1a00, 1, &el1004_channels[0]},
	{0x1a01, 1, &el1004_channels[1]},
	{0x1a02, 1, &el1004_channels[2]},
	{0x1a03, 1, &el1004_channels[3]}
};

static ec_sync_info_t el1004_syncs[] = {
	{0, EC_DIR_INPUT, 4, el1004_pdos},
	{0xff}
};

/* Digital Output *************************/
static ec_pdo_entry_info_t el2004_channels[] = {
     {0x7000, 1, 1}, // Value 1
     {0x7010, 2, 1}, // Value 2
     {0x7020, 3, 1}, // Value 3
     {0x7030, 4, 1}  // Value 4
};

static ec_pdo_info_t el2004_pdos[] = {
     {0x1600, 1, &el2004_channels[0]},
     {0x1601, 1, &el2004_channels[1]},
     {0x1602, 1, &el2004_channels[2]},
     {0x1603, 1, &el2004_channels[3]}
};

static ec_sync_info_t el2004_syncs[] = {
     {0, EC_DIR_OUTPUT, 4, el2004_pdos},
     {1, EC_DIR_INPUT},
     {0xff}
};

/* Analog out *****************************/
static ec_pdo_entry_info_t el4132_pdo_entries[] = {
     {0x3001, 1, 16}, // channel 1 value
     {0x3002, 1, 16}, // channel 2 value
};

static ec_pdo_info_t el4132_pdos[] = {
     {0x1600, 1, el4132_pdo_entries},
     {0x1601, 1, el4132_pdo_entries + 1}
};

static ec_sync_info_t el4132_syncs[] = {
     {2, EC_DIR_OUTPUT, 2, el4132_pdos},
     {3, EC_DIR_INPUT},
     {0xff}
};

.....

void run(long data)
{
     while (1) {
         t_last_cycle = get_cycles();

         // receive process data
         rt_sem_wait(&master_sem);
         ecrt_master_receive(master);
         ecrt_domain_process(domain1);
         rt_sem_signal(&master_sem);

         // check process data state (optional)
         check_domain1_state();

         if (counter) {
             counter--;
         } else { // do this at 1 Hz
             counter = FREQUENCY;

             // calculate new process data
             blink = !blink;

             // check for master state (optional)
             check_master_state();

             // check for islave configuration state(s) (optional)
             check_slave_config_states();
         }

         // write process data
         EC_WRITE_S16(domain1_pd + off_ana_out, 0x6556);
		printk("Valor Analogic: %d\n", EC_READ_S16(domain1_pd + off_ana_in_value));
         EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x09 : 0x06);
		printk("Valor Digital: %d\n", EC_READ_U8(domain1_pd + off_dig_in));

         rt_sem_wait(&master_sem);
         ecrt_domain_queue(domain1);
         rt_sem_signal(&master_sem);
         ecrt_master_send(master);

         rt_task_wait_period();
     }
}

...

int __init init_mod(void)
{
     int ret = -1;
     RTIME tick_period, requested_ticks, now;
     ec_slave_config_t *sc;

     printk(KERN_ERR PFX "Starting...\n");

     rt_sem_init(&master_sem, 1);

     t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000;

     master = ecrt_request_master(0);
     if (!master) {
         ret = -EBUSY;
         printk(KERN_ERR PFX "Requesting master 0 failed!\n");
         goto out_return;
     }

     ecrt_master_callbacks(master, request_lock_callback,  
release_lock_callback, master);

     printk(KERN_ERR PFX "Registering domain...\n");
     if (!(domain1 = ecrt_master_create_domain(master))) {
         printk(KERN_ERR PFX "Domain creation failed!\n");
         goto out_release_master;
     }

     printk(KERN_ERR PFX "Configuring PDOs...\n");

     printk(KERN_ERR PFX "Vamos a configurar Ana In.\n");
     if (!(sc_ana_in = ecrt_master_slave_config(
                     master, AnaInSlavePos, Beckhoff_EL3102))) {
         printk(KERN_ERR PFX "Failed to get slave configuration.\n");
         return -1;
     }
     if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3102_syncs)) {
         printk(KERN_ERR PFX "Failed to configure PDOs.\n");
         return -1;
     }

	printk(KERN_ERR PFX "Vamos a configurar Dig In.\n");
     if (!(sc = ecrt_master_slave_config(
                     master, DigInSlavePos, Beckhoff_EL1004))) {
         printk(KERN_ERR PFX "Failed to get slave configuration.\n");
         goto out_release_master;
     }

     if (ecrt_slave_config_pdos(sc, EC_END, el1004_syncs)) {
         printk(KERN_ERR PFX "Failed to configure PDOs.\n");
         goto out_release_master;
     }

	printk(KERN_ERR PFX "Vamos a configurar Dig Out.\n");
     if (!(sc = ecrt_master_slave_config(master, DigOutSlavePos,  
Beckhoff_EL2004))) {
         printk(KERN_ERR PFX "Failed to get slave configuration.\n");
         goto out_release_master;
     }

     if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) {
         printk(KERN_ERR PFX "Failed to configure PDOs.\n");
         goto out_release_master;
     }

	printk(KERN_ERR PFX "Vamos a configurar Ana Out.\n");
     if (!(sc = ecrt_master_slave_config(
                     master, AnaOutSlavePos, Beckhoff_EL4132))) {
         printk(KERN_ERR PFX "Failed to get slave configuration.\n");
         goto out_release_master;
     }

     if (ecrt_slave_config_pdos(sc, EC_END, el4132_syncs)) {
         printk(KERN_ERR PFX "Failed to configure PDOs.\n");
         goto out_release_master;
     }

	printk(KERN_ERR PFX "Vamos a configurar el Coupler.\n");
	if (!(sc = ecrt_master_slave_config(master, BusCouplerPos,  
Beckhoff_EK1101))) {
		printk(KERN_ERR PFX "Failed to get slave configuration.\n");
         goto out_release_master;
	}

     printk(KERN_ERR PFX "Registering PDO entries...\n");
     if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
         printk(KERN_ERR PFX "PDO entry registration failed!\n");
         goto out_release_master;
     }

     printk(KERN_ERR PFX "Activating master...\n");
     if (ecrt_master_activate(master)) {
         printk(KERN_ERR PFX "Failed to activate master!\n");
         goto out_release_master;
     }

     // Get internal process data for domain
     domain1_pd = ecrt_domain_data(domain1);

     printk(KERN_ERR PFX "Starting cyclic sample thread...\n");
     requested_ticks = nano2count(TIMERTICKS);
     tick_period = start_rt_timer(requested_ticks);
     printk(KERN_ERR PFX "RT timer started with %i/%i ticks.\n",
            (int) tick_period, (int) requested_ticks);

     if (rt_task_init(&task, run, 0, 2000, 0, 1, NULL)) {
         printk(KERN_ERR PFX "Failed to init RTAI task!\n");
         goto out_stop_timer;
     }

     now = rt_get_time();
     if (rt_task_make_periodic(&task, now + tick_period, tick_period)) {
         printk(KERN_ERR PFX "Failed to run RTAI task!\n");
         goto out_stop_task;
     }

     printk(KERN_ERR PFX "Initialized.\n");
     return 0;

  out_stop_task:
     rt_task_delete(&task);
  out_stop_timer:
     stop_rt_timer();
  out_release_master:
     printk(KERN_ERR PFX "Releasing master...\n");
     ecrt_release_master(master);
  out_return:
     rt_sem_delete(&master_sem);
     printk(KERN_ERR PFX "Failed to load. Aborting.\n");
     return ret;
}
-----------------------------------------------------------------

  ethercat slaves
0  0:0  OP     +  EK1101 EtherCAT-Koppler (2A E-Bus, ID-Switch)
1  0:1  PREOP  +  EL2004 4K. Dig. Ausgang 24V, 0.5A
2  0:2  PREOP  +  EL1004 4K. Dig. Eingang 24V, 3ms
3  0:3  PREOP  +  EL4132 2Ch. Ana. Ausgang +/-10V, 16bit
4  0:4  PREOP  +  EL3102 2K. Ana. Eingang +/-10V, Diff.

Thanks in advance

-- 
Carlos Jiménez

ENCOPIM S.L.
C/. del Parc 5 (nau 13), P.I. Els Pinetons
E-08291 RIPOLLET (Barcelona)
Tel: (+34) 935 94 23 47
Fax: (+34) 935 94 64 15

==========================================================
La información contenida en la presente transmisión es confidencial y su
uso únicamente está permitido a su(s) destinatario(s). Si Ud. no es la
persona destinataria de la presente transmisión, rogamos nos lo
comunique de manera inmediata por teléfono (+34 935 942 347) y destruya
cualquier copia de la misma (tanto digitales como en papel).

The information contained in this transmission is confidential and is
intended only for the use of the addressee(s). If you are not the
designated recipient of this transmission, please advise us immediately
by telephone (+34 935 942 347) and destroy any copies (digital and
paper).
==========================================================



More information about the Etherlab-users mailing list