master.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: master.c 490 2006-08-02 12:25:25Z 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 "types.h"
00052 #include "device.h"
00053 #include "datagram.h"
00054 #include "ethernet.h"
00055 
00056 /*****************************************************************************/
00057 
00058 void ec_master_idle_run(void *);
00059 void ec_master_eoe_run(unsigned long);
00060 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
00061 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
00062                                   const char *, size_t);
00063 
00064 /*****************************************************************************/
00065 
00068 EC_SYSFS_READ_ATTR(slave_count);
00069 EC_SYSFS_READ_ATTR(mode);
00070 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable);
00071 EC_SYSFS_READ_WRITE_ATTR(debug_level);
00072 
00073 static struct attribute *ec_def_attrs[] = {
00074     &attr_slave_count,
00075     &attr_mode,
00076     &attr_eeprom_write_enable,
00077     &attr_debug_level,
00078     NULL,
00079 };
00080 
00081 static struct sysfs_ops ec_sysfs_ops = {
00082     .show = &ec_show_master_attribute,
00083     .store = ec_store_master_attribute
00084 };
00085 
00086 static struct kobj_type ktype_ec_master = {
00087     .release = ec_master_clear,
00088     .sysfs_ops = &ec_sysfs_ops,
00089     .default_attrs = ec_def_attrs
00090 };
00091 
00094 /*****************************************************************************/
00095 
00101 int ec_master_init(ec_master_t *master, 
00102                    unsigned int index, 
00103                    unsigned int eoeif_count 
00104                    )
00105 {
00106     ec_eoe_t *eoe, *next_eoe;
00107     unsigned int i;
00108 
00109     EC_INFO("Initializing master %i.\n", index);
00110 
00111     master->index = index;
00112     master->device = NULL;
00113     master->reserved = 0;
00114     INIT_LIST_HEAD(&master->slaves);
00115     INIT_LIST_HEAD(&master->datagram_queue);
00116     INIT_LIST_HEAD(&master->domains);
00117     INIT_LIST_HEAD(&master->eoe_handlers);
00118     ec_datagram_init(&master->simple_datagram);
00119     INIT_WORK(&master->idle_work, ec_master_idle_run, (void *) master);
00120     init_timer(&master->eoe_timer);
00121     master->eoe_timer.function = ec_master_eoe_run;
00122     master->eoe_timer.data = (unsigned long) master;
00123     master->internal_lock = SPIN_LOCK_UNLOCKED;
00124     master->eoe_running = 0;
00125 
00126     // create workqueue
00127     if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) {
00128         EC_ERR("Failed to create master workqueue.\n");
00129         goto out_return;
00130     }
00131 
00132     // create EoE handlers
00133     for (i = 0; i < eoeif_count; i++) {
00134         if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
00135             EC_ERR("Failed to allocate EoE-Object.\n");
00136             goto out_clear_eoe;
00137         }
00138         if (ec_eoe_init(eoe)) {
00139             kfree(eoe);
00140             goto out_clear_eoe;
00141         }
00142         list_add_tail(&eoe->list, &master->eoe_handlers);
00143     }
00144 
00145     // create state machine object
00146     if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe;
00147 
00148     // init kobject and add it to the hierarchy
00149     memset(&master->kobj, 0x00, sizeof(struct kobject));
00150     kobject_init(&master->kobj);
00151     master->kobj.ktype = &ktype_ec_master;
00152     if (kobject_set_name(&master->kobj, "ethercat%i", index)) {
00153         EC_ERR("Failed to set kobj name.\n");
00154         kobject_put(&master->kobj);
00155         return -1;
00156     }
00157 
00158     ec_master_reset(master);
00159     return 0;
00160 
00161  out_clear_eoe:
00162     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
00163         list_del(&eoe->list);
00164         ec_eoe_clear(eoe);
00165         kfree(eoe);
00166     }
00167     destroy_workqueue(master->workqueue);
00168  out_return:
00169     return -1;
00170 }
00171 
00172 /*****************************************************************************/
00173 
00180 void ec_master_clear(struct kobject *kobj )
00181 {
00182     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00183     ec_eoe_t *eoe, *next_eoe;
00184 
00185     EC_INFO("Clearing master %i...\n", master->index);
00186 
00187     ec_master_reset(master);
00188     ec_fsm_clear(&master->fsm);
00189     ec_datagram_clear(&master->simple_datagram);
00190     destroy_workqueue(master->workqueue);
00191 
00192     // clear EoE objects
00193     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
00194         list_del(&eoe->list);
00195         ec_eoe_clear(eoe);
00196         kfree(eoe);
00197     }
00198 
00199     if (master->device) {
00200         ec_device_clear(master->device);
00201         kfree(master->device);
00202     }
00203 
00204     EC_INFO("Master %i cleared.\n", master->index);
00205 }
00206 
00207 /*****************************************************************************/
00208 
00215 void ec_master_reset(ec_master_t *master )
00216 {
00217     ec_datagram_t *datagram, *next_c;
00218     ec_domain_t *domain, *next_d;
00219 
00220     ec_master_eoe_stop(master);
00221     ec_master_idle_stop(master);
00222     ec_master_clear_slaves(master);
00223 
00224     // empty datagram queue
00225     list_for_each_entry_safe(datagram, next_c,
00226                              &master->datagram_queue, queue) {
00227         list_del_init(&datagram->queue);
00228         datagram->state = EC_CMD_ERROR;
00229     }
00230 
00231     // clear domains
00232     list_for_each_entry_safe(domain, next_d, &master->domains, list) {
00233         list_del(&domain->list);
00234         kobject_del(&domain->kobj);
00235         kobject_put(&domain->kobj);
00236     }
00237 
00238     master->datagram_index = 0;
00239     master->debug_level = 0;
00240     master->timeout = 500; // 500us
00241 
00242     master->stats.timeouts = 0;
00243     master->stats.delayed = 0;
00244     master->stats.corrupted = 0;
00245     master->stats.unmatched = 0;
00246     master->stats.t_last = 0;
00247 
00248     master->mode = EC_MASTER_MODE_ORPHANED;
00249 
00250     master->request_cb = NULL;
00251     master->release_cb = NULL;
00252     master->cb_data = NULL;
00253 
00254     master->eeprom_write_enable = 0;
00255 
00256     ec_fsm_reset(&master->fsm);
00257 }
00258 
00259 /*****************************************************************************/
00260 
00265 void ec_master_clear_slaves(ec_master_t *master)
00266 {
00267     ec_slave_t *slave, *next_slave;
00268 
00269     list_for_each_entry_safe(slave, next_slave, &master->slaves, list) {
00270         list_del(&slave->list);
00271         kobject_del(&slave->kobj);
00272         kobject_put(&slave->kobj);
00273     }
00274     master->slave_count = 0;
00275 }
00276 
00277 /*****************************************************************************/
00278 
00283 void ec_master_queue_datagram(ec_master_t *master, 
00284                               ec_datagram_t *datagram 
00285                               )
00286 {
00287     ec_datagram_t *queued_datagram;
00288 
00289     // check, if the datagram is already queued
00290     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
00291         if (queued_datagram == datagram) {
00292             datagram->state = EC_CMD_QUEUED;
00293             if (unlikely(master->debug_level))
00294                 EC_WARN("datagram already queued.\n");
00295             return;
00296         }
00297     }
00298 
00299     list_add_tail(&datagram->queue, &master->datagram_queue);
00300     datagram->state = EC_CMD_QUEUED;
00301 }
00302 
00303 /*****************************************************************************/
00304 
00310 void ec_master_send_datagrams(ec_master_t *master )
00311 {
00312     ec_datagram_t *datagram;
00313     size_t datagram_size;
00314     uint8_t *frame_data, *cur_data;
00315     void *follows_word;
00316     cycles_t t_start, t_end;
00317     unsigned int frame_count, more_datagrams_waiting;
00318 
00319     frame_count = 0;
00320     t_start = get_cycles();
00321 
00322     if (unlikely(master->debug_level > 1))
00323         EC_DBG("ec_master_send_datagrams\n");
00324 
00325     do {
00326         // fetch pointer to transmit socket buffer
00327         frame_data = ec_device_tx_data(master->device);
00328         cur_data = frame_data + EC_FRAME_HEADER_SIZE;
00329         follows_word = NULL;
00330         more_datagrams_waiting = 0;
00331 
00332         // fill current frame with datagrams
00333         list_for_each_entry(datagram, &master->datagram_queue, queue) {
00334             if (datagram->state != EC_CMD_QUEUED) continue;
00335 
00336             // does the current datagram fit in the frame?
00337             datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
00338                 + EC_DATAGRAM_FOOTER_SIZE;
00339             if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
00340                 more_datagrams_waiting = 1;
00341                 break;
00342             }
00343 
00344             datagram->state = EC_CMD_SENT;
00345             datagram->t_sent = t_start;
00346             datagram->index = master->datagram_index++;
00347 
00348             if (unlikely(master->debug_level > 1))
00349                 EC_DBG("adding datagram 0x%02X\n", datagram->index);
00350 
00351             // set "datagram following" flag in previous frame
00352             if (follows_word)
00353                 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000);
00354 
00355             // EtherCAT datagram header
00356             EC_WRITE_U8 (cur_data,     datagram->type);
00357             EC_WRITE_U8 (cur_data + 1, datagram->index);
00358             EC_WRITE_U32(cur_data + 2, datagram->address.logical);
00359             EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
00360             EC_WRITE_U16(cur_data + 8, 0x0000);
00361             follows_word = cur_data + 6;
00362             cur_data += EC_DATAGRAM_HEADER_SIZE;
00363 
00364             // EtherCAT datagram data
00365             memcpy(cur_data, datagram->data, datagram->data_size);
00366             cur_data += datagram->data_size;
00367 
00368             // EtherCAT datagram footer
00369             EC_WRITE_U16(cur_data, 0x0000); // reset working counter
00370             cur_data += EC_DATAGRAM_FOOTER_SIZE;
00371         }
00372 
00373         if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) {
00374             if (unlikely(master->debug_level > 1))
00375                 EC_DBG("nothing to send.\n");
00376             break;
00377         }
00378 
00379         // EtherCAT frame header
00380         EC_WRITE_U16(frame_data, ((cur_data - frame_data
00381                                    - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
00382 
00383         // pad frame
00384         while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
00385             EC_WRITE_U8(cur_data++, 0x00);
00386 
00387         if (unlikely(master->debug_level > 1))
00388             EC_DBG("frame size: %i\n", cur_data - frame_data);
00389 
00390         // send frame
00391         ec_device_send(master->device, cur_data - frame_data);
00392         frame_count++;
00393     }
00394     while (more_datagrams_waiting);
00395 
00396     if (unlikely(master->debug_level > 1)) {
00397         t_end = get_cycles();
00398         EC_DBG("ec_master_send_datagrams sent %i frames in %ius.\n",
00399                frame_count, (unsigned int) (t_end - t_start) * 1000 / cpu_khz);
00400     }
00401 }
00402 
00403 /*****************************************************************************/
00404 
00411 void ec_master_receive(ec_master_t *master, 
00412                        const uint8_t *frame_data, 
00413                        size_t size 
00414                        )
00415 {
00416     size_t frame_size, data_size;
00417     uint8_t datagram_type, datagram_index;
00418     unsigned int cmd_follows, matched;
00419     const uint8_t *cur_data;
00420     ec_datagram_t *datagram;
00421 
00422     if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
00423         master->stats.corrupted++;
00424         ec_master_output_stats(master);
00425         return;
00426     }
00427 
00428     cur_data = frame_data;
00429 
00430     // check length of entire frame
00431     frame_size = EC_READ_U16(cur_data) & 0x07FF;
00432     cur_data += EC_FRAME_HEADER_SIZE;
00433 
00434     if (unlikely(frame_size > size)) {
00435         master->stats.corrupted++;
00436         ec_master_output_stats(master);
00437         return;
00438     }
00439 
00440     cmd_follows = 1;
00441     while (cmd_follows) {
00442         // process datagram header
00443         datagram_type  = EC_READ_U8 (cur_data);
00444         datagram_index = EC_READ_U8 (cur_data + 1);
00445         data_size      = EC_READ_U16(cur_data + 6) & 0x07FF;
00446         cmd_follows    = EC_READ_U16(cur_data + 6) & 0x8000;
00447         cur_data += EC_DATAGRAM_HEADER_SIZE;
00448 
00449         if (unlikely(cur_data - frame_data
00450                      + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
00451             master->stats.corrupted++;
00452             ec_master_output_stats(master);
00453             return;
00454         }
00455 
00456         // search for matching datagram in the queue
00457         matched = 0;
00458         list_for_each_entry(datagram, &master->datagram_queue, queue) {
00459             if (datagram->state == EC_CMD_SENT
00460                 && datagram->type == datagram_type
00461                 && datagram->index == datagram_index
00462                 && datagram->data_size == data_size) {
00463                 matched = 1;
00464                 break;
00465             }
00466         }
00467 
00468         // no matching datagram was found
00469         if (!matched) {
00470             master->stats.unmatched++;
00471             ec_master_output_stats(master);
00472             cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
00473             continue;
00474         }
00475 
00476         // copy received data in the datagram memory
00477         memcpy(datagram->data, cur_data, data_size);
00478         cur_data += data_size;
00479 
00480         // set the datagram's working counter
00481         datagram->working_counter = EC_READ_U16(cur_data);
00482         cur_data += EC_DATAGRAM_FOOTER_SIZE;
00483 
00484         // dequeue the received datagram
00485         datagram->state = EC_CMD_RECEIVED;
00486         list_del_init(&datagram->queue);
00487     }
00488 }
00489 
00490 /*****************************************************************************/
00491 
00498 int ec_master_simple_io(ec_master_t *master, 
00499                         ec_datagram_t *datagram 
00500                         )
00501 {
00502     unsigned int response_tries_left;
00503 
00504     response_tries_left = 10000;
00505 
00506     while (1)
00507     {
00508         ec_master_queue_datagram(master, datagram);
00509         ecrt_master_sync_io(master);
00510 
00511         if (datagram->state == EC_CMD_RECEIVED) {
00512             if (likely(datagram->working_counter))
00513                 return 0;
00514         }
00515         else if (datagram->state == EC_CMD_TIMEOUT) {
00516             EC_ERR("Simple-IO TIMEOUT!\n");
00517             return -1;
00518         }
00519         else if (datagram->state == EC_CMD_ERROR) {
00520             EC_ERR("Simple-IO datagram error!\n");
00521             return -1;
00522         }
00523 
00524         // no direct response, wait a little bit...
00525         udelay(100);
00526 
00527         if (unlikely(--response_tries_left)) {
00528             EC_ERR("No response in simple-IO!\n");
00529             return -1;
00530         }
00531     }
00532 }
00533 
00534 /*****************************************************************************/
00535 
00542 int ec_master_bus_scan(ec_master_t *master )
00543 {
00544     ec_slave_t *slave;
00545     ec_slave_ident_t *ident;
00546     ec_datagram_t *datagram;
00547     unsigned int i;
00548     uint16_t coupler_index, coupler_subindex;
00549     uint16_t reverse_coupler_index, current_coupler_index;
00550 
00551     if (!list_empty(&master->slaves)) {
00552         EC_ERR("Slave scan already done!\n");
00553         return -1;
00554     }
00555 
00556     datagram = &master->simple_datagram;
00557 
00558     // determine number of slaves on bus
00559     if (ec_datagram_brd(datagram, 0x0000, 4)) return -1;
00560     if (unlikely(ec_master_simple_io(master, datagram))) return -1;
00561     master->slave_count = datagram->working_counter;
00562     EC_INFO("Found %i slaves on bus.\n", master->slave_count);
00563 
00564     if (!master->slave_count) return 0;
00565 
00566     // init slaves
00567     for (i = 0; i < master->slave_count; i++) {
00568         if (!(slave =
00569               (ec_slave_t *) kmalloc(sizeof(ec_slave_t), GFP_KERNEL))) {
00570             EC_ERR("Failed to allocate slave %i!\n", i);
00571             goto out_free;
00572         }
00573 
00574         if (ec_slave_init(slave, master, i, i + 1)) goto out_free;
00575 
00576         if (kobject_add(&slave->kobj)) {
00577             EC_ERR("Failed to add kobject.\n");
00578             kobject_put(&slave->kobj); // free
00579             goto out_free;
00580         }
00581 
00582         list_add_tail(&slave->list, &master->slaves);
00583     }
00584 
00585     coupler_index = 0;
00586     reverse_coupler_index = 0xFFFF;
00587     current_coupler_index = 0x3FFF;
00588     coupler_subindex = 0;
00589 
00590     // for every slave on the bus
00591     list_for_each_entry(slave, &master->slaves, list) {
00592 
00593         // write station address
00594         if (ec_datagram_apwr(datagram, slave->ring_position, 0x0010,
00595                             sizeof(uint16_t))) goto out_free;
00596         EC_WRITE_U16(datagram->data, slave->station_address);
00597         if (unlikely(ec_master_simple_io(master, datagram))) {
00598             EC_ERR("Writing station address failed on slave %i!\n",
00599                    slave->ring_position);
00600             goto out_free;
00601         }
00602 
00603         // fetch all slave information
00604         if (ec_slave_fetch(slave)) goto out_free;
00605 
00606         // search for identification in "database"
00607         ident = slave_idents;
00608         while (ident->type) {
00609             if (unlikely(ident->vendor_id == slave->sii_vendor_id
00610                          && ident->product_code == slave->sii_product_code)) {
00611                 slave->type = ident->type;
00612                 break;
00613             }
00614             ident++;
00615         }
00616 
00617         if (!slave->type) {
00618             EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at"
00619                     " position %i.\n", slave->sii_vendor_id,
00620                     slave->sii_product_code, slave->ring_position);
00621         }
00622         else if (slave->type->special == EC_TYPE_BUS_COUPLER) {
00623             if (slave->sii_alias)
00624                 current_coupler_index = reverse_coupler_index--;
00625             else
00626                 current_coupler_index = coupler_index++;
00627             coupler_subindex = 0;
00628         }
00629 
00630         slave->coupler_index = current_coupler_index;
00631         slave->coupler_subindex = coupler_subindex;
00632         coupler_subindex++;
00633     }
00634 
00635     return 0;
00636 
00637  out_free:
00638     ec_master_clear_slaves(master);
00639     return -1;
00640 }
00641 
00642 /*****************************************************************************/
00643 
00650 void ec_master_output_stats(ec_master_t *master )
00651 {
00652     cycles_t t_now = get_cycles();
00653 
00654     if (unlikely((u32) (t_now - master->stats.t_last) / cpu_khz > 1000)) {
00655         if (master->stats.timeouts) {
00656             EC_WARN("%i datagrams TIMED OUT!\n", master->stats.timeouts);
00657             master->stats.timeouts = 0;
00658         }
00659         if (master->stats.delayed) {
00660             EC_WARN("%i frame(s) DELAYED!\n", master->stats.delayed);
00661             master->stats.delayed = 0;
00662         }
00663         if (master->stats.corrupted) {
00664             EC_WARN("%i frame(s) CORRUPTED!\n", master->stats.corrupted);
00665             master->stats.corrupted = 0;
00666         }
00667         if (master->stats.unmatched) {
00668             EC_WARN("%i datagram(s) UNMATCHED!\n", master->stats.unmatched);
00669             master->stats.unmatched = 0;
00670         }
00671         master->stats.t_last = t_now;
00672     }
00673 }
00674 
00675 /*****************************************************************************/
00676 
00681 void ec_master_idle_start(ec_master_t *master )
00682 {
00683     if (master->mode == EC_MASTER_MODE_IDLE) return;
00684 
00685     if (master->mode == EC_MASTER_MODE_RUNNING) {
00686         EC_ERR("ec_master_idle_start: Master already running!\n");
00687         return;
00688     }
00689 
00690     EC_INFO("Starting Idle mode.\n");
00691 
00692     master->mode = EC_MASTER_MODE_IDLE;
00693     ec_fsm_reset(&master->fsm);
00694     queue_delayed_work(master->workqueue, &master->idle_work, 1);
00695 }
00696 
00697 /*****************************************************************************/
00698 
00703 void ec_master_idle_stop(ec_master_t *master )
00704 {
00705     if (master->mode != EC_MASTER_MODE_IDLE) return;
00706 
00707     ec_master_eoe_stop(master);
00708 
00709     EC_INFO("Stopping Idle mode.\n");
00710     master->mode = EC_MASTER_MODE_ORPHANED; // this is important for the
00711                                             // IDLE work function to not
00712                                             // queue itself again
00713 
00714     if (!cancel_delayed_work(&master->idle_work)) {
00715         flush_workqueue(master->workqueue);
00716     }
00717 
00718     ec_master_clear_slaves(master);
00719 }
00720 
00721 /*****************************************************************************/
00722 
00727 void ec_master_idle_run(void *data )
00728 {
00729     ec_master_t *master = (ec_master_t *) data;
00730 
00731     // aquire master lock
00732     spin_lock_bh(&master->internal_lock);
00733 
00734     ecrt_master_async_receive(master);
00735 
00736     // execute master state machine
00737     ec_fsm_execute(&master->fsm);
00738 
00739     ecrt_master_async_send(master);
00740 
00741     // release master lock
00742     spin_unlock_bh(&master->internal_lock);
00743 
00744     if (master->mode == EC_MASTER_MODE_IDLE)
00745         queue_delayed_work(master->workqueue, &master->idle_work, 1);
00746 }
00747 
00748 /*****************************************************************************/
00749 
00755 void ec_sync_config(const ec_sync_t *sync, 
00756                     const ec_slave_t *slave, 
00757                     uint8_t *data 
00758                     )
00759 {
00760     size_t sync_size;
00761 
00762     sync_size = ec_slave_calc_sync_size(slave, sync);
00763 
00764     EC_WRITE_U16(data,     sync->physical_start_address);
00765     EC_WRITE_U16(data + 2, sync_size);
00766     EC_WRITE_U8 (data + 4, sync->control_byte);
00767     EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
00768     EC_WRITE_U16(data + 6, 0x0001); // enable
00769 }
00770 
00771 /*****************************************************************************/
00772 
00778 void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, 
00779                            const ec_slave_t *slave, 
00780                            uint8_t *data 
00781                            )
00782 {
00783     size_t sync_size;
00784 
00785     sync_size = ec_slave_calc_eeprom_sync_size(slave, sync);
00786 
00787     if (slave->master->debug_level) {
00788         EC_INFO("Slave %i, sync manager %i:\n", slave->ring_position,
00789                 sync->index);
00790         EC_INFO("  Address: 0x%04X\n", sync->physical_start_address);
00791         EC_INFO("     Size: %i\n", sync_size);
00792         EC_INFO("  Control: 0x%02X\n", sync->control_register);
00793     }
00794 
00795     EC_WRITE_U16(data,     sync->physical_start_address);
00796     EC_WRITE_U16(data + 2, sync_size);
00797     EC_WRITE_U8 (data + 4, sync->control_register);
00798     EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
00799     EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable
00800 }
00801 
00802 /*****************************************************************************/
00803 
00809 void ec_fmmu_config(const ec_fmmu_t *fmmu, 
00810                     const ec_slave_t *slave, 
00811                     uint8_t *data 
00812                     )
00813 {
00814     size_t sync_size;
00815 
00816     sync_size = ec_slave_calc_sync_size(slave, fmmu->sync);
00817 
00818     EC_WRITE_U32(data,      fmmu->logical_start_address);
00819     EC_WRITE_U16(data + 4,  sync_size); // size of fmmu
00820     EC_WRITE_U8 (data + 6,  0x00); // logical start bit
00821     EC_WRITE_U8 (data + 7,  0x07); // logical end bit
00822     EC_WRITE_U16(data + 8,  fmmu->sync->physical_start_address);
00823     EC_WRITE_U8 (data + 10, 0x00); // physical start bit
00824     EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01);
00825     EC_WRITE_U16(data + 12, 0x0001); // enable
00826     EC_WRITE_U16(data + 14, 0x0000); // reserved
00827 }
00828 
00829 /*****************************************************************************/
00830 
00836 ssize_t ec_show_master_attribute(struct kobject *kobj, 
00837                                  struct attribute *attr, 
00838                                  char *buffer 
00839                                  )
00840 {
00841     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00842 
00843     if (attr == &attr_slave_count) {
00844         return sprintf(buffer, "%i\n", master->slave_count);
00845     }
00846     else if (attr == &attr_mode) {
00847         switch (master->mode) {
00848             case EC_MASTER_MODE_ORPHANED:
00849                 return sprintf(buffer, "ORPHANED\n");
00850             case EC_MASTER_MODE_IDLE:
00851                 return sprintf(buffer, "IDLE\n");
00852             case EC_MASTER_MODE_RUNNING:
00853                 return sprintf(buffer, "RUNNING\n");
00854         }
00855     }
00856     else if (attr == &attr_debug_level) {
00857         return sprintf(buffer, "%i\n", master->debug_level);
00858     }
00859     else if (attr == &attr_eeprom_write_enable) {
00860         return sprintf(buffer, "%i\n", master->eeprom_write_enable);
00861     }
00862 
00863     return 0;
00864 }
00865 
00866 /*****************************************************************************/
00867 
00873 ssize_t ec_store_master_attribute(struct kobject *kobj, 
00874                                   struct attribute *attr, 
00875                                   const char *buffer, 
00876                                   size_t size 
00877                                   )
00878 {
00879     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00880 
00881     if (attr == &attr_eeprom_write_enable) {
00882         if (!strcmp(buffer, "1\n")) {
00883             master->eeprom_write_enable = 1;
00884             EC_INFO("Slave EEPROM writing enabled.\n");
00885             return size;
00886         }
00887         else if (!strcmp(buffer, "0\n")) {
00888             master->eeprom_write_enable = 0;
00889             EC_INFO("Slave EEPROM writing disabled.\n");
00890             return size;
00891         }
00892 
00893         EC_ERR("Invalid value for eeprom_write_enable!\n");
00894 
00895         if (master->eeprom_write_enable) {
00896             master->eeprom_write_enable = 0;
00897             EC_INFO("Slave EEPROM writing disabled.\n");
00898         }
00899     }
00900     else if (attr == &attr_debug_level) {
00901         if (!strcmp(buffer, "0\n")) {
00902             master->debug_level = 0;
00903         }
00904         else if (!strcmp(buffer, "1\n")) {
00905             master->debug_level = 1;
00906         }
00907         else if (!strcmp(buffer, "2\n")) {
00908             master->debug_level = 2;
00909         }
00910         else {
00911             EC_ERR("Invalid debug level value!\n");
00912             return -EINVAL;
00913         }
00914 
00915         EC_INFO("Master debug level set to %i.\n", master->debug_level);
00916         return size;
00917     }
00918 
00919     return -EINVAL;
00920 }
00921 
00922 /*****************************************************************************/
00923 
00928 void ec_master_eoe_start(ec_master_t *master )
00929 {
00930     ec_eoe_t *eoe;
00931     ec_slave_t *slave;
00932     unsigned int coupled, found;
00933 
00934     if (master->eoe_running) return;
00935 
00936     // decouple all EoE handlers
00937     list_for_each_entry(eoe, &master->eoe_handlers, list)
00938         eoe->slave = NULL;
00939     coupled = 0;
00940 
00941     // couple a free EoE handler to every EoE-capable slave
00942     list_for_each_entry(slave, &master->slaves, list) {
00943         if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
00944 
00945         found = 0;
00946         list_for_each_entry(eoe, &master->eoe_handlers, list) {
00947             if (eoe->slave) continue;
00948             eoe->slave = slave;
00949             found = 1;
00950             coupled++;
00951             EC_INFO("Coupling device %s to slave %i.\n",
00952                     eoe->dev->name, slave->ring_position);
00953             if (eoe->opened) {
00954                 slave->requested_state = EC_SLAVE_STATE_OP;
00955             }
00956             else {
00957                 slave->requested_state = EC_SLAVE_STATE_INIT;
00958             }
00959             slave->error_flag = 0;
00960             break;
00961         }
00962 
00963         if (!found) {
00964             EC_WARN("No EoE handler for slave %i!\n", slave->ring_position);
00965             slave->requested_state = EC_SLAVE_STATE_INIT;
00966             slave->error_flag = 0;
00967         }
00968     }
00969 
00970     if (!coupled) {
00971         EC_INFO("No EoE handlers coupled.\n");
00972         return;
00973     }
00974 
00975     EC_INFO("Starting EoE processing.\n");
00976     master->eoe_running = 1;
00977 
00978     // start EoE processing
00979     master->eoe_timer.expires = jiffies + 10;
00980     add_timer(&master->eoe_timer);
00981     return;
00982 }
00983 
00984 /*****************************************************************************/
00985 
00990 void ec_master_eoe_stop(ec_master_t *master )
00991 {
00992     ec_eoe_t *eoe;
00993 
00994     if (!master->eoe_running) return;
00995 
00996     EC_INFO("Stopping EoE processing.\n");
00997 
00998     del_timer_sync(&master->eoe_timer);
00999 
01000     // decouple all EoE handlers
01001     list_for_each_entry(eoe, &master->eoe_handlers, list) {
01002         if (eoe->slave) {
01003             eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
01004             eoe->slave->error_flag = 0;
01005             eoe->slave = NULL;
01006         }
01007     }
01008 
01009     master->eoe_running = 0;
01010 }
01011 
01012 /*****************************************************************************/
01017 void ec_master_eoe_run(unsigned long data )
01018 {
01019     ec_master_t *master = (ec_master_t *) data;
01020     ec_eoe_t *eoe;
01021     unsigned int active = 0;
01022 
01023     list_for_each_entry(eoe, &master->eoe_handlers, list) {
01024         if (ec_eoe_active(eoe)) active++;
01025     }
01026     if (!active) goto queue_timer;
01027 
01028     // aquire master lock...
01029     if (master->mode == EC_MASTER_MODE_RUNNING) {
01030         // request_cb must return 0, if the lock has been aquired!
01031         if (master->request_cb(master->cb_data))
01032             goto queue_timer;
01033     }
01034     else if (master->mode == EC_MASTER_MODE_IDLE) {
01035         spin_lock(&master->internal_lock);
01036     }
01037     else
01038         goto queue_timer;
01039 
01040     // actual EoE stuff
01041     ecrt_master_async_receive(master);
01042     list_for_each_entry(eoe, &master->eoe_handlers, list) {
01043         ec_eoe_run(eoe);
01044     }
01045     ecrt_master_async_send(master);
01046 
01047     // release lock...
01048     if (master->mode == EC_MASTER_MODE_RUNNING) {
01049         master->release_cb(master->cb_data);
01050     }
01051     else if (master->mode == EC_MASTER_MODE_IDLE) {
01052         spin_unlock(&master->internal_lock);
01053     }
01054 
01055  queue_timer:
01056     master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;
01057     add_timer(&master->eoe_timer);
01058 }
01059 
01060 /******************************************************************************
01061  *  Realtime interface
01062  *****************************************************************************/
01063 
01070 ec_domain_t *ecrt_master_create_domain(ec_master_t *master )
01071 {
01072     ec_domain_t *domain, *last_domain;
01073     unsigned int index;
01074 
01075     if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) {
01076         EC_ERR("Error allocating domain memory!\n");
01077         goto out_return;
01078     }
01079 
01080     if (list_empty(&master->domains)) index = 0;
01081     else {
01082         last_domain = list_entry(master->domains.prev, ec_domain_t, list);
01083         index = last_domain->index + 1;
01084     }
01085 
01086     if (ec_domain_init(domain, master, index)) {
01087         EC_ERR("Failed to init domain.\n");
01088         goto out_return;
01089     }
01090 
01091     if (kobject_add(&domain->kobj)) {
01092         EC_ERR("Failed to add domain kobject.\n");
01093         goto out_put;
01094     }
01095 
01096     list_add_tail(&domain->list, &master->domains);
01097     return domain;
01098 
01099  out_put:
01100     kobject_put(&domain->kobj);
01101  out_return:
01102     return NULL;
01103 }
01104 
01105 /*****************************************************************************/
01106 
01116 int ecrt_master_activate(ec_master_t *master )
01117 {
01118     unsigned int j;
01119     ec_slave_t *slave;
01120     ec_datagram_t *datagram;
01121     const ec_sync_t *sync;
01122     const ec_slave_type_t *type;
01123     const ec_fmmu_t *fmmu;
01124     uint32_t domain_offset;
01125     ec_domain_t *domain;
01126     ec_eeprom_sync_t *eeprom_sync, mbox_sync;
01127 
01128     datagram = &master->simple_datagram;
01129 
01130     // allocate all domains
01131     domain_offset = 0;
01132     list_for_each_entry(domain, &master->domains, list) {
01133         if (ec_domain_alloc(domain, domain_offset)) {
01134             EC_ERR("Failed to allocate domain %X!\n", (u32) domain);
01135             return -1;
01136         }
01137         domain_offset += domain->data_size;
01138     }
01139 
01140     // configure and activate slaves
01141     list_for_each_entry(slave, &master->slaves, list) {
01142 
01143         // change state to INIT
01144         if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT)))
01145             return -1;
01146 
01147         // check for slave registration
01148         type = slave->type;
01149         if (!type)
01150             EC_WARN("Slave %i has unknown type!\n", slave->ring_position);
01151 
01152         // check and reset CRC fault counters
01153         ec_slave_check_crc(slave);
01154 
01155         // reset FMMUs
01156         if (slave->base_fmmu_count) {
01157             if (ec_datagram_npwr(datagram, slave->station_address, 0x0600,
01158                                  EC_FMMU_SIZE * slave->base_fmmu_count))
01159                 return -1;
01160             memset(datagram->data, 0x00,
01161                    EC_FMMU_SIZE * slave->base_fmmu_count);
01162             if (unlikely(ec_master_simple_io(master, datagram))) {
01163                 EC_ERR("Resetting FMMUs failed on slave %i!\n",
01164                        slave->ring_position);
01165                 return -1;
01166             }
01167         }
01168 
01169         // reset sync managers
01170         if (slave->base_sync_count) {
01171             if (ec_datagram_npwr(datagram, slave->station_address, 0x0800,
01172                                 EC_SYNC_SIZE * slave->base_sync_count))
01173                 return -1;
01174             memset(datagram->data, 0x00,
01175                    EC_SYNC_SIZE * slave->base_sync_count);
01176             if (unlikely(ec_master_simple_io(master, datagram))) {
01177                 EC_ERR("Resetting sync managers failed on slave %i!\n",
01178                        slave->ring_position);
01179                 return -1;
01180             }
01181         }
01182 
01183         // configure sync managers
01184 
01185         // does the slave provide sync manager information?
01186         if (!list_empty(&slave->eeprom_syncs)) {
01187             list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) {
01188                 if (ec_datagram_npwr(datagram, slave->station_address,
01189                                      0x800 + eeprom_sync->index *
01190                                      EC_SYNC_SIZE,
01191                                      EC_SYNC_SIZE)) return -1;
01192                 ec_eeprom_sync_config(eeprom_sync, slave, datagram->data);
01193                 if (unlikely(ec_master_simple_io(master, datagram))) {
01194                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
01195                            eeprom_sync->index, slave->ring_position);
01196                     return -1;
01197                 }
01198             }
01199         }
01200 
01201         else if (type) { // known slave type, take type's SM information
01202             for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) {
01203                 sync = type->sync_managers[j];
01204                 if (ec_datagram_npwr(datagram, slave->station_address,
01205                                      0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE))
01206                     return -1;
01207                 ec_sync_config(sync, slave, datagram->data);
01208                 if (unlikely(ec_master_simple_io(master, datagram))) {
01209                     EC_ERR("Setting sync manager %i failed on slave %i!\n",
01210                            j, slave->ring_position);
01211                     return -1;
01212                 }
01213             }
01214         }
01215 
01216         // no sync manager information; guess mailbox settings
01217         else if (slave->sii_mailbox_protocols) { 
01218             mbox_sync.physical_start_address =
01219                 slave->sii_rx_mailbox_offset;
01220             mbox_sync.length = slave->sii_rx_mailbox_size;
01221             mbox_sync.control_register = 0x26;
01222             mbox_sync.enable = 1;
01223             if (ec_datagram_npwr(datagram, slave->station_address,
01224                                  0x800,EC_SYNC_SIZE)) return -1;
01225             ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
01226             if (unlikely(ec_master_simple_io(master, datagram))) {
01227                 EC_ERR("Setting sync manager 0 failed on slave %i!\n",
01228                        slave->ring_position);
01229                 return -1;
01230             }
01231 
01232             mbox_sync.physical_start_address =
01233                 slave->sii_tx_mailbox_offset;
01234             mbox_sync.length = slave->sii_tx_mailbox_size;
01235             mbox_sync.control_register = 0x22;
01236             mbox_sync.enable = 1;
01237             if (ec_datagram_npwr(datagram, slave->station_address,
01238                                  0x808, EC_SYNC_SIZE)) return -1;
01239             ec_eeprom_sync_config(&mbox_sync, slave, datagram->data);
01240             if (unlikely(ec_master_simple_io(master, datagram))) {
01241             EC_ERR("Setting sync manager 1 failed on slave %i!\n",
01242                slave->ring_position);
01243             return -1;
01244             }
01245         }
01246 
01247         // change state to PREOP
01248         if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_PREOP)))
01249             return -1;
01250 
01251         // stop activation here for slaves without type
01252         if (!type) continue;
01253 
01254         // slaves that are not registered are only brought into PREOP
01255         // state -> nice blinking and mailbox communication possible
01256         if (!slave->registered && !slave->type->special) {
01257             EC_WARN("Slave %i was not registered!\n", slave->ring_position);
01258             continue;
01259         }
01260 
01261         // configure FMMUs
01262         for (j = 0; j < slave->fmmu_count; j++) {
01263             fmmu = &slave->fmmus[j];
01264             if (ec_datagram_npwr(datagram, slave->station_address,
01265                                  0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE))
01266                 return -1;
01267             ec_fmmu_config(fmmu, slave, datagram->data);
01268             if (unlikely(ec_master_simple_io(master, datagram))) {
01269                 EC_ERR("Setting FMMU %i failed on slave %i!\n",
01270                        j, slave->ring_position);
01271                 return -1;
01272             }
01273         }
01274 
01275         // change state to SAVEOP
01276         if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_SAVEOP)))
01277             return -1;
01278 
01279         // change state to OP
01280         if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_OP)))
01281             return -1;
01282     }
01283 
01284     return 0;
01285 }
01286 
01287 /*****************************************************************************/
01288 
01294 void ecrt_master_deactivate(ec_master_t *master )
01295 {
01296     ec_slave_t *slave;
01297 
01298     list_for_each_entry(slave, &master->slaves, list) {
01299         ec_slave_check_crc(slave);
01300         ec_slave_state_change(slave, EC_SLAVE_STATE_INIT);
01301     }
01302 }
01303 
01304 
01305 /*****************************************************************************/
01306 
01314 int ecrt_master_fetch_sdo_lists(ec_master_t *master )
01315 {
01316     ec_slave_t *slave;
01317 
01318     list_for_each_entry(slave, &master->slaves, list) {
01319         if (slave->sii_mailbox_protocols & EC_MBOX_COE) {
01320             if (unlikely(ec_slave_fetch_sdo_list(slave))) {
01321                 EC_ERR("Failed to fetch SDO list on slave %i!\n",
01322                        slave->ring_position);
01323                 return -1;
01324             }
01325         }
01326     }
01327 
01328     return 0;
01329 }
01330 
01331 /*****************************************************************************/
01332 
01338 void ecrt_master_sync_io(ec_master_t *master )
01339 {
01340     ec_datagram_t *datagram, *n;
01341     unsigned int datagrams_sent;
01342     cycles_t t_start, t_end, t_timeout;
01343 
01344     // send datagrams
01345     ecrt_master_async_send(master);
01346 
01347     t_start = get_cycles(); // measure io time
01348     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
01349 
01350     while (1) { // active waiting
01351         ec_device_call_isr(master->device);
01352 
01353         t_end = get_cycles(); // take current time
01354         if (t_end - t_start >= t_timeout) break; // timeout!
01355 
01356         datagrams_sent = 0;
01357         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
01358             if (datagram->state == EC_CMD_RECEIVED)
01359                 list_del_init(&datagram->queue);
01360             else if (datagram->state == EC_CMD_SENT)
01361                 datagrams_sent++;
01362         }
01363 
01364         if (!datagrams_sent) break;
01365     }
01366 
01367     // timeout; dequeue all datagrams
01368     list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
01369         switch (datagram->state) {
01370             case EC_CMD_SENT:
01371             case EC_CMD_QUEUED:
01372                 datagram->state = EC_CMD_TIMEOUT;
01373                 master->stats.timeouts++;
01374                 ec_master_output_stats(master);
01375                 break;
01376             case EC_CMD_RECEIVED:
01377                 master->stats.delayed++;
01378                 ec_master_output_stats(master);
01379                 break;
01380             default:
01381                 break;
01382         }
01383         list_del_init(&datagram->queue);
01384     }
01385 }
01386 
01387 /*****************************************************************************/
01388 
01394 void ecrt_master_async_send(ec_master_t *master )
01395 {
01396     ec_datagram_t *datagram, *n;
01397 
01398     if (unlikely(!master->device->link_state)) {
01399         // link is down, no datagram can be sent
01400         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
01401             datagram->state = EC_CMD_ERROR;
01402             list_del_init(&datagram->queue);
01403         }
01404 
01405         // query link state
01406         ec_device_call_isr(master->device);
01407         return;
01408     }
01409 
01410     // send frames
01411     ec_master_send_datagrams(master);
01412 }
01413 
01414 /*****************************************************************************/
01415 
01421 void ecrt_master_async_receive(ec_master_t *master )
01422 {
01423     ec_datagram_t *datagram, *next;
01424     cycles_t t_received, t_timeout;
01425 
01426     ec_device_call_isr(master->device);
01427 
01428     t_received = get_cycles();
01429     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
01430 
01431     // dequeue all received datagrams
01432     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue)
01433         if (datagram->state == EC_CMD_RECEIVED)
01434             list_del_init(&datagram->queue);
01435 
01436     // dequeue all datagrams that timed out
01437     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
01438         switch (datagram->state) {
01439             case EC_CMD_SENT:
01440             case EC_CMD_QUEUED:
01441                 if (t_received - datagram->t_sent > t_timeout) {
01442                     list_del_init(&datagram->queue);
01443                     datagram->state = EC_CMD_TIMEOUT;
01444                     master->stats.timeouts++;
01445                     ec_master_output_stats(master);
01446                 }
01447                 break;
01448             default:
01449                 break;
01450         }
01451     }
01452 }
01453 
01454 /*****************************************************************************/
01455 
01463 void ecrt_master_prepare_async_io(ec_master_t *master )
01464 {
01465     ec_domain_t *domain;
01466     cycles_t t_start, t_end, t_timeout;
01467 
01468     // queue datagrams of all domains
01469     list_for_each_entry(domain, &master->domains, list)
01470         ecrt_domain_queue(domain);
01471 
01472     ecrt_master_async_send(master);
01473 
01474     t_start = get_cycles(); // take sending time
01475     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
01476 
01477     // active waiting
01478     while (1) {
01479         t_end = get_cycles();
01480         if (t_end - t_start >= t_timeout) break;
01481     }
01482 }
01483 
01484 /*****************************************************************************/
01485 
01491 void ecrt_master_run(ec_master_t *master )
01492 {
01493     // output statistics
01494     ec_master_output_stats(master);
01495 
01496     // execute master state machine
01497     ec_fsm_execute(&master->fsm);
01498 }
01499 
01500 /*****************************************************************************/
01501 
01515 ec_slave_t *ecrt_master_get_slave(const ec_master_t *master, 
01516                                   const char *address 
01517                                   )
01518 {
01519     unsigned long first, second;
01520     char *remainder, *remainder2;
01521     unsigned int alias_requested, alias_found;
01522     ec_slave_t *alias_slave = NULL, *slave;
01523 
01524     if (!address || address[0] == 0) return NULL;
01525 
01526     alias_requested = 0;
01527     if (address[0] == '#') {
01528         alias_requested = 1;
01529         address++;
01530     }
01531 
01532     first = simple_strtoul(address, &remainder, 0);
01533     if (remainder == address) {
01534         EC_ERR("Slave address \"%s\" - First number empty!\n", address);
01535         return NULL;
01536     }
01537 
01538     if (alias_requested) {
01539         alias_found = 0;
01540         list_for_each_entry(alias_slave, &master->slaves, list) {
01541             if (alias_slave->sii_alias == first) {
01542                 alias_found = 1;
01543                 break;
01544             }
01545         }
01546         if (!alias_found) {
01547             EC_ERR("Slave address \"%s\" - Alias not found!\n", address);
01548             return NULL;
01549         }
01550     }
01551 
01552     if (!remainder[0]) { // absolute position
01553         if (alias_requested) {
01554             return alias_slave;
01555         }
01556         else {
01557             list_for_each_entry(slave, &master->slaves, list) {
01558                 if (slave->ring_position == first) return slave;
01559             }
01560             EC_ERR("Slave address \"%s\" - Absolute position invalid!\n",
01561                    address);
01562         }
01563     }
01564     else if (remainder[0] == ':') { // field position
01565         remainder++;
01566         second = simple_strtoul(remainder, &remainder2, 0);
01567 
01568         if (remainder2 == remainder) {
01569             EC_ERR("Slave address \"%s\" - Second number empty!\n", address);
01570             return NULL;
01571         }
01572 
01573         if (remainder2[0]) {
01574             EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address);
01575             return NULL;
01576         }
01577 
01578         if (alias_requested) {
01579             if (!alias_slave->type ||
01580                 alias_slave->type->special != EC_TYPE_BUS_COUPLER) {
01581                 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler"
01582                        " in colon mode.\n", address);
01583                 return NULL;
01584             }
01585             list_for_each_entry(slave, &master->slaves, list) {
01586                 if (slave->coupler_index == alias_slave->coupler_index
01587                     && slave->coupler_subindex == second)
01588                     return slave;
01589             }
01590             EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave"
01591                    " following!\n", address, alias_slave->ring_position,
01592                    second);
01593             return NULL;
01594         }
01595         else {
01596             list_for_each_entry(slave, &master->slaves, list) {
01597                 if (slave->coupler_index == first
01598                     && slave->coupler_subindex == second) return slave;
01599             }
01600         }
01601     }
01602     else
01603         EC_ERR("Slave address \"%s\" - Invalid format!\n", address);
01604 
01605     return NULL;
01606 }
01607 
01608 /*****************************************************************************/
01609 
01618 void ecrt_master_callbacks(ec_master_t *master, 
01619                            int (*request_cb)(void *), 
01620                            void (*release_cb)(void *), 
01621                            void *cb_data 
01622                            )
01623 {
01624     master->request_cb = request_cb;
01625     master->release_cb = release_cb;
01626     master->cb_data = cb_data;
01627 }
01628 
01629 /*****************************************************************************/
01630 
01636 int ecrt_master_start_eoe(ec_master_t *master )
01637 {
01638     if (!master->request_cb || !master->release_cb) {
01639         EC_ERR("EoE requires master callbacks to be set!\n");
01640         return -1;
01641     }
01642 
01643     ec_master_eoe_start(master);
01644     return 0;
01645 }
01646 
01647 /*****************************************************************************/
01648 
01657 void ecrt_master_debug(ec_master_t *master, 
01658                        int level 
01659                        )
01660 {
01661     if (level != master->debug_level) {
01662         master->debug_level = level;
01663         EC_INFO("Master debug level set to %i.\n", level);
01664     }
01665 }
01666 
01667 /*****************************************************************************/
01668 
01678 void ecrt_master_print(const ec_master_t *master, 
01679                        unsigned int verbosity 
01680                        )
01681 {
01682     ec_slave_t *slave;
01683     ec_eoe_t *eoe;
01684 
01685     EC_INFO("*** Begin master information ***\n");
01686     if (master->slave_count) {
01687         EC_INFO("Slave list:\n");
01688         list_for_each_entry(slave, &master->slaves, list)
01689             ec_slave_print(slave, verbosity);
01690     }
01691     if (!list_empty(&master->eoe_handlers)) {
01692         EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n");
01693         list_for_each_entry(eoe, &master->eoe_handlers, list) {
01694             ec_eoe_print(eoe);
01695         }
01696     }
01697     EC_INFO("*** End master information ***\n");
01698 }
01699 
01700 /*****************************************************************************/
01701 
01704 EXPORT_SYMBOL(ecrt_master_create_domain);
01705 EXPORT_SYMBOL(ecrt_master_activate);
01706 EXPORT_SYMBOL(ecrt_master_deactivate);
01707 EXPORT_SYMBOL(ecrt_master_fetch_sdo_lists);
01708 EXPORT_SYMBOL(ecrt_master_prepare_async_io);
01709 EXPORT_SYMBOL(ecrt_master_sync_io);
01710 EXPORT_SYMBOL(ecrt_master_async_send);
01711 EXPORT_SYMBOL(ecrt_master_async_receive);
01712 EXPORT_SYMBOL(ecrt_master_run);
01713 EXPORT_SYMBOL(ecrt_master_callbacks);
01714 EXPORT_SYMBOL(ecrt_master_start_eoe);
01715 EXPORT_SYMBOL(ecrt_master_debug);
01716 EXPORT_SYMBOL(ecrt_master_print);
01717 EXPORT_SYMBOL(ecrt_master_get_slave);
01718 
01721 /*****************************************************************************/

Generated on Wed Aug 2 18:41:43 2006 for IgH EtherCAT master by  doxygen 1.4.6