master.c

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  *  $Id: master.c 533 2006-09-01 12:35:41Z 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_sync_io(ec_master_t *);
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(info);
00069 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable);
00070 EC_SYSFS_READ_WRITE_ATTR(debug_level);
00071 
00072 static struct attribute *ec_def_attrs[] = {
00073     &attr_info,
00074     &attr_eeprom_write_enable,
00075     &attr_debug_level,
00076     NULL,
00077 };
00078 
00079 static struct sysfs_ops ec_sysfs_ops = {
00080     .show = &ec_show_master_attribute,
00081     .store = ec_store_master_attribute
00082 };
00083 
00084 static struct kobj_type ktype_ec_master = {
00085     .release = ec_master_clear,
00086     .sysfs_ops = &ec_sysfs_ops,
00087     .default_attrs = ec_def_attrs
00088 };
00089 
00092 /*****************************************************************************/
00093 
00099 int ec_master_init(ec_master_t *master, 
00100                    unsigned int index, 
00101                    unsigned int eoeif_count 
00102                    )
00103 {
00104     ec_eoe_t *eoe, *next_eoe;
00105     unsigned int i;
00106 
00107     EC_INFO("Initializing master %i.\n", index);
00108 
00109     master->index = index;
00110     master->device = NULL;
00111     master->reserved = 0;
00112     INIT_LIST_HEAD(&master->slaves);
00113     INIT_LIST_HEAD(&master->datagram_queue);
00114     INIT_LIST_HEAD(&master->domains);
00115     INIT_LIST_HEAD(&master->eoe_handlers);
00116     INIT_WORK(&master->idle_work, ec_master_idle_run, (void *) master);
00117     init_timer(&master->eoe_timer);
00118     master->eoe_timer.function = ec_master_eoe_run;
00119     master->eoe_timer.data = (unsigned long) master;
00120     master->internal_lock = SPIN_LOCK_UNLOCKED;
00121     master->eoe_running = 0;
00122     master->eoe_checked = 0;
00123     for (i = 0; i < HZ; i++) {
00124         master->idle_cycle_times[i] = 0;
00125         master->eoe_cycle_times[i] = 0;
00126     }
00127     master->idle_cycle_time_pos = 0;
00128     master->eoe_cycle_time_pos = 0;
00129 
00130     // create workqueue
00131     if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) {
00132         EC_ERR("Failed to create master workqueue.\n");
00133         goto out_return;
00134     }
00135 
00136     // create EoE handlers
00137     for (i = 0; i < eoeif_count; i++) {
00138         if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
00139             EC_ERR("Failed to allocate EoE-Object.\n");
00140             goto out_clear_eoe;
00141         }
00142         if (ec_eoe_init(eoe)) {
00143             kfree(eoe);
00144             goto out_clear_eoe;
00145         }
00146         list_add_tail(&eoe->list, &master->eoe_handlers);
00147     }
00148 
00149     // create state machine object
00150     if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe;
00151 
00152     // init kobject and add it to the hierarchy
00153     memset(&master->kobj, 0x00, sizeof(struct kobject));
00154     kobject_init(&master->kobj);
00155     master->kobj.ktype = &ktype_ec_master;
00156     if (kobject_set_name(&master->kobj, "ethercat%i", index)) {
00157         EC_ERR("Failed to set kobj name.\n");
00158         kobject_put(&master->kobj);
00159         return -1;
00160     }
00161 
00162     ec_master_reset(master);
00163     return 0;
00164 
00165  out_clear_eoe:
00166     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
00167         list_del(&eoe->list);
00168         ec_eoe_clear(eoe);
00169         kfree(eoe);
00170     }
00171     destroy_workqueue(master->workqueue);
00172  out_return:
00173     return -1;
00174 }
00175 
00176 /*****************************************************************************/
00177 
00184 void ec_master_clear(struct kobject *kobj )
00185 {
00186     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00187     ec_eoe_t *eoe, *next_eoe;
00188 
00189     EC_INFO("Clearing master %i...\n", master->index);
00190 
00191     ec_master_reset(master);
00192     ec_fsm_clear(&master->fsm);
00193     destroy_workqueue(master->workqueue);
00194 
00195     // clear EoE objects
00196     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
00197         list_del(&eoe->list);
00198         ec_eoe_clear(eoe);
00199         kfree(eoe);
00200     }
00201 
00202     if (master->device) {
00203         ec_device_clear(master->device);
00204         kfree(master->device);
00205     }
00206 
00207     EC_INFO("Master %i cleared.\n", master->index);
00208 }
00209 
00210 /*****************************************************************************/
00211 
00218 void ec_master_reset(ec_master_t *master )
00219 {
00220     ec_datagram_t *datagram, *next_c;
00221     ec_domain_t *domain, *next_d;
00222 
00223     ec_master_eoe_stop(master);
00224     ec_master_idle_stop(master);
00225     ec_master_clear_slaves(master);
00226 
00227     // empty datagram queue
00228     list_for_each_entry_safe(datagram, next_c,
00229                              &master->datagram_queue, queue) {
00230         datagram->state = EC_DATAGRAM_ERROR;
00231         list_del_init(&datagram->queue);
00232     }
00233 
00234     // clear domains
00235     list_for_each_entry_safe(domain, next_d, &master->domains, list) {
00236         list_del(&domain->list);
00237         kobject_del(&domain->kobj);
00238         kobject_put(&domain->kobj);
00239     }
00240 
00241     master->datagram_index = 0;
00242     master->debug_level = 0;
00243 
00244     master->stats.timeouts = 0;
00245     master->stats.corrupted = 0;
00246     master->stats.skipped = 0;
00247     master->stats.unmatched = 0;
00248     master->stats.output_jiffies = 0;
00249 
00250     master->mode = EC_MASTER_MODE_ORPHANED;
00251 
00252     master->request_cb = NULL;
00253     master->release_cb = NULL;
00254     master->cb_data = NULL;
00255 
00256     master->eeprom_write_enable = 0;
00257 
00258     ec_fsm_reset(&master->fsm);
00259 }
00260 
00261 /*****************************************************************************/
00262 
00267 void ec_master_clear_slaves(ec_master_t *master)
00268 {
00269     ec_slave_t *slave, *next_slave;
00270 
00271     list_for_each_entry_safe(slave, next_slave, &master->slaves, list) {
00272         list_del(&slave->list);
00273         kobject_del(&slave->kobj);
00274         kobject_put(&slave->kobj);
00275     }
00276     master->slave_count = 0;
00277 }
00278 
00279 /*****************************************************************************/
00280 
00285 void ec_master_queue_datagram(ec_master_t *master, 
00286                               ec_datagram_t *datagram 
00287                               )
00288 {
00289     ec_datagram_t *queued_datagram;
00290 
00291     // check, if the datagram is already queued
00292     list_for_each_entry(queued_datagram, &master->datagram_queue, queue) {
00293         if (queued_datagram == datagram) {
00294             master->stats.skipped++;
00295             ec_master_output_stats(master);
00296             datagram->state = EC_DATAGRAM_QUEUED;
00297             return;
00298         }
00299     }
00300 
00301     list_add_tail(&datagram->queue, &master->datagram_queue);
00302     datagram->state = EC_DATAGRAM_QUEUED;
00303 }
00304 
00305 /*****************************************************************************/
00306 
00312 void ec_master_send_datagrams(ec_master_t *master )
00313 {
00314     ec_datagram_t *datagram;
00315     size_t datagram_size;
00316     uint8_t *frame_data, *cur_data;
00317     void *follows_word;
00318     cycles_t cycles_start, cycles_end;
00319     unsigned int frame_count, more_datagrams_waiting;
00320 
00321     frame_count = 0;
00322     cycles_start = get_cycles();
00323 
00324     if (unlikely(master->debug_level > 1))
00325         EC_DBG("ec_master_send_datagrams\n");
00326 
00327     do {
00328         // fetch pointer to transmit socket buffer
00329         frame_data = ec_device_tx_data(master->device);
00330         cur_data = frame_data + EC_FRAME_HEADER_SIZE;
00331         follows_word = NULL;
00332         more_datagrams_waiting = 0;
00333 
00334         // fill current frame with datagrams
00335         list_for_each_entry(datagram, &master->datagram_queue, queue) {
00336             if (datagram->state != EC_DATAGRAM_QUEUED) continue;
00337 
00338             // does the current datagram fit in the frame?
00339             datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size
00340                 + EC_DATAGRAM_FOOTER_SIZE;
00341             if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) {
00342                 more_datagrams_waiting = 1;
00343                 break;
00344             }
00345 
00346             datagram->state = EC_DATAGRAM_SENT;
00347             datagram->cycles_sent = cycles_start;
00348             datagram->index = master->datagram_index++;
00349 
00350             if (unlikely(master->debug_level > 1))
00351                 EC_DBG("adding datagram 0x%02X\n", datagram->index);
00352 
00353             // set "datagram following" flag in previous frame
00354             if (follows_word)
00355                 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000);
00356 
00357             // EtherCAT datagram header
00358             EC_WRITE_U8 (cur_data,     datagram->type);
00359             EC_WRITE_U8 (cur_data + 1, datagram->index);
00360             EC_WRITE_U32(cur_data + 2, datagram->address.logical);
00361             EC_WRITE_U16(cur_data + 6, datagram->data_size & 0x7FF);
00362             EC_WRITE_U16(cur_data + 8, 0x0000);
00363             follows_word = cur_data + 6;
00364             cur_data += EC_DATAGRAM_HEADER_SIZE;
00365 
00366             // EtherCAT datagram data
00367             memcpy(cur_data, datagram->data, datagram->data_size);
00368             cur_data += datagram->data_size;
00369 
00370             // EtherCAT datagram footer
00371             EC_WRITE_U16(cur_data, 0x0000); // reset working counter
00372             cur_data += EC_DATAGRAM_FOOTER_SIZE;
00373         }
00374 
00375         if (cur_data - frame_data == EC_FRAME_HEADER_SIZE) {
00376             if (unlikely(master->debug_level > 1))
00377                 EC_DBG("nothing to send.\n");
00378             break;
00379         }
00380 
00381         // EtherCAT frame header
00382         EC_WRITE_U16(frame_data, ((cur_data - frame_data
00383                                    - EC_FRAME_HEADER_SIZE) & 0x7FF) | 0x1000);
00384 
00385         // pad frame
00386         while (cur_data - frame_data < ETH_ZLEN - ETH_HLEN)
00387             EC_WRITE_U8(cur_data++, 0x00);
00388 
00389         if (unlikely(master->debug_level > 1))
00390             EC_DBG("frame size: %i\n", cur_data - frame_data);
00391 
00392         // send frame
00393         ec_device_send(master->device, cur_data - frame_data);
00394         frame_count++;
00395     }
00396     while (more_datagrams_waiting);
00397 
00398     if (unlikely(master->debug_level > 1)) {
00399         cycles_end = get_cycles();
00400         EC_DBG("ec_master_send_datagrams sent %i frames in %ius.\n",
00401                frame_count,
00402                (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz);
00403     }
00404 }
00405 
00406 /*****************************************************************************/
00407 
00414 void ec_master_receive_datagrams(ec_master_t *master, 
00415                                  const uint8_t *frame_data, 
00416                                  size_t size 
00417                                  )
00418 {
00419     size_t frame_size, data_size;
00420     uint8_t datagram_type, datagram_index;
00421     unsigned int cmd_follows, matched;
00422     const uint8_t *cur_data;
00423     ec_datagram_t *datagram;
00424 
00425     if (unlikely(size < EC_FRAME_HEADER_SIZE)) {
00426         master->stats.corrupted++;
00427         ec_master_output_stats(master);
00428         return;
00429     }
00430 
00431     cur_data = frame_data;
00432 
00433     // check length of entire frame
00434     frame_size = EC_READ_U16(cur_data) & 0x07FF;
00435     cur_data += EC_FRAME_HEADER_SIZE;
00436 
00437     if (unlikely(frame_size > size)) {
00438         master->stats.corrupted++;
00439         ec_master_output_stats(master);
00440         return;
00441     }
00442 
00443     cmd_follows = 1;
00444     while (cmd_follows) {
00445         // process datagram header
00446         datagram_type  = EC_READ_U8 (cur_data);
00447         datagram_index = EC_READ_U8 (cur_data + 1);
00448         data_size      = EC_READ_U16(cur_data + 6) & 0x07FF;
00449         cmd_follows    = EC_READ_U16(cur_data + 6) & 0x8000;
00450         cur_data += EC_DATAGRAM_HEADER_SIZE;
00451 
00452         if (unlikely(cur_data - frame_data
00453                      + data_size + EC_DATAGRAM_FOOTER_SIZE > size)) {
00454             master->stats.corrupted++;
00455             ec_master_output_stats(master);
00456             return;
00457         }
00458 
00459         // search for matching datagram in the queue
00460         matched = 0;
00461         list_for_each_entry(datagram, &master->datagram_queue, queue) {
00462             if (datagram->state == EC_DATAGRAM_SENT
00463                 && datagram->type == datagram_type
00464                 && datagram->index == datagram_index
00465                 && datagram->data_size == data_size) {
00466                 matched = 1;
00467                 break;
00468             }
00469         }
00470 
00471         // no matching datagram was found
00472         if (!matched) {
00473             master->stats.unmatched++;
00474             ec_master_output_stats(master);
00475             cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
00476             continue;
00477         }
00478 
00479         // copy received data into the datagram memory
00480         memcpy(datagram->data, cur_data, data_size);
00481         cur_data += data_size;
00482 
00483         // set the datagram's working counter
00484         datagram->working_counter = EC_READ_U16(cur_data);
00485         cur_data += EC_DATAGRAM_FOOTER_SIZE;
00486 
00487         // dequeue the received datagram
00488         datagram->state = EC_DATAGRAM_RECEIVED;
00489         list_del_init(&datagram->queue);
00490     }
00491 }
00492 
00493 /*****************************************************************************/
00494 
00501 int ec_master_bus_scan(ec_master_t *master )
00502 {
00503     ec_fsm_t *fsm = &master->fsm;
00504 
00505     ec_fsm_startup(fsm); // init startup state machine
00506 
00507     do {
00508         ec_fsm_execute(fsm);
00509         ec_master_sync_io(master);
00510     }
00511     while (ec_fsm_startup_running(fsm));
00512 
00513     if (!ec_fsm_startup_success(fsm)) {
00514         ec_master_clear_slaves(master);
00515         return -1;
00516     }
00517 
00518     return 0;
00519 }
00520 
00521 /*****************************************************************************/
00522 
00529 void ec_master_output_stats(ec_master_t *master )
00530 {
00531     if (unlikely(jiffies - master->stats.output_jiffies >= HZ)) {
00532         master->stats.output_jiffies = jiffies;
00533 
00534         if (master->stats.timeouts) {
00535             EC_WARN("%i datagrams TIMED OUT!\n", master->stats.timeouts);
00536             master->stats.timeouts = 0;
00537         }
00538         if (master->stats.corrupted) {
00539             EC_WARN("%i frame(s) CORRUPTED!\n", master->stats.corrupted);
00540             master->stats.corrupted = 0;
00541         }
00542         if (master->stats.skipped) {
00543             EC_WARN("%i datagram(s) SKIPPED!\n", master->stats.skipped);
00544             master->stats.skipped = 0;
00545         }
00546         if (master->stats.unmatched) {
00547             EC_WARN("%i datagram(s) UNMATCHED!\n", master->stats.unmatched);
00548             master->stats.unmatched = 0;
00549         }
00550     }
00551 }
00552 
00553 /*****************************************************************************/
00554 
00559 void ec_master_idle_start(ec_master_t *master )
00560 {
00561     if (master->mode == EC_MASTER_MODE_IDLE) return;
00562 
00563     if (master->mode == EC_MASTER_MODE_OPERATION) {
00564         EC_ERR("ec_master_idle_start: Master already running!\n");
00565         return;
00566     }
00567 
00568     EC_INFO("Starting Idle mode.\n");
00569 
00570     master->mode = EC_MASTER_MODE_IDLE;
00571     ec_fsm_reset(&master->fsm);
00572     queue_delayed_work(master->workqueue, &master->idle_work, 1);
00573 }
00574 
00575 /*****************************************************************************/
00576 
00581 void ec_master_idle_stop(ec_master_t *master )
00582 {
00583     if (master->mode != EC_MASTER_MODE_IDLE) return;
00584 
00585     ec_master_eoe_stop(master);
00586 
00587     EC_INFO("Stopping Idle mode.\n");
00588     master->mode = EC_MASTER_MODE_ORPHANED; // this is important for the
00589                                             // IDLE work function to not
00590                                             // queue itself again
00591 
00592     if (!cancel_delayed_work(&master->idle_work)) {
00593         flush_workqueue(master->workqueue);
00594     }
00595 
00596     ec_master_clear_slaves(master);
00597 }
00598 
00599 /*****************************************************************************/
00600 
00605 void ec_master_idle_run(void *data )
00606 {
00607     ec_master_t *master = (ec_master_t *) data;
00608     cycles_t cycles_start, cycles_end;
00609 
00610     // aquire master lock
00611     spin_lock_bh(&master->internal_lock);
00612 
00613     cycles_start = get_cycles();
00614     ecrt_master_receive(master);
00615 
00616     // execute master state machine
00617     ec_fsm_execute(&master->fsm);
00618 
00619     ecrt_master_send(master);
00620     cycles_end = get_cycles();
00621 
00622     // release master lock
00623     spin_unlock_bh(&master->internal_lock);
00624 
00625     master->idle_cycle_times[master->idle_cycle_time_pos]
00626         = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
00627     master->idle_cycle_time_pos++;
00628     master->idle_cycle_time_pos %= HZ;
00629 
00630     if (master->mode == EC_MASTER_MODE_IDLE)
00631         queue_delayed_work(master->workqueue, &master->idle_work, 1);
00632 }
00633 
00634 /*****************************************************************************/
00635 
00641 void ec_sync_config(const ec_sii_sync_t *sync, 
00642                     const ec_slave_t *slave, 
00643                     uint8_t *data 
00644                     )
00645 {
00646     size_t sync_size;
00647 
00648     sync_size = ec_slave_calc_sync_size(slave, sync);
00649 
00650     if (slave->master->debug_level) {
00651         EC_INFO("Slave %i, sync manager %i:\n", slave->ring_position,
00652                 sync->index);
00653         EC_INFO("  Address: 0x%04X\n", sync->physical_start_address);
00654         EC_INFO("     Size: %i\n", sync_size);
00655         EC_INFO("  Control: 0x%02X\n", sync->control_register);
00656     }
00657 
00658     EC_WRITE_U16(data,     sync->physical_start_address);
00659     EC_WRITE_U16(data + 2, sync_size);
00660     EC_WRITE_U8 (data + 4, sync->control_register);
00661     EC_WRITE_U8 (data + 5, 0x00); // status byte (read only)
00662     EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable
00663 }
00664 
00665 /*****************************************************************************/
00666 
00672 void ec_fmmu_config(const ec_fmmu_t *fmmu, 
00673                     const ec_slave_t *slave, 
00674                     uint8_t *data 
00675                     )
00676 {
00677     size_t sync_size;
00678 
00679     sync_size = ec_slave_calc_sync_size(slave, fmmu->sync);
00680 
00681     EC_WRITE_U32(data,      fmmu->logical_start_address);
00682     EC_WRITE_U16(data + 4,  sync_size); // size of fmmu
00683     EC_WRITE_U8 (data + 6,  0x00); // logical start bit
00684     EC_WRITE_U8 (data + 7,  0x07); // logical end bit
00685     EC_WRITE_U16(data + 8,  fmmu->sync->physical_start_address);
00686     EC_WRITE_U8 (data + 10, 0x00); // physical start bit
00687     EC_WRITE_U8 (data + 11, ((fmmu->sync->control_register & 0x04)
00688                              ? 0x02 : 0x01));
00689     EC_WRITE_U16(data + 12, 0x0001); // enable
00690     EC_WRITE_U16(data + 14, 0x0000); // reserved
00691 }
00692 
00693 /*****************************************************************************/
00694 
00700 ssize_t ec_master_info(ec_master_t *master, 
00701                        char *buffer 
00702                        )
00703 {
00704     off_t off = 0;
00705     ec_eoe_t *eoe;
00706     uint32_t cur, sum, min, max, pos, i;
00707 
00708     off += sprintf(buffer + off, "\nMode: ");
00709     switch (master->mode) {
00710         case EC_MASTER_MODE_ORPHANED:
00711             off += sprintf(buffer + off, "ORPHANED");
00712             break;
00713         case EC_MASTER_MODE_IDLE:
00714             off += sprintf(buffer + off, "IDLE");
00715             break;
00716         case EC_MASTER_MODE_OPERATION:
00717             off += sprintf(buffer + off, "OPERATION");
00718             break;
00719     }
00720 
00721     off += sprintf(buffer + off, "\nSlaves: %i\n",
00722                    master->slave_count);
00723 
00724     off += sprintf(buffer + off, "\nTiming (min/avg/max) [us]:\n");
00725 
00726     sum = 0;
00727     min = 0xFFFFFFFF;
00728     max = 0;
00729     pos = master->idle_cycle_time_pos;
00730     for (i = 0; i < HZ; i++) {
00731         cur = master->idle_cycle_times[(i + pos) % HZ];
00732         sum += cur;
00733         if (cur < min) min = cur;
00734         if (cur > max) max = cur;
00735     }
00736     off += sprintf(buffer + off, "  Idle cycle: %u / %u.%u / %u\n",
00737                    min, sum / HZ, (sum * 100 / HZ) % 100, max);
00738 
00739     sum = 0;
00740     min = 0xFFFFFFFF;
00741     max = 0;
00742     pos = master->eoe_cycle_time_pos;
00743     for (i = 0; i < HZ; i++) {
00744         cur = master->eoe_cycle_times[(i + pos) % HZ];
00745         sum += cur;
00746         if (cur < min) min = cur;
00747         if (cur > max) max = cur;
00748     }
00749     off += sprintf(buffer + off, "  EoE cycle: %u / %u.%u / %u\n",
00750                    min, sum / HZ, (sum * 100 / HZ) % 100, max);
00751 
00752     if (!list_empty(&master->eoe_handlers))
00753         off += sprintf(buffer + off, "\nEoE statistics (RX/TX) [bps]:\n");
00754     list_for_each_entry(eoe, &master->eoe_handlers, list) {
00755         off += sprintf(buffer + off, "  %s: %u / %u (%u KB/s)\n",
00756                        eoe->dev->name, eoe->rx_rate, eoe->tx_rate,
00757                        ((eoe->rx_rate + eoe->tx_rate) / 8 + 512) / 1024);
00758     }
00759 
00760     off += sprintf(buffer + off, "\n");
00761 
00762     return off;
00763 }
00764 
00765 /*****************************************************************************/
00766 
00772 ssize_t ec_show_master_attribute(struct kobject *kobj, 
00773                                  struct attribute *attr, 
00774                                  char *buffer 
00775                                  )
00776 {
00777     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00778 
00779     if (attr == &attr_info) {
00780         return ec_master_info(master, buffer);
00781     }
00782     else if (attr == &attr_debug_level) {
00783         return sprintf(buffer, "%i\n", master->debug_level);
00784     }
00785     else if (attr == &attr_eeprom_write_enable) {
00786         return sprintf(buffer, "%i\n", master->eeprom_write_enable);
00787     }
00788 
00789     return 0;
00790 }
00791 
00792 /*****************************************************************************/
00793 
00799 ssize_t ec_store_master_attribute(struct kobject *kobj, 
00800                                   struct attribute *attr, 
00801                                   const char *buffer, 
00802                                   size_t size 
00803                                   )
00804 {
00805     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
00806 
00807     if (attr == &attr_eeprom_write_enable) {
00808         if (!strcmp(buffer, "1\n")) {
00809             master->eeprom_write_enable = 1;
00810             EC_INFO("Slave EEPROM writing enabled.\n");
00811             return size;
00812         }
00813         else if (!strcmp(buffer, "0\n")) {
00814             master->eeprom_write_enable = 0;
00815             EC_INFO("Slave EEPROM writing disabled.\n");
00816             return size;
00817         }
00818 
00819         EC_ERR("Invalid value for eeprom_write_enable!\n");
00820 
00821         if (master->eeprom_write_enable) {
00822             master->eeprom_write_enable = 0;
00823             EC_INFO("Slave EEPROM writing disabled.\n");
00824         }
00825     }
00826     else if (attr == &attr_debug_level) {
00827         if (!strcmp(buffer, "0\n")) {
00828             master->debug_level = 0;
00829         }
00830         else if (!strcmp(buffer, "1\n")) {
00831             master->debug_level = 1;
00832         }
00833         else if (!strcmp(buffer, "2\n")) {
00834             master->debug_level = 2;
00835         }
00836         else {
00837             EC_ERR("Invalid debug level value!\n");
00838             return -EINVAL;
00839         }
00840 
00841         EC_INFO("Master debug level set to %i.\n", master->debug_level);
00842         return size;
00843     }
00844 
00845     return -EINVAL;
00846 }
00847 
00848 /*****************************************************************************/
00849 
00854 void ec_master_eoe_start(ec_master_t *master )
00855 {
00856     ec_eoe_t *eoe;
00857     ec_slave_t *slave;
00858     unsigned int coupled, found;
00859 
00860     if (master->eoe_running || master->eoe_checked) return;
00861 
00862     master->eoe_checked = 1;
00863 
00864     // if the locking callbacks are not set in operation mode,
00865     // the EoE timer my not be started.
00866     if (master->mode == EC_MASTER_MODE_OPERATION
00867         && (!master->request_cb || !master->release_cb)) {
00868         EC_INFO("No EoE processing because of missing locking callbacks.\n");
00869         return;
00870     }
00871 
00872     // decouple all EoE handlers
00873     list_for_each_entry(eoe, &master->eoe_handlers, list)
00874         eoe->slave = NULL;
00875 
00876     // couple a free EoE handler to every EoE-capable slave
00877     coupled = 0;
00878     list_for_each_entry(slave, &master->slaves, list) {
00879         if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
00880 
00881         found = 0;
00882         list_for_each_entry(eoe, &master->eoe_handlers, list) {
00883             if (eoe->slave) continue;
00884             eoe->slave = slave;
00885             found = 1;
00886             coupled++;
00887             EC_INFO("Coupling device %s to slave %i.\n",
00888                     eoe->dev->name, slave->ring_position);
00889             if (eoe->opened) slave->requested_state = EC_SLAVE_STATE_OP;
00890             else slave->requested_state = EC_SLAVE_STATE_INIT;
00891             slave->error_flag = 0;
00892             break;
00893         }
00894 
00895         if (!found) {
00896             EC_WARN("No EoE handler for slave %i!\n", slave->ring_position);
00897             slave->requested_state = EC_SLAVE_STATE_INIT;
00898             slave->error_flag = 0;
00899         }
00900     }
00901 
00902     if (!coupled) {
00903         EC_INFO("No EoE handlers coupled.\n");
00904         return;
00905     }
00906 
00907     EC_INFO("Starting EoE processing.\n");
00908     master->eoe_running = 1;
00909 
00910     // start EoE processing
00911     master->eoe_timer.expires = jiffies + 10;
00912     add_timer(&master->eoe_timer);
00913     return;
00914 }
00915 
00916 /*****************************************************************************/
00917 
00922 void ec_master_eoe_stop(ec_master_t *master )
00923 {
00924     ec_eoe_t *eoe;
00925 
00926     master->eoe_checked = 0;
00927 
00928     if (!master->eoe_running) return;
00929 
00930     EC_INFO("Stopping EoE processing.\n");
00931 
00932     del_timer_sync(&master->eoe_timer);
00933 
00934     // decouple all EoE handlers
00935     list_for_each_entry(eoe, &master->eoe_handlers, list) {
00936         if (eoe->slave) {
00937             eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
00938             eoe->slave->error_flag = 0;
00939             eoe->slave = NULL;
00940         }
00941     }
00942 
00943     master->eoe_running = 0;
00944 }
00945 
00946 /*****************************************************************************/
00951 void ec_master_eoe_run(unsigned long data )
00952 {
00953     ec_master_t *master = (ec_master_t *) data;
00954     ec_eoe_t *eoe;
00955     unsigned int active = 0;
00956     cycles_t cycles_start, cycles_end;
00957     unsigned long restart_jiffies;
00958 
00959     list_for_each_entry(eoe, &master->eoe_handlers, list) {
00960         if (ec_eoe_active(eoe)) active++;
00961     }
00962     if (!active) goto queue_timer;
00963 
00964     // aquire master lock...
00965     if (master->mode == EC_MASTER_MODE_OPERATION) {
00966         // request_cb must return 0, if the lock has been aquired!
00967         if (master->request_cb(master->cb_data))
00968             goto queue_timer;
00969     }
00970     else if (master->mode == EC_MASTER_MODE_IDLE) {
00971         spin_lock(&master->internal_lock);
00972     }
00973     else
00974         goto queue_timer;
00975 
00976     // actual EoE processing
00977     cycles_start = get_cycles();
00978     ecrt_master_receive(master);
00979 
00980     list_for_each_entry(eoe, &master->eoe_handlers, list) {
00981         ec_eoe_run(eoe);
00982     }
00983 
00984     ecrt_master_send(master);
00985     cycles_end = get_cycles();
00986 
00987     // release lock...
00988     if (master->mode == EC_MASTER_MODE_OPERATION) {
00989         master->release_cb(master->cb_data);
00990     }
00991     else if (master->mode == EC_MASTER_MODE_IDLE) {
00992         spin_unlock(&master->internal_lock);
00993     }
00994 
00995     master->eoe_cycle_times[master->eoe_cycle_time_pos]
00996         = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz;
00997     master->eoe_cycle_time_pos++;
00998     master->eoe_cycle_time_pos %= HZ;
00999 
01000  queue_timer:
01001     restart_jiffies = HZ / EC_EOE_FREQUENCY;
01002     if (!restart_jiffies) restart_jiffies = 1;
01003     master->eoe_timer.expires += restart_jiffies;
01004     add_timer(&master->eoe_timer);
01005 }
01006 
01007 /*****************************************************************************/
01008 
01013 void ec_master_calc_addressing(ec_master_t *master )
01014 {
01015     uint16_t coupler_index, coupler_subindex;
01016     uint16_t reverse_coupler_index, current_coupler_index;
01017     ec_slave_t *slave;
01018 
01019     coupler_index = 0;
01020     reverse_coupler_index = 0xFFFF;
01021     current_coupler_index = 0x0000;
01022     coupler_subindex = 0;
01023 
01024     list_for_each_entry(slave, &master->slaves, list) {
01025         if (ec_slave_is_coupler(slave)) {
01026             if (slave->sii_alias)
01027                 current_coupler_index = reverse_coupler_index--;
01028             else
01029                 current_coupler_index = coupler_index++;
01030             coupler_subindex = 0;
01031         }
01032 
01033         slave->coupler_index = current_coupler_index;
01034         slave->coupler_subindex = coupler_subindex;
01035         coupler_subindex++;
01036     }
01037 }
01038 
01039 /*****************************************************************************/
01040 
01045 void ec_master_measure_bus_time(ec_master_t *master)
01046 {
01047     ec_datagram_t datagram;
01048     cycles_t cycles_start, cycles_end, cycles_timeout;
01049     uint32_t times[100], sum, min, max, i;
01050 
01051     ec_datagram_init(&datagram);
01052 
01053     if (ec_datagram_brd(&datagram, 0x130, 2)) {
01054         EC_ERR("Failed to allocate datagram for bus time measuring.\n");
01055         ec_datagram_clear(&datagram);
01056         return;
01057     }
01058 
01059     cycles_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000);
01060 
01061     sum = 0;
01062     min = 0xFFFFFFFF;
01063     max = 0;
01064 
01065     for (i = 0; i < 100; i++) {
01066         ec_master_queue_datagram(master, &datagram);
01067         ecrt_master_send(master);
01068         cycles_start = get_cycles();
01069 
01070         while (1) { // active waiting
01071             ec_device_call_isr(master->device);
01072             cycles_end = get_cycles(); // take current time
01073 
01074             if (datagram.state == EC_DATAGRAM_RECEIVED) {
01075                 break;
01076             }
01077             else if (datagram.state == EC_DATAGRAM_ERROR) {
01078                 EC_WARN("Failed to measure bus time.\n");
01079                 goto error;
01080             }
01081             else if (cycles_end - cycles_start >= cycles_timeout) {
01082                 EC_WARN("Timeout while measuring bus time.\n");
01083                 goto error;
01084             }
01085         }
01086 
01087         times[i] = (unsigned int) (cycles_end - cycles_start) * 1000 / cpu_khz;
01088         sum += times[i];
01089         if (times[i] > max) max = times[i];
01090         if (times[i] < min) min = times[i];
01091     }
01092 
01093     EC_INFO("Bus time is (min/avg/max) %u/%u.%u/%u us.\n",
01094             min, sum / 100, sum % 100, max);
01095 
01096   error:
01097     // Dequeue and free datagram
01098     list_del(&datagram.queue);
01099     ec_datagram_clear(&datagram);
01100 }
01101 
01102 /******************************************************************************
01103  *  Realtime interface
01104  *****************************************************************************/
01105 
01112 ec_domain_t *ecrt_master_create_domain(ec_master_t *master )
01113 {
01114     ec_domain_t *domain, *last_domain;
01115     unsigned int index;
01116 
01117     if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) {
01118         EC_ERR("Error allocating domain memory!\n");
01119         goto out_return;
01120     }
01121 
01122     if (list_empty(&master->domains)) index = 0;
01123     else {
01124         last_domain = list_entry(master->domains.prev, ec_domain_t, list);
01125         index = last_domain->index + 1;
01126     }
01127 
01128     if (ec_domain_init(domain, master, index)) {
01129         EC_ERR("Failed to init domain.\n");
01130         goto out_return;
01131     }
01132 
01133     if (kobject_add(&domain->kobj)) {
01134         EC_ERR("Failed to add domain kobject.\n");
01135         goto out_put;
01136     }
01137 
01138     list_add_tail(&domain->list, &master->domains);
01139     return domain;
01140 
01141  out_put:
01142     kobject_put(&domain->kobj);
01143  out_return:
01144     return NULL;
01145 }
01146 
01147 /*****************************************************************************/
01148 
01158 int ecrt_master_activate(ec_master_t *master )
01159 {
01160     uint32_t domain_offset;
01161     ec_domain_t *domain;
01162     ec_fsm_t *fsm = &master->fsm;
01163     ec_slave_t *slave;
01164 
01165     // allocate all domains
01166     domain_offset = 0;
01167     list_for_each_entry(domain, &master->domains, list) {
01168         if (ec_domain_alloc(domain, domain_offset)) {
01169             EC_ERR("Failed to allocate domain %X!\n", (u32) domain);
01170             return -1;
01171         }
01172         domain_offset += domain->data_size;
01173     }
01174 
01175     // determine initial states.
01176     list_for_each_entry(slave, &master->slaves, list) {
01177         if (ec_slave_is_coupler(slave) || slave->registered) {
01178             slave->requested_state = EC_SLAVE_STATE_OP;
01179         }
01180         else {
01181             slave->requested_state = EC_SLAVE_STATE_PREOP;
01182         }
01183     }
01184 
01185     ec_fsm_configuration(fsm); // init configuration state machine
01186 
01187     do {
01188         ec_fsm_execute(fsm);
01189         ec_master_sync_io(master);
01190     }
01191     while (ec_fsm_configuration_running(fsm));
01192 
01193     if (!ec_fsm_configuration_success(fsm)) {
01194         return -1;
01195     }
01196 
01197     ec_fsm_reset(&master->fsm); // prepare for operation state machine
01198 
01199     return 0;
01200 }
01201 
01202 /*****************************************************************************/
01203 
01209 void ecrt_master_deactivate(ec_master_t *master )
01210 {
01211     ec_fsm_t *fsm = &master->fsm;
01212     ec_slave_t *slave;
01213 
01214     list_for_each_entry(slave, &master->slaves, list) {
01215         slave->requested_state = EC_SLAVE_STATE_INIT;
01216     }
01217 
01218     ec_fsm_configuration(fsm); // init configuration state machine
01219 
01220     do {
01221         ec_fsm_execute(fsm);
01222         ec_master_sync_io(master);
01223     }
01224     while (ec_fsm_configuration_running(fsm));
01225 }
01226 
01227 /*****************************************************************************/
01228 
01233 void ec_master_sync_io(ec_master_t *master )
01234 {
01235     ec_datagram_t *datagram;
01236     unsigned int datagrams_waiting;
01237 
01238     // send datagrams
01239     ecrt_master_send(master);
01240 
01241     while (1) { // active waiting
01242         ecrt_master_receive(master); // receive and dequeue datagrams
01243 
01244         // count number of datagrams still waiting for response
01245         datagrams_waiting = 0;
01246         list_for_each_entry(datagram, &master->datagram_queue, queue) {
01247             datagrams_waiting++;
01248         }
01249 
01250         // if there are no more datagrams waiting, abort loop.
01251         if (!datagrams_waiting) break;
01252     }
01253 }
01254 
01255 /*****************************************************************************/
01256 
01262 void ecrt_master_send(ec_master_t *master )
01263 {
01264     ec_datagram_t *datagram, *n;
01265 
01266     if (unlikely(!master->device->link_state)) {
01267         // link is down, no datagram can be sent
01268         list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) {
01269             datagram->state = EC_DATAGRAM_ERROR;
01270             list_del_init(&datagram->queue);
01271         }
01272 
01273         // query link state
01274         ec_device_call_isr(master->device);
01275         return;
01276     }
01277 
01278     // send frames
01279     ec_master_send_datagrams(master);
01280 }
01281 
01282 /*****************************************************************************/
01283 
01289 void ecrt_master_receive(ec_master_t *master )
01290 {
01291     ec_datagram_t *datagram, *next;
01292     cycles_t cycles_received, cycles_timeout;
01293 
01294     ec_device_call_isr(master->device);
01295 
01296     cycles_received = get_cycles();
01297     cycles_timeout = EC_IO_TIMEOUT * cpu_khz / 1000;
01298 
01299     // dequeue all datagrams that timed out
01300     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
01301         switch (datagram->state) {
01302             case EC_DATAGRAM_SENT:
01303             case EC_DATAGRAM_QUEUED:
01304                 if (cycles_received - datagram->cycles_sent > cycles_timeout) {
01305                     list_del_init(&datagram->queue);
01306                     datagram->state = EC_DATAGRAM_TIMED_OUT;
01307                     master->stats.timeouts++;
01308                     ec_master_output_stats(master);
01309                 }
01310                 break;
01311             default:
01312                 break;
01313         }
01314     }
01315 }
01316 
01317 /*****************************************************************************/
01318 
01326 void ecrt_master_prepare(ec_master_t *master )
01327 {
01328     ec_domain_t *domain;
01329     cycles_t cycles_start, cycles_end, cycles_timeout;
01330 
01331     // queue datagrams of all domains
01332     list_for_each_entry(domain, &master->domains, list)
01333         ec_domain_queue(domain);
01334 
01335     ecrt_master_send(master);
01336 
01337     cycles_start = get_cycles(); // take sending time
01338     cycles_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000);
01339 
01340     // active waiting
01341     while (1) {
01342         cycles_end = get_cycles();
01343         if (cycles_end - cycles_start >= cycles_timeout) break;
01344     }
01345 }
01346 
01347 /*****************************************************************************/
01348 
01354 void ecrt_master_run(ec_master_t *master )
01355 {
01356     // output statistics
01357     ec_master_output_stats(master);
01358 
01359     // execute master state machine
01360     ec_fsm_execute(&master->fsm);
01361 }
01362 
01363 /*****************************************************************************/
01364 
01378 ec_slave_t *ecrt_master_get_slave(const ec_master_t *master, 
01379                                   const char *address 
01380                                   )
01381 {
01382     unsigned long first, second;
01383     char *remainder, *remainder2;
01384     unsigned int alias_requested, alias_found;
01385     ec_slave_t *alias_slave = NULL, *slave;
01386 
01387     if (!address || address[0] == 0) return NULL;
01388 
01389     alias_requested = 0;
01390     if (address[0] == '#') {
01391         alias_requested = 1;
01392         address++;
01393     }
01394 
01395     first = simple_strtoul(address, &remainder, 0);
01396     if (remainder == address) {
01397         EC_ERR("Slave address \"%s\" - First number empty!\n", address);
01398         return NULL;
01399     }
01400 
01401     if (alias_requested) {
01402         alias_found = 0;
01403         list_for_each_entry(alias_slave, &master->slaves, list) {
01404             if (alias_slave->sii_alias == first) {
01405                 alias_found = 1;
01406                 break;
01407             }
01408         }
01409         if (!alias_found) {
01410             EC_ERR("Slave address \"%s\" - Alias not found!\n", address);
01411             return NULL;
01412         }
01413     }
01414 
01415     if (!remainder[0]) { // absolute position
01416         if (alias_requested) {
01417             return alias_slave;
01418         }
01419         else {
01420             list_for_each_entry(slave, &master->slaves, list) {
01421                 if (slave->ring_position == first) return slave;
01422             }
01423             EC_ERR("Slave address \"%s\" - Absolute position invalid!\n",
01424                    address);
01425         }
01426     }
01427     else if (remainder[0] == ':') { // field position
01428         remainder++;
01429         second = simple_strtoul(remainder, &remainder2, 0);
01430 
01431         if (remainder2 == remainder) {
01432             EC_ERR("Slave address \"%s\" - Second number empty!\n", address);
01433             return NULL;
01434         }
01435 
01436         if (remainder2[0]) {
01437             EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address);
01438             return NULL;
01439         }
01440 
01441         if (alias_requested) {
01442             if (!ec_slave_is_coupler(alias_slave)) {
01443                 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler"
01444                        " in colon mode.\n", address);
01445                 return NULL;
01446             }
01447             list_for_each_entry(slave, &master->slaves, list) {
01448                 if (slave->coupler_index == alias_slave->coupler_index
01449                     && slave->coupler_subindex == second)
01450                     return slave;
01451             }
01452             EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave"
01453                    " following!\n", address, alias_slave->ring_position,
01454                    second);
01455             return NULL;
01456         }
01457         else {
01458             list_for_each_entry(slave, &master->slaves, list) {
01459                 if (slave->coupler_index == first
01460                     && slave->coupler_subindex == second) return slave;
01461             }
01462         }
01463     }
01464     else
01465         EC_ERR("Slave address \"%s\" - Invalid format!\n", address);
01466 
01467     return NULL;
01468 }
01469 
01470 /*****************************************************************************/
01471 
01480 void ecrt_master_callbacks(ec_master_t *master, 
01481                            int (*request_cb)(void *), 
01482                            void (*release_cb)(void *), 
01483                            void *cb_data 
01484                            )
01485 {
01486     master->request_cb = request_cb;
01487     master->release_cb = release_cb;
01488     master->cb_data = cb_data;
01489 }
01490 
01491 /*****************************************************************************/
01492 
01495 EXPORT_SYMBOL(ecrt_master_create_domain);
01496 EXPORT_SYMBOL(ecrt_master_activate);
01497 EXPORT_SYMBOL(ecrt_master_deactivate);
01498 EXPORT_SYMBOL(ecrt_master_prepare);
01499 EXPORT_SYMBOL(ecrt_master_send);
01500 EXPORT_SYMBOL(ecrt_master_receive);
01501 EXPORT_SYMBOL(ecrt_master_run);
01502 EXPORT_SYMBOL(ecrt_master_callbacks);
01503 EXPORT_SYMBOL(ecrt_master_get_slave);
01504 
01507 /*****************************************************************************/

Generated on Fri Sep 1 14:56:56 2006 for IgH EtherCAT master by  doxygen 1.4.6