Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

master.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: master.c 682 2006-11-07 12:13:30Z fp $
00004  *
00005  *  Copyright (C) 2006  Florian Pose, Ingenieurgemeinschaft IgH
00006  *
00007  *  This file is part of the IgH EtherCAT Master.
00008  *
00009  *  The IgH EtherCAT Master is free software; you can redistribute it
00010  *  and/or modify it under the terms of the GNU General Public License
00011  *  as published by the Free Software Foundation; either version 2 of the
00012  *  License, or (at your option) any later version.
00013  *
00014  *  The IgH EtherCAT Master is distributed in the hope that it will be
00015  *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with the IgH EtherCAT Master; if not, write to the Free Software
00021  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  *  The right to use EtherCAT Technology is granted and comes free of
00024  *  charge under condition of compatibility of product made by
00025  *  Licensee. People intending to distribute/sell products based on the
00026  *  code, have to sign an agreement to guarantee that products using
00027  *  software based on IgH EtherCAT master stay compatible with the actual
00028  *  EtherCAT specification (which are released themselves as an open
00029  *  standard) as the (only) precondition to have the right to use EtherCAT
00030  *  Technology, IP and trade marks.
00031  *
00032  *****************************************************************************/
00033 
00039 /*****************************************************************************/
00040 
00041 #include <linux/module.h>
00042 #include <linux/kernel.h>
00043 #include <linux/string.h>
00044 #include <linux/slab.h>
00045 #include <linux/delay.h>
00046 
00047 #include "../include/ecrt.h"
00048 #include "globals.h"
00049 #include "master.h"
00050 #include "slave.h"
00051 #include "device.h"
00052 #include "datagram.h"
00053 #include "ethernet.h"
00054 
00055 /*****************************************************************************/
00056 
00057 void ec_master_clear(struct kobject *);
00058 void ec_master_destroy_domains(ec_master_t *);
00059 void ec_master_sync_io(ec_master_t *);
00060 void ec_master_idle_run(void *);
00061 void ec_master_eoe_run(unsigned long);
00062 void ec_master_check_sdo(unsigned long);
00063 int ec_master_measure_bus_time(ec_master_t *);
00064 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
00065 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
00066                                   const char *, size_t);
00067 
00068 /*****************************************************************************/
00069 
00072 EC_SYSFS_READ_ATTR(info);
00073 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable);
00074 EC_SYSFS_READ_WRITE_ATTR(debug_level);
00075 
00076 static struct attribute *ec_def_attrs[] = {
00077     &attr_info,
00078     &attr_eeprom_write_enable,
00079     &attr_debug_level,
00080     NULL,
00081 };
00082 
00083 static struct sysfs_ops ec_sysfs_ops = {
00084     .show = &ec_show_master_attribute,
00085     .store = ec_store_master_attribute
00086 };
00087 
00088 static struct kobj_type ktype_ec_master = {
00089     .release = ec_master_clear,
00090     .sysfs_ops = &ec_sysfs_ops,
00091     .default_attrs = ec_def_attrs
00092 };
00093 
00096 /*****************************************************************************/
00097 
00103 int ec_master_init(ec_master_t *master, 
00104                    unsigned int index, 
00105                    unsigned int eoeif_count 
00106                    )
00107 {
00108     ec_eoe_t *eoe, *next_eoe;
00109     unsigned int i;
00110 
00111     EC_INFO("Initializing master %i.\n", index);
00112 
00113     atomic_set(&master->available, 1);
00114     master->index = index;
00115 
00116     master->device = NULL;
00117     init_MUTEX(&master->device_sem);
00118 
00119     master->mode = EC_MASTER_MODE_ORPHANED;
00120 
00121     INIT_LIST_HEAD(&master->slaves);
00122     master->slave_count = 0;
00123 
00124     INIT_LIST_HEAD(&master->datagram_queue);
00125     master->datagram_index = 0;
00126 
00127     INIT_LIST_HEAD(&master->domains);
00128     master->debug_level = 0;
00129 
00130     master->stats.timeouts = 0;
00131     master->stats.corrupted = 0;
00132     master->stats.skipped = 0;
00133     master->stats.unmatched = 0;
00134     master->stats.output_jiffies = 0;
00135 
00136     INIT_WORK(&master->idle_work, ec_master_idle_run, (void *) master);
00137 
00138     for (i = 0; i < HZ; i++) {
00139         master->idle_cycle_times[i] = 0;
00140         master->eoe_cycle_times[i] = 0;
00141     }
00142     master->idle_cycle_time_pos = 0;
00143     master->eoe_cycle_time_pos = 0;
00144 
00145     init_timer(&master->eoe_timer);
00146     master->eoe_timer.function = ec_master_eoe_run;
00147     master->eoe_timer.data = (unsigned long) master;
00148     master->eoe_running = 0;
00149     master->eoe_checked = 0;
00150     INIT_LIST_HEAD(&master->eoe_handlers);
00151 
00152     master->internal_lock = SPIN_LOCK_UNLOCKED;
00153     master->request_cb = NULL;
00154     master->release_cb = NULL;
00155     master->cb_data = NULL;
00156 
00157     master->eeprom_write_enable = 0;
00158 
00159     master->sdo_request = NULL;
00160     master->sdo_seq_user = 0;
00161     master->sdo_seq_master = 0;
00162     init_MUTEX(&master->sdo_sem);
00163     init_timer(&master->sdo_timer);
00164     master->sdo_timer.function = ec_master_check_sdo;
00165     master->sdo_timer.data = (unsigned long) master;
00166     init_completion(&master->sdo_complete);
00167 
00168     // create workqueue
00169     if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) {
00170         EC_ERR("Failed to create master workqueue.\n");
00171         goto out_return;
00172     }
00173 
00174     // create EoE handlers
00175     for (i = 0; i < eoeif_count; i++) {
00176         if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
00177             EC_ERR("Failed to allocate EoE-Object.\n");
00178             goto out_clear_eoe;
00179         }
00180         if (ec_eoe_init(eoe)) {
00181             kfree(eoe);
00182             goto out_clear_eoe;
00183         }
00184         list_add_tail(&eoe->list, &master->eoe_handlers);
00185     }
00186 
00187     // create state machine object
00188     if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe;
00189 
00190     // init kobject and add it to the hierarchy
00191     memset(&master->kobj, 0x00, sizeof(struct kobject));
00192     kobject_init(&master->kobj);
00193     master->kobj.ktype = &ktype_ec_master;
00194     if (kobject_set_name(&master->kobj, "ethercat%i", index)) {
00195         EC_ERR("Failed to set kobj name.\n");
00196         kobject_put(&master->kobj);
00197         return -1;
00198     }
00199     if (kobject_add(&master->kobj)) {
00200         EC_ERR("Failed to add master kobj.\n");
00201         kobject_put(&master->kobj);
00202         return -1;
00203     }
00204 
00205     return 0;
00206 
00207  out_clear_eoe:
00208     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
00209         list_del(&eoe->list);
00210         ec_eoe_clear(eoe);
00211         kfree(eoe);
00212     }
00213     destroy_workqueue(master->workqueue);
00214  out_return:
00215     return -1;
00216 }
00217 
00218 /*****************************************************************************/
00219 
00225 void ec_master_destroy(ec_master_t *master )
00226 {
00227     ec_master_destroy_slaves(master);
00228     ec_master_destroy_domains(master);
00229 
00230     // destroy self
00231     kobject_del(&master->kobj);
00232     kobject_put(&master->kobj); // free master
00233 }
00234 
00235 /*****************************************************************************/
00236 
00243 void ec_master_clear(struct kobject *kobj )
00244 {
00245     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00246     ec_eoe_t *eoe, *next_eoe;
00247     ec_datagram_t *datagram, *next_datagram;
00248 
00249     // dequeue all datagrams
00250     list_for_each_entry_safe(datagram, next_datagram,
00251                              &master->datagram_queue, queue) {
00252         datagram->state = EC_DATAGRAM_ERROR;
00253         list_del_init(&datagram->queue);
00254     }
00255 
00256     ec_fsm_clear(&master->fsm);
00257     destroy_workqueue(master->workqueue);
00258 
00259     // clear EoE objects
00260     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
00261         list_del(&eoe->list);
00262         ec_eoe_clear(eoe);
00263         kfree(eoe);
00264     }
00265 
00266     EC_INFO("Master %i freed.\n", master->index);
00267 
00268     kfree(master);
00269 }
00270 
00271 /*****************************************************************************/
00272 
00277 void ec_master_destroy_slaves(ec_master_t *master)
00278 {
00279     ec_slave_t *slave, *next_slave;
00280 
00281     list_for_each_entry_safe(slave, next_slave, &master->slaves, list) {
00282         list_del(&slave->list);
00283         ec_slave_destroy(slave);
00284     }
00285 
00286     master->slave_count = 0;
00287 }
00288 
00289 /*****************************************************************************/
00290 
00295 void ec_master_destroy_domains(ec_master_t *master)
00296 {
00297     ec_domain_t *domain, *next_d;
00298 
00299     list_for_each_entry_safe(domain, next_d, &master->domains, list) {
00300         list_del(&domain->list);
00301         ec_domain_destroy(domain);
00302     }
00303 }
00304 
00305 /*****************************************************************************/
00306 
00311 void ec_master_flush_sdo_requests(ec_master_t *master)
00312 {
00313     del_timer_sync(&master->sdo_timer);
00314     complete(&master->sdo_complete);
00315     master->sdo_request = NULL;
00316     master->sdo_seq_user = 0;
00317     master->sdo_seq_master = 0;
00318 }
00319 
00320 /*****************************************************************************/
00321 
00325 int ec_master_enter_idle_mode(ec_master_t *master )
00326 {
00327     master->mode = EC_MASTER_MODE_IDLE;
00328     queue_delayed_work(master->workqueue, &master->idle_work, 1);
00329     return 0;
00330 }
00331 
00332 /*****************************************************************************/
00333 
00337 void ec_master_leave_idle_mode(ec_master_t *master )
00338 {
00339     ec_master_eoe_stop(master);
00340 
00341     master->mode = EC_MASTER_MODE_ORPHANED;
00342     while (!cancel_delayed_work(&master->idle_work)) {
00343         flush_workqueue(master->workqueue);
00344     }
00345 
00346     ec_master_flush_sdo_requests(master);
00347 }
00348 
00349 /*****************************************************************************/
00350 
00354 int ec_master_enter_operation_mode(ec_master_t *master )
00355 {
00356     ec_slave_t *slave;
00357     ec_datagram_t *datagram = &master->fsm.datagram;
00358 
00359     master->mode = EC_MASTER_MODE_OPERATION;
00360     while (!cancel_delayed_work(&master->idle_work)) {
00361         flush_workqueue(master->workqueue);
00362     }
00363 
00364     // wait for FSM datagram
00365     if (datagram->state == EC_DATAGRAM_SENT) {;
00366         while (get_cycles() - datagram->cycles_sent
00367                < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)) {}
00368         ecrt_master_receive(master);
00369     }
00370 
00371     // finish running master FSM
00372     if (ec_fsm_running(&master->fsm)) {
00373         while (ec_fsm_exec(&master->fsm)) {
00374             ec_master_sync_io(master);
00375         }
00376     }
00377 
00378     if (master->debug_level) {
00379         if (ec_master_measure_bus_time(master)) {
00380             EC_ERR("Bus time measuring failed!\n");
00381             goto out_idle;
00382         }
00383     }
00384 
00385     // set initial slave states
00386     list_for_each_entry(slave, &master->slaves, list) {
00387         if (ec_slave_is_coupler(slave)) {
00388             ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
00389         }
00390         else {
00391             ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
00392         }
00393     }
00394 
00395     return 0;
00396 
00397  out_idle:
00398     master->mode = EC_MASTER_MODE_IDLE;
00399     queue_delayed_work(master->workqueue, &master->idle_work, 1);
00400     return -1;
00401 }
00402 
00403 /*****************************************************************************/
00404 
00408 void ec_master_leave_operation_mode(ec_master_t *master)
00410 {
00411     ec_slave_t *slave;
00412     ec_fsm_t *fsm = &master->fsm;
00413     ec_datagram_t *datagram = &master->fsm.datagram;
00414 
00415     // wait for FSM datagram
00416     if (datagram->state == EC_DATAGRAM_SENT) {
00417         while (get_cycles() - datagram->cycles_sent
00418                < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)) {}
00419         ecrt_master_receive(master);
00420     }
00421 
00422     // finish running master FSM
00423     if (ec_fsm_running(fsm)) {
00424         while (ec_fsm_exec(fsm)) {
00425             ec_master_sync_io(master);
00426         }
00427     }
00428 
00429     // set states for all slaves
00430     list_for_each_entry(slave, &master->slaves, list) {
00431         ec_slave_reset(slave);
00432         ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
00433 
00434         fsm->slave = slave;
00435         fsm->slave_state = ec_fsm_slaveconf_state_start;
00436 
00437         do {
00438             fsm->slave_state(fsm);
00439             ec_master_sync_io(master);
00440         }
00441         while (fsm->slave_state != ec_fsm_slave_state_end
00442                && fsm->slave_state != ec_fsm_slave_state_error);
00443     }
00444 
00445     ec_master_destroy_domains(master);
00446 
00447     master->request_cb = NULL;
00448     master->release_cb = NULL;
00449     master->cb_data = NULL;
00450 
00451     master->mode = EC_MASTER_MODE_IDLE;
00452     queue_delayed_work(master->workqueue, &master->idle_work, 1);
00453 }
00454 
00455 /*****************************************************************************/
00456 
00461 void ec_master_queue_datagram(ec_master_t *master, 
00462                               ec_datagram_t *datagram 
00463                               )
00464 {
00465     ec_datagram_t *queued_datagram;
00466 
00467     // check, if the datagram is already queued
00468     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
00469         if (queued_datagram == datagram) {
00470             master->stats.skipped++;
00471             ec_master_output_stats(master);
00472             datagram->state = EC_DATAGRAM_QUEUED;
00473             return;
00474         }
00475     }
00476 
00477     list_add_tail(&datagram->queue, &master->datagram_queue);
00478     datagram->state = EC_DATAGRAM_QUEUED;
00479     datagram->cycles_queued = get_cycles();
00480 }
00481 
00482 /*****************************************************************************/
00483 
00489 void ec_master_send_datagrams(ec_master_t *master )
00490 {
00491     ec_datagram_t *datagram, *next;
00492     size_t datagram_size;
00493     uint8_t *frame_data, *cur_data;
00494     void *follows_word;
00495     cycles_t cycles_start, cycles_sent, cycles_end;
00496     unsigned long jiffies_sent;
00497     unsigned int frame_count, more_datagrams_waiting;
00498     struct list_head sent_datagrams;
00499 
00500     cycles_start = get_cycles();
00501     frame_count = 0;
00502     INIT_LIST_HEAD(&sent_datagrams);
00503 
00504     if (unlikely(master->debug_level > 1))
00505         EC_DBG("ec_master_send_datagrams\n");
00506 
00507     do {
00508         // fetch pointer to transmit socket buffer
00509         frame_data = ec_device_tx_data(master->device);
00510         cur_data = frame_data + EC_FRAME_HEADER_SIZE;
00511         follows_word = NULL;
00512         more_datagrams_waiting = 0;
00513 
00514         // fill current frame with datagrams
00515         list_for_each_entry(datagram, &master->datagram_queue, queue) {
00516             if (datagram->state != EC_DATAGRAM_QUEUED) continue;
00517 
00518             // does the current datagram fit in the frame?
00519             datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
00520                 + EC_DATAGRAM_FOOTER_SIZE;
00521             if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
00522                 more_datagrams_waiting = 1;
00523                 break;
00524             }
00525 
00526             list_add_tail(&datagram->sent, &sent_datagrams);
00527             datagram->index = master->datagram_index++;
00528 
00529             if (unlikely(master->debug_level > 1))
00530                 EC_DBG("adding datagram 0x%02X\n", datagram->index);
00531 
00532             // set "datagram following" flag in previous frame
00533             if (follows_word)
00534                 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000);
00535 
00536             // EtherCAT datagram header
00537             EC_WRITE_U8 (cur_data,     datagram->type);
00538             EC_WRITE_U8 (cur_data + 1, datagram->index);
00539             EC_WRITE_U32(cur_data + 2, datagram->address.logical);
00540             EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
00541             EC_WRITE_U16(cur_data + 8, 0x0000);
00542             follows_word = cur_data + 6;
00543             cur_data += EC_DATAGRAM_HEADER_SIZE;
00544 
00545             // EtherCAT datagram data
00546             memcpy(cur_data, datagram->data, datagram->data_size);
00547             cur_data += datagram->data_size;
00548 
00549             // EtherCAT datagram footer
00550             EC_WRITE_U16(cur_data, 0x0000); // reset working counter
00551             cur_data += EC_DATAGRAM_FOOTER_SIZE;
00552         }
00553 
00554         if (list_empty(&sent_datagrams)) {
00555             if (unlikely(master->debug_level > 1))
00556                 EC_DBG("nothing to send.\n");
00557             break;
00558         }
00559 
00560         // EtherCAT frame header
00561         EC_WRITE_U16(frame_data, ((cur_data - frame_data
00562                                    - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
00563 
00564         // pad frame
00565         while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
00566             EC_WRITE_U8(cur_data++, 0x00);
00567 
00568         if (unlikely(master->debug_level > 1))
00569             EC_DBG("frame size: %i\n", cur_data - frame_data);
00570 
00571         // send frame
00572         ec_device_send(master->device, cur_data - frame_data);
00573         cycles_sent = get_cycles();
00574         jiffies_sent = jiffies;
00575 
00576         // set datagram states and sending timestamps
00577         list_for_each_entry_safe(datagram, next, &sent_datagrams, sent) {
00578             datagram->state = EC_DATAGRAM_SENT;
00579             datagram->cycles_sent = cycles_sent;
00580             datagram->jiffies_sent = jiffies_sent;
00581             list_del_init(&datagram->sent); // empty list of sent datagrams
00582         }
00583 
00584         frame_count++;
00585     }
00586     while (more_datagrams_waiting);
00587 
00588     if (unlikely(master->debug_level > 1)) {
00589         cycles_end = get_cycles();
00590         EC_DBG("ec_master_send_datagrams sent %i frames in %ius.\n",
00591                frame_count,
00592                (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
00593     }
00594 }
00595 
00596 /*****************************************************************************/
00597 
00604 void ec_master_receive_datagrams(ec_master_t *master, 
00605                                  const uint8_t *frame_data, 
00606                                  size_t size 
00607                                  )
00608 {
00609     size_t frame_size, data_size;
00610     uint8_t datagram_type, datagram_index;
00611     unsigned int cmd_follows, matched;
00612     const uint8_t *cur_data;
00613     ec_datagram_t *datagram;
00614 
00615     if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
00616         master->stats.corrupted++;
00617         ec_master_output_stats(master);
00618         return;
00619     }
00620 
00621     cur_data = frame_data;
00622 
00623     // check length of entire frame
00624     frame_size = EC_READ_U16(cur_data) & 0x07FF;
00625     cur_data += EC_FRAME_HEADER_SIZE;
00626 
00627     if (unlikely(frame_size > size)) {
00628         master->stats.corrupted++;
00629         ec_master_output_stats(master);
00630         return;
00631     }
00632 
00633     cmd_follows = 1;
00634     while (cmd_follows) {
00635         // process datagram header
00636         datagram_type  = EC_READ_U8 (cur_data);
00637         datagram_index = EC_READ_U8 (cur_data + 1);
00638         data_size      = EC_READ_U16(cur_data + 6) & 0x07FF;
00639         cmd_follows    = EC_READ_U16(cur_data + 6) & 0x8000;
00640         cur_data += EC_DATAGRAM_HEADER_SIZE;
00641 
00642         if (unlikely(cur_data - frame_data
00643                      + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
00644             master->stats.corrupted++;
00645             ec_master_output_stats(master);
00646             return;
00647         }
00648 
00649         // search for matching datagram in the queue
00650         matched = 0;
00651         list_for_each_entry(datagram, &master->datagram_queue, queue) {
00652             if (datagram->state == EC_DATAGRAM_SENT
00653                 && datagram->type == datagram_type
00654                 && datagram->index == datagram_index
00655                 && datagram->data_size == data_size) {
00656                 matched = 1;
00657                 break;
00658             }
00659         }
00660 
00661         // no matching datagram was found
00662         if (!matched) {
00663             master->stats.unmatched++;
00664             ec_master_output_stats(master);
00665             cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
00666             continue;
00667         }
00668 
00669         // copy received data into the datagram memory
00670         memcpy(datagram->data, cur_data, data_size);
00671         cur_data += data_size;
00672 
00673         // set the datagram's working counter
00674         datagram->working_counter = EC_READ_U16(cur_data);
00675         cur_data += EC_DATAGRAM_FOOTER_SIZE;
00676 
00677         // dequeue the received datagram
00678         datagram->state = EC_DATAGRAM_RECEIVED;
00679         datagram->cycles_received = master->device->cycles_isr;
00680         datagram->jiffies_received = master->device->jiffies_isr;
00681         list_del_init(&datagram->queue);
00682     }
00683 }
00684 
00685 /*****************************************************************************/
00686 
00693 void ec_master_output_stats(ec_master_t *master )
00694 {
00695     if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) {
00696         master->stats.output_jiffies = jiffies;
00697 
00698         if (master->stats.timeouts) {
00699             EC_WARN("%i datagram%s TIMED OUT!\n", master->stats.timeouts,
00700                     master->stats.timeouts == 1 ? "" : "s");
00701             master->stats.timeouts = 0;
00702         }
00703         if (master->stats.corrupted) {
00704             EC_WARN("%i frame%s CORRUPTED!\n", master->stats.corrupted,
00705                     master->stats.corrupted == 1 ? "" : "s");
00706             master->stats.corrupted = 0;
00707         }
00708         if (master->stats.skipped) {
00709             EC_WARN("%i datagram%s SKIPPED!\n", master->stats.skipped,
00710                     master->stats.skipped == 1 ? "" : "s");
00711             master->stats.skipped = 0;
00712         }
00713         if (master->stats.unmatched) {
00714             EC_WARN("%i datagram%s UNMATCHED!\n", master->stats.unmatched,
00715                     master->stats.unmatched == 1 ? "" : "s");
00716             master->stats.unmatched = 0;
00717         }
00718     }
00719 }
00720 
00721 /*****************************************************************************/
00722 
00727 void ec_master_idle_run(void *data )
00728 {
00729     ec_master_t *master = (ec_master_t *) data;
00730     cycles_t cycles_start, cycles_end;
00731 
00732     // aquire master lock
00733     spin_lock_bh(&master->internal_lock);
00734 
00735     cycles_start = get_cycles();
00736     ecrt_master_receive(master);
00737 
00738     // execute master state machine
00739     ec_fsm_exec(&master->fsm);
00740 
00741     ecrt_master_send(master);
00742     cycles_end = get_cycles();
00743 
00744     // release master lock
00745     spin_unlock_bh(&master->internal_lock);
00746 
00747     master->idle_cycle_times[master->idle_cycle_time_pos]
00748         = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
00749     master->idle_cycle_time_pos++;
00750     master->idle_cycle_time_pos %= HZ;
00751 
00752     if (master->mode == EC_MASTER_MODE_IDLE)
00753         queue_delayed_work(master->workqueue, &master->idle_work, 1);
00754 }
00755 
00756 /*****************************************************************************/
00757 
00763 void ec_sync_config(const ec_sii_sync_t *sync, 
00764                     const ec_slave_t *slave, 
00765                     uint8_t *data 
00766                     )
00767 {
00768     size_t sync_size;
00769 
00770     sync_size = ec_slave_calc_sync_size(slave, sync);
00771 
00772     if (slave->master->debug_level) {
00773         EC_DBG("Slave %3i, SM %i: Addr 0x%04X, Size %3i, Ctrl 0x%02X, En %i\n",
00774                slave->ring_position, sync->index, sync->physical_start_address,
00775                sync_size, sync->control_register, sync->enable);
00776     }
00777 
00778     EC_WRITE_U16(data,     sync->physical_start_address);
00779     EC_WRITE_U16(data + 2, sync_size);
00780     EC_WRITE_U8 (data + 4, sync->control_register);
00781     EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
00782     EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable
00783 }
00784 
00785 /*****************************************************************************/
00786 
00792 void ec_fmmu_config(const ec_fmmu_t *fmmu, 
00793                     const ec_slave_t *slave, 
00794                     uint8_t *data 
00795                     )
00796 {
00797     size_t sync_size;
00798 
00799     sync_size = ec_slave_calc_sync_size(slave, fmmu->sync);
00800 
00801     if (slave->master->debug_level) {
00802         EC_DBG("Slave %3i, FMMU %2i:"
00803                " LogAddr 0x%08X, Size %3i, PhysAddr 0x%04X, Dir %s\n",
00804                slave->ring_position, fmmu->index, fmmu->logical_start_address,
00805                sync_size, fmmu->sync->physical_start_address,
00806                ((fmmu->sync->control_register & 0x04) ? "out" : "in"));
00807     }
00808 
00809     EC_WRITE_U32(data,      fmmu->logical_start_address);
00810     EC_WRITE_U16(data + 4,  sync_size); // size of fmmu
00811     EC_WRITE_U8 (data + 6,  0x00); // logical start bit
00812     EC_WRITE_U8 (data + 7,  0x07); // logical end bit
00813     EC_WRITE_U16(data + 8,  fmmu->sync->physical_start_address);
00814     EC_WRITE_U8 (data + 10, 0x00); // physical start bit
00815     EC_WRITE_U8 (data + 11, ((fmmu->sync->control_register & 0x04)
00816                              ? 0x02 : 0x01));
00817     EC_WRITE_U16(data + 12, 0x0001); // enable
00818     EC_WRITE_U16(data + 14, 0x0000); // reserved
00819 }
00820 
00821 /*****************************************************************************/
00822 
00828 ssize_t ec_master_info(ec_master_t *master, 
00829                        char *buffer 
00830                        )
00831 {
00832     off_t off = 0;
00833     ec_eoe_t *eoe;
00834     uint32_t cur, sum, min, max, pos, i;
00835 
00836     off += sprintf(buffer + off, "\nVersion: %s", ec_master_version_str);
00837     off += sprintf(buffer + off, "\nMode: ");
00838     switch (master->mode) {
00839         case EC_MASTER_MODE_ORPHANED:
00840             off += sprintf(buffer + off, "ORPHANED");
00841             break;
00842         case EC_MASTER_MODE_IDLE:
00843             off += sprintf(buffer + off, "IDLE");
00844             break;
00845         case EC_MASTER_MODE_OPERATION:
00846             off += sprintf(buffer + off, "OPERATION");
00847             break;
00848     }
00849 
00850     off += sprintf(buffer + off, "\nSlaves: %i\n",
00851                    master->slave_count);
00852 
00853     off += sprintf(buffer + off, "\nTiming (min/avg/max) [us]:\n");
00854 
00855     sum = 0;
00856     min = 0xFFFFFFFF;
00857     max = 0;
00858     pos = master->idle_cycle_time_pos;
00859     for (i = 0; i < HZ; i++) {
00860         cur = master->idle_cycle_times[(i + pos) % HZ];
00861         sum += cur;
00862         if (cur < min) min = cur;
00863         if (cur > max) max = cur;
00864     }
00865     off += sprintf(buffer + off, "  Idle cycle: %u / %u.%u / %u\n",
00866                    min, sum / HZ, (sum * 100 / HZ) % 100, max);
00867 
00868     sum = 0;
00869     min = 0xFFFFFFFF;
00870     max = 0;
00871     pos = master->eoe_cycle_time_pos;
00872     for (i = 0; i < HZ; i++) {
00873         cur = master->eoe_cycle_times[(i + pos) % HZ];
00874         sum += cur;
00875         if (cur < min) min = cur;
00876         if (cur > max) max = cur;
00877     }
00878     off += sprintf(buffer + off, "  EoE cycle: %u / %u.%u / %u\n",
00879                    min, sum / HZ, (sum * 100 / HZ) % 100, max);
00880 
00881     if (!list_empty(&master->eoe_handlers))
00882         off += sprintf(buffer + off, "\nEoE statistics (RX/TX) [bps]:\n");
00883     list_for_each_entry(eoe, &master->eoe_handlers, list) {
00884         off += sprintf(buffer + off, "  %s: %u / %u (%u KB/s)\n",
00885                        eoe->dev->name, eoe->rx_rate, eoe->tx_rate,
00886                        ((eoe->rx_rate + eoe->tx_rate) / 8 + 512) / 1024);
00887     }
00888 
00889     off += sprintf(buffer + off, "\n");
00890 
00891     return off;
00892 }
00893 
00894 /*****************************************************************************/
00895 
00901 ssize_t ec_show_master_attribute(struct kobject *kobj, 
00902                                  struct attribute *attr, 
00903                                  char *buffer 
00904                                  )
00905 {
00906     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00907 
00908     if (attr == &attr_info) {
00909         return ec_master_info(master, buffer);
00910     }
00911     else if (attr == &attr_debug_level) {
00912         return sprintf(buffer, "%i\n", master->debug_level);
00913     }
00914     else if (attr == &attr_eeprom_write_enable) {
00915         return sprintf(buffer, "%i\n", master->eeprom_write_enable);
00916     }
00917 
00918     return 0;
00919 }
00920 
00921 /*****************************************************************************/
00922 
00928 ssize_t ec_store_master_attribute(struct kobject *kobj, 
00929                                   struct attribute *attr, 
00930                                   const char *buffer, 
00931                                   size_t size 
00932                                   )
00933 {
00934     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00935 
00936     if (attr == &attr_eeprom_write_enable) {
00937         if (!strcmp(buffer, "1\n")) {
00938             master->eeprom_write_enable = 1;
00939             EC_INFO("Slave EEPROM writing enabled.\n");
00940             return size;
00941         }
00942         else if (!strcmp(buffer, "0\n")) {
00943             master->eeprom_write_enable = 0;
00944             EC_INFO("Slave EEPROM writing disabled.\n");
00945             return size;
00946         }
00947 
00948         EC_ERR("Invalid value for eeprom_write_enable!\n");
00949 
00950         if (master->eeprom_write_enable) {
00951             master->eeprom_write_enable = 0;
00952             EC_INFO("Slave EEPROM writing disabled.\n");
00953         }
00954     }
00955     else if (attr == &attr_debug_level) {
00956         if (!strcmp(buffer, "0\n")) {
00957             master->debug_level = 0;
00958         }
00959         else if (!strcmp(buffer, "1\n")) {
00960             master->debug_level = 1;
00961         }
00962         else if (!strcmp(buffer, "2\n")) {
00963             master->debug_level = 2;
00964         }
00965         else {
00966             EC_ERR("Invalid debug level value!\n");
00967             return -EINVAL;
00968         }
00969 
00970         EC_INFO("Master debug level set to %i.\n", master->debug_level);
00971         return size;
00972     }
00973 
00974     return -EINVAL;
00975 }
00976 
00977 /*****************************************************************************/
00978 
00983 void ec_master_eoe_start(ec_master_t *master )
00984 {
00985     ec_eoe_t *eoe;
00986     ec_slave_t *slave;
00987     unsigned int coupled, found;
00988 
00989     if (master->eoe_running || master->eoe_checked) return;
00990 
00991     master->eoe_checked = 1;
00992 
00993     // if the locking callbacks are not set in operation mode,
00994     // the EoE timer my not be started.
00995     if (master->mode == EC_MASTER_MODE_OPERATION
00996         && (!master->request_cb || !master->release_cb)) {
00997         EC_INFO("No EoE processing because of missing locking callbacks.\n");
00998         return;
00999     }
01000 
01001     // decouple all EoE handlers
01002     list_for_each_entry(eoe, &master->eoe_handlers, list)
01003         eoe->slave = NULL;
01004 
01005     // couple a free EoE handler to every EoE-capable slave
01006     coupled = 0;
01007     list_for_each_entry(slave, &master->slaves, list) {
01008         if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
01009 
01010         found = 0;
01011         list_for_each_entry(eoe, &master->eoe_handlers, list) {
01012             if (eoe->slave) continue;
01013             eoe->slave = slave;
01014             found = 1;
01015             coupled++;
01016             EC_INFO("Coupling device %s to slave %i.\n",
01017                     eoe->dev->name, slave->ring_position);
01018             if (eoe->opened)
01019                 ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
01020             else
01021                 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
01022             break;
01023         }
01024 
01025         if (!found) {
01026             if (master->debug_level)
01027                 EC_WARN("No EoE handler for slave %i!\n",
01028                         slave->ring_position);
01029             ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
01030         }
01031     }
01032 
01033     if (!coupled) {
01034         EC_INFO("No EoE handlers coupled.\n");
01035         return;
01036     }
01037 
01038     EC_INFO("Starting EoE processing.\n");
01039     master->eoe_running = 1;
01040 
01041     // start EoE processing
01042     master->eoe_timer.expires = jiffies + 10;
01043     add_timer(&master->eoe_timer);
01044     return;
01045 }
01046 
01047 /*****************************************************************************/
01048 
01053 void ec_master_eoe_stop(ec_master_t *master )
01054 {
01055     ec_eoe_t *eoe;
01056 
01057     master->eoe_checked = 0;
01058 
01059     if (!master->eoe_running) return;
01060 
01061     EC_INFO("Stopping EoE processing.\n");
01062 
01063     del_timer_sync(&master->eoe_timer);
01064 
01065     // decouple all EoE handlers
01066     list_for_each_entry(eoe, &master->eoe_handlers, list) {
01067         if (eoe->slave) {
01068             ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_PREOP);
01069             eoe->slave = NULL;
01070         }
01071     }
01072 
01073     master->eoe_running = 0;
01074 }
01075 
01076 /*****************************************************************************/
01077 
01082 void ec_master_eoe_run(unsigned long data )
01083 {
01084     ec_master_t *master = (ec_master_t *) data;
01085     ec_eoe_t *eoe;
01086     unsigned int active = 0;
01087     cycles_t cycles_start, cycles_end;
01088     unsigned long restart_jiffies;
01089 
01090     list_for_each_entry(eoe, &master->eoe_handlers, list) {
01091         if (ec_eoe_active(eoe)) active++;
01092     }
01093     if (!active) goto queue_timer;
01094 
01095     // aquire master lock...
01096     if (master->mode == EC_MASTER_MODE_OPERATION) {
01097         // request_cb must return 0, if the lock has been aquired!
01098         if (master->request_cb(master->cb_data))
01099             goto queue_timer;
01100     }
01101     else if (master->mode == EC_MASTER_MODE_IDLE) {
01102         spin_lock(&master->internal_lock);
01103     }
01104     else
01105         goto queue_timer;
01106 
01107     // actual EoE processing
01108     cycles_start = get_cycles();
01109     ecrt_master_receive(master);
01110 
01111     list_for_each_entry(eoe, &master->eoe_handlers, list) {
01112         ec_eoe_run(eoe);
01113     }
01114 
01115     ecrt_master_send(master);
01116     cycles_end = get_cycles();
01117 
01118     // release lock...
01119     if (master->mode == EC_MASTER_MODE_OPERATION) {
01120         master->release_cb(master->cb_data);
01121     }
01122     else if (master->mode == EC_MASTER_MODE_IDLE) {
01123         spin_unlock(&master->internal_lock);
01124     }
01125 
01126     master->eoe_cycle_times[master->eoe_cycle_time_pos]
01127         = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
01128     master->eoe_cycle_time_pos++;
01129     master->eoe_cycle_time_pos %= HZ;
01130 
01131  queue_timer:
01132     restart_jiffies = HZ / EC_EOE_FREQUENCY;
01133     if (!restart_jiffies) restart_jiffies = 1;
01134     master->eoe_timer.expires += restart_jiffies;
01135     add_timer(&master->eoe_timer);
01136 }
01137 
01138 /*****************************************************************************/
01139 
01143 void ec_master_check_sdo(unsigned long data )
01144 {
01145     ec_master_t *master = (ec_master_t *) data;
01146 
01147     if (master->sdo_seq_master != master->sdo_seq_user) {
01148         master->sdo_timer.expires = jiffies + 10;
01149         add_timer(&master->sdo_timer);
01150         return;
01151     }
01152 
01153     // master has processed the request
01154     complete(&master->sdo_complete);
01155 }
01156 
01157 /*****************************************************************************/
01158 
01163 void ec_master_calc_addressing(ec_master_t *master )
01164 {
01165     uint16_t coupler_index, coupler_subindex;
01166     uint16_t reverse_coupler_index, current_coupler_index;
01167     ec_slave_t *slave;
01168 
01169     coupler_index = 0;
01170     reverse_coupler_index = 0xFFFF;
01171     current_coupler_index = 0x0000;
01172     coupler_subindex = 0;
01173 
01174     list_for_each_entry(slave, &master->slaves, list) {
01175         if (ec_slave_is_coupler(slave)) {
01176             if (slave->sii_alias)
01177                 current_coupler_index = reverse_coupler_index--;
01178             else
01179                 current_coupler_index = coupler_index++;
01180             coupler_subindex = 0;
01181         }
01182 
01183         slave->coupler_index = current_coupler_index;
01184         slave->coupler_subindex = coupler_subindex;
01185         coupler_subindex++;
01186     }
01187 }
01188 
01189 /*****************************************************************************/
01190 
01196 int ec_master_measure_bus_time(ec_master_t *master)
01197 {
01198     ec_datagram_t datagram;
01199     uint32_t cur, sum, min, max, i;
01200 
01201     ec_datagram_init(&datagram);
01202 
01203     if (ec_datagram_brd(&datagram, 0x130, 2)) {
01204         EC_ERR("Failed to allocate datagram for bus time measuring.\n");
01205         ec_datagram_clear(&datagram);
01206         return -1;
01207     }
01208 
01209     ecrt_master_receive(master);
01210 
01211     sum = 0;
01212     min = 0xFFFFFFFF;
01213     max = 0;
01214 
01215     for (i = 0; i < 100; i++) {
01216         ec_master_queue_datagram(master, &datagram);
01217         ecrt_master_send(master);
01218 
01219         while (1) {
01220             ecrt_master_receive(master);
01221 
01222             if (datagram.state == EC_DATAGRAM_RECEIVED) {
01223                 break;
01224             }
01225             else if (datagram.state == EC_DATAGRAM_ERROR) {
01226                 EC_WARN("Failed to measure bus time.\n");
01227                 goto error;
01228             }
01229             else if (datagram.state == EC_DATAGRAM_TIMED_OUT) {
01230                 EC_WARN("Timeout while measuring bus time.\n");
01231                 goto error;
01232             }
01233         }
01234 
01235         cur = (unsigned int) (datagram.cycles_received
01236                               - datagram.cycles_sent) * 1000 / cpu_khz;
01237         sum += cur;
01238         if (cur > max) max = cur;
01239         if (cur < min) min = cur;
01240     }
01241 
01242     EC_DBG("Bus time is (min/avg/max) %u / %u.%u / %u us.\n",
01243            min, sum / 100, sum % 100, max);
01244     ec_datagram_clear(&datagram);
01245     return 0;
01246 
01247   error:
01248     ec_datagram_clear(&datagram);
01249     return -1;
01250 }
01251 
01252 /******************************************************************************
01253  *  Realtime interface
01254  *****************************************************************************/
01255 
01262 ec_domain_t *ecrt_master_create_domain(ec_master_t *master )
01263 {
01264     ec_domain_t *domain, *last_domain;
01265     unsigned int index;
01266 
01267     if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) {
01268         EC_ERR("Error allocating domain memory!\n");
01269         return NULL;
01270     }
01271 
01272     if (list_empty(&master->domains)) index = 0;
01273     else {
01274         last_domain = list_entry(master->domains.prev, ec_domain_t, list);
01275         index = last_domain->index + 1;
01276     }
01277 
01278     if (ec_domain_init(domain, master, index)) {
01279         EC_ERR("Failed to init domain.\n");
01280         return NULL;
01281     }
01282 
01283     list_add_tail(&domain->list, &master->domains);
01284 
01285     return domain;
01286 }
01287 
01288 /*****************************************************************************/
01289 
01299 int ecrt_master_activate(ec_master_t *master )
01300 {
01301     uint32_t domain_offset;
01302     ec_domain_t *domain;
01303     ec_fsm_t *fsm = &master->fsm;
01304     ec_slave_t *slave;
01305 
01306     // allocate all domains
01307     domain_offset = 0;
01308     list_for_each_entry(domain, &master->domains, list) {
01309         if (ec_domain_alloc(domain, domain_offset)) {
01310             EC_ERR("Failed to allocate domain %X!\n", (u32) domain);
01311             return -1;
01312         }
01313         domain_offset += domain->data_size;
01314     }
01315 
01316     // configure all slaves
01317     list_for_each_entry(slave, &master->slaves, list) {
01318         fsm->slave = slave;
01319         fsm->slave_state = ec_fsm_slaveconf_state_start;
01320 
01321         do {
01322             fsm->slave_state(fsm);
01323             ec_master_sync_io(master);
01324         }
01325         while (fsm->slave_state != ec_fsm_slave_state_end
01326                && fsm->slave_state != ec_fsm_slave_state_error);
01327 
01328         if (fsm->slave_state == ec_fsm_slave_state_error) {
01329             EC_ERR("Failed to configure slave %i!\n", slave->ring_position);
01330             return -1;
01331         }
01332     }
01333 
01334     return 0;
01335 }
01336 
01337 /*****************************************************************************/
01338 
01347 void ecrt_master_deactivate(ec_master_t *master )
01348 {
01349 }
01350 
01351 /*****************************************************************************/
01352 
01357 void ec_master_sync_io(ec_master_t *master )
01358 {
01359     ec_datagram_t *datagram;
01360     unsigned int datagrams_waiting;
01361 
01362     // send datagrams
01363     ecrt_master_send(master);
01364 
01365     while (1) { // active waiting
01366         ecrt_master_receive(master); // receive and dequeue datagrams
01367 
01368         // count number of datagrams still waiting for response
01369         datagrams_waiting = 0;
01370         list_for_each_entry(datagram, &master->datagram_queue, queue) {
01371             datagrams_waiting++;
01372         }
01373 
01374         // if there are no more datagrams waiting, abort loop.
01375         if (!datagrams_waiting) break;
01376     }
01377 }
01378 
01379 /*****************************************************************************/
01380 
01386 void ecrt_master_send(ec_master_t *master )
01387 {
01388     ec_datagram_t *datagram, *n;
01389 
01390     if (unlikely(!master->device->link_state)) {
01391         // link is down, no datagram can be sent
01392         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
01393             datagram->state = EC_DATAGRAM_ERROR;
01394             list_del_init(&datagram->queue);
01395         }
01396 
01397         // query link state
01398         ec_device_call_isr(master->device);
01399         return;
01400     }
01401 
01402     // send frames
01403     ec_master_send_datagrams(master);
01404 }
01405 
01406 /*****************************************************************************/
01407 
01413 void ecrt_master_receive(ec_master_t *master )
01414 {
01415     ec_datagram_t *datagram, *next;
01416     cycles_t cycles_timeout;
01417 
01418     // receive datagrams
01419     ec_device_call_isr(master->device);
01420 
01421     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
01422 
01423     // dequeue all datagrams that timed out
01424     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
01425         switch (datagram->state) {
01426             case EC_DATAGRAM_QUEUED:
01427                 if (master->device->cycles_isr
01428                     - datagram->cycles_queued > cycles_timeout) {
01429                     list_del_init(&datagram->queue);
01430                     datagram->state = EC_DATAGRAM_TIMED_OUT;
01431                     master->stats.timeouts++;
01432                     ec_master_output_stats(master);
01433                 }
01434                 break;
01435             case EC_DATAGRAM_SENT:
01436                 if (master->device->cycles_isr
01437                     - datagram->cycles_sent > cycles_timeout) {
01438                     list_del_init(&datagram->queue);
01439                     datagram->state = EC_DATAGRAM_TIMED_OUT;
01440                     master->stats.timeouts++;
01441                     ec_master_output_stats(master);
01442                 }
01443                 break;
01444             default:
01445                 break;
01446         }
01447     }
01448 }
01449 
01450 /*****************************************************************************/
01451 
01459 void ecrt_master_prepare(ec_master_t *master )
01460 {
01461     ec_domain_t *domain;
01462     cycles_t cycles_start, cycles_end, cycles_timeout;
01463 
01464     // queue datagrams of all domains
01465     list_for_each_entry(domain, &master->domains, list)
01466         ec_domain_queue_datagrams(domain);
01467 
01468     ecrt_master_send(master);
01469 
01470     cycles_start = get_cycles();
01471     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
01472 
01473     // active waiting
01474     while (1) {
01475         udelay(100);
01476         cycles_end = get_cycles();
01477         if (cycles_end - cycles_start >= cycles_timeout) break;
01478     }
01479 }
01480 
01481 /*****************************************************************************/
01482 
01488 void ecrt_master_run(ec_master_t *master )
01489 {
01490     // output statistics
01491     ec_master_output_stats(master);
01492 
01493     // execute master state machine in a loop
01494     ec_fsm_exec(&master->fsm);
01495 }
01496 
01497 /*****************************************************************************/
01498 
01512 ec_slave_t *ecrt_master_get_slave(const ec_master_t *master, 
01513                                   const char *address 
01514                                   )
01515 {
01516     unsigned long first, second;
01517     char *remainder, *remainder2;
01518     unsigned int alias_requested, alias_found;
01519     ec_slave_t *alias_slave = NULL, *slave;
01520 
01521     if (!address || address[0] == 0) return NULL;
01522 
01523     alias_requested = 0;
01524     if (address[0] == '#') {
01525         alias_requested = 1;
01526         address++;
01527     }
01528 
01529     first = simple_strtoul(address, &remainder, 0);
01530     if (remainder == address) {
01531         EC_ERR("Slave address \"%s\" - First number empty!\n", address);
01532         return NULL;
01533     }
01534 
01535     if (alias_requested) {
01536         alias_found = 0;
01537         list_for_each_entry(alias_slave, &master->slaves, list) {
01538             if (alias_slave->sii_alias == first) {
01539                 alias_found = 1;
01540                 break;
01541             }
01542         }
01543         if (!alias_found) {
01544             EC_ERR("Slave address \"%s\" - Alias not found!\n", address);
01545             return NULL;
01546         }
01547     }
01548 
01549     if (!remainder[0]) { // absolute position
01550         if (alias_requested) {
01551             return alias_slave;
01552         }
01553         else {
01554             list_for_each_entry(slave, &master->slaves, list) {
01555                 if (slave->ring_position == first) return slave;
01556             }
01557             EC_ERR("Slave address \"%s\" - Absolute position invalid!\n",
01558                    address);
01559         }
01560     }
01561     else if (remainder[0] == ':') { // field position
01562         remainder++;
01563         second = simple_strtoul(remainder, &remainder2, 0);
01564 
01565         if (remainder2 == remainder) {
01566             EC_ERR("Slave address \"%s\" - Second number empty!\n", address);
01567             return NULL;
01568         }
01569 
01570         if (remainder2[0]) {
01571             EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address);
01572             return NULL;
01573         }
01574 
01575         if (alias_requested) {
01576             if (!ec_slave_is_coupler(alias_slave)) {
01577                 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler"
01578                        " in colon mode.\n", address);
01579                 return NULL;
01580             }
01581             list_for_each_entry(slave, &master->slaves, list) {
01582                 if (slave->coupler_index == alias_slave->coupler_index
01583                     && slave->coupler_subindex == second)
01584                     return slave;
01585             }
01586             EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave"
01587                    " following!\n", address, alias_slave->ring_position,
01588                    second);
01589             return NULL;
01590         }
01591         else {
01592             list_for_each_entry(slave, &master->slaves, list) {
01593                 if (slave->coupler_index == first
01594                     && slave->coupler_subindex == second) return slave;
01595             }
01596         }
01597     }
01598     else
01599         EC_ERR("Slave address \"%s\" - Invalid format!\n", address);
01600 
01601     return NULL;
01602 }
01603 
01604 /*****************************************************************************/
01605 
01614 void ecrt_master_callbacks(ec_master_t *master, 
01615                            int (*request_cb)(void *), 
01616                            void (*release_cb)(void *), 
01617                            void *cb_data 
01618                            )
01619 {
01620     master->request_cb = request_cb;
01621     master->release_cb = release_cb;
01622     master->cb_data = cb_data;
01623 }
01624 
01625 /*****************************************************************************/
01626 
01629 EXPORT_SYMBOL(ecrt_master_create_domain);
01630 EXPORT_SYMBOL(ecrt_master_activate);
01631 EXPORT_SYMBOL(ecrt_master_deactivate);
01632 EXPORT_SYMBOL(ecrt_master_prepare);
01633 EXPORT_SYMBOL(ecrt_master_send);
01634 EXPORT_SYMBOL(ecrt_master_receive);
01635 EXPORT_SYMBOL(ecrt_master_run);
01636 EXPORT_SYMBOL(ecrt_master_callbacks);
01637 EXPORT_SYMBOL(ecrt_master_get_slave);
01638 
01641 /*****************************************************************************/

Generated on Tue Nov 7 15:03:36 2006 for IgH EtherCAT master by  doxygen 1.4.4