# HG changeset patch # User Florian Pose # Date 1351095712 -7200 # Node ID 960cc1bb6b4a87c9b830dc8aca037546ef39dde1 # Parent 4151f6f4c3e196dcc6b68e99523d57218c8851a6 EtherLab skin for 'ethercat pdos' command. diff -r 4151f6f4c3e1 -r 960cc1bb6b4a tool/Command.cpp --- a/tool/Command.cpp Tue Oct 09 09:52:50 2012 +0200 +++ b/tool/Command.cpp Wed Oct 24 18:21:52 2012 +0200 @@ -216,6 +216,13 @@ outputFile = f; }; +/*****************************************************************************/ + +void Command::setSkin(const string &s) +{ + skin = s; +}; + /****************************************************************************/ bool Command::matchesSubstr(const string &cmd) const diff -r 4151f6f4c3e1 -r 960cc1bb6b4a tool/Command.h --- a/tool/Command.h Tue Oct 09 09:52:50 2012 +0200 +++ b/tool/Command.h Wed Oct 24 18:21:52 2012 +0200 @@ -113,6 +113,9 @@ void setOutputFile(const string &); const string &getOutputFile() const; + void setSkin(const string &); + const string &getSkin() const; + bool matchesSubstr(const string &) const; bool matchesAbbrev(const string &) const; @@ -151,6 +154,7 @@ string dataType; bool force; string outputFile; + string skin; Command(); }; @@ -199,4 +203,11 @@ /****************************************************************************/ +inline const string &Command::getSkin() const +{ + return skin; +} + +/****************************************************************************/ + #endif diff -r 4151f6f4c3e1 -r 960cc1bb6b4a tool/CommandPdos.cpp --- a/tool/CommandPdos.cpp Tue Oct 09 09:52:50 2012 +0200 +++ b/tool/CommandPdos.cpp Wed Oct 24 18:21:52 2012 +0200 @@ -29,6 +29,7 @@ #include #include +#include using namespace std; #include "CommandPdos.h" @@ -51,7 +52,8 @@ << endl << getBriefDescription() << endl << endl - << "The information is displayed in three layers, which are" << endl + << "For the default skin (see --skin option) the information" << endl + << "is displayed in three layers, which are" << endl << "indented accordingly:" << endl << endl << "1) Sync managers - Contains the sync manager information" << endl @@ -77,10 +79,16 @@ << "information can either originate from the SII or from the" << endl << "CoE communication area." << endl << endl + << "The \"etherlab\" skin outputs a template configuration" << endl + << "for EtherLab's generic EtherCAT slave block." << endl + << endl << "Command-specific options:" << endl << " --alias -a " << endl << " --position -p Slave selection. See the help of" << endl << " the 'slaves' command." << endl + << " --skin -s Choose output skin. Possible values are" + << endl + << " \"default\" and \"etherlab\"." << endl << endl << numericInfo(); @@ -102,19 +110,40 @@ throwInvalidUsageException(err); } - masterIndices = getMasterIndices(); - multiMaster = masterIndices.size() > 1; - MasterIndexList::const_iterator mi; - for (mi = masterIndices.begin(); - mi != masterIndices.end(); mi++) { - MasterDevice m(*mi); - m.open(MasterDevice::Read); - slaves = selectedSlaves(m); - showHeader = multiMaster || slaves.size() > 1; - - for (si = slaves.begin(); si != slaves.end(); si++) { - listSlavePdos(m, *si, showHeader); - } + if (getSkin().empty() || getSkin() == "default") { + masterIndices = getMasterIndices(); + multiMaster = masterIndices.size() > 1; + MasterIndexList::const_iterator mi; + for (mi = masterIndices.begin(); + mi != masterIndices.end(); mi++) { + MasterDevice m(*mi); + m.open(MasterDevice::Read); + slaves = selectedSlaves(m); + showHeader = multiMaster || slaves.size() > 1; + + for (si = slaves.begin(); si != slaves.end(); si++) { + listSlavePdos(m, *si, showHeader); + } + } + } + else if (getSkin() == "etherlab") { + masterIndices = getMasterIndices(); + MasterIndexList::const_iterator mi; + for (mi = masterIndices.begin(); + mi != masterIndices.end(); mi++) { + MasterDevice m(*mi); + m.open(MasterDevice::Read); + slaves = selectedSlaves(m); + + for (si = slaves.begin(); si != slaves.end(); si++) { + etherlabConfig(m, *si); + } + } + } + else { + stringstream err; + err << "Invalid skin '" << getSkin() << "'!"; + throwInvalidUsageException(err); } } @@ -177,4 +206,111 @@ } } +/****************************************************************************/ + +void CommandPdos::etherlabConfig( + MasterDevice &m, + const ec_ioctl_slave_t &slave + ) +{ + ec_ioctl_slave_sync_t sync; + ec_ioctl_slave_sync_pdo_t pdo; + ec_ioctl_slave_sync_pdo_entry_t entry; + unsigned int i, j, k; + + cout << "%" << endl + << "% Master " << m.getIndex() << ", Slave " << slave.position; + if (strlen(slave.order)) { + cout << ", \"" << slave.order << "\""; + } + cout << endl + << "%" << endl + << "function rv = slave" << slave.position << "()" << endl << endl; + + cout << "% Slave configuration" << endl << endl; + + cout << "rv.SlaveConfig.vendor = " << slave.vendor_id << ";" << endl + << "rv.SlaveConfig.product = hex2dec('" + << hex << setfill('0') << setw(8) << slave.product_code << "');" + << endl + << "rv.SlaveConfig.description = '" << slave.order << "';" << endl + << "rv.SlaveConfig.sm = { ..." << endl; + + /* slave configuration */ + for (i = 0; i < slave.sync_count; i++) { + m.getSync(&sync, slave.position, i); + + cout << " {" << dec << i << ", " + << (sync.control_register & 0x04 ? 0 : 1) << ", {" << endl; + + for (j = 0; j < sync.pdo_count; j++) { + m.getPdo(&pdo, slave.position, i, j); + + cout << " {hex2dec('" << + hex << setfill('0') << setw(4) << pdo.index << "'), [" + << endl; + + for (k = 0; k < pdo.entry_count; k++) { + m.getPdoEntry(&entry, slave.position, i, j, k); + + cout << " hex2dec('" + << hex << setfill('0') << setw(4) << entry.index + << "'), hex2dec('" + << setw(2) << (unsigned int) entry.subindex + << "'), " << dec << setfill(' ') << setw(3) + << (unsigned int) entry.bit_length + << "; ..." << endl; + } + + cout << " ]}, ..." << endl; + } + cout << " }}, ..." << endl; + } + + cout << " };" << endl << endl; + + cout << "% Port configuration" << endl << endl; + + unsigned int input = 1, output = 1; + for (i = 0; i < slave.sync_count; i++) { + m.getSync(&sync, slave.position, i); + + for (j = 0; j < sync.pdo_count; j++) { + m.getPdo(&pdo, slave.position, i, j); + + for (k = 0; k < pdo.entry_count; k++) { + m.getPdoEntry(&entry, slave.position, i, j, k); + + if (!entry.index) { + continue; + } + + string dir; + unsigned int port; + + if (sync.control_register & 0x04) { + dir = "input"; + port = input++; + } + else { + dir = "output"; + port = output++; + } + + stringstream var; + var << "rv.PortConfig." << dir << "(" << dec << port + << ")"; + + cout << var.str() << ".pdo = [" + << i << ", " << j << ", " << k << ", 0];" << endl; + cout << var.str() << ".pdo_data_type = " + << 1000 + (unsigned int) entry.bit_length + << ";" << endl << endl; + } + } + } + + cout << "end" << endl; +} + /*****************************************************************************/ diff -r 4151f6f4c3e1 -r 960cc1bb6b4a tool/CommandPdos.h --- a/tool/CommandPdos.h Tue Oct 09 09:52:50 2012 +0200 +++ b/tool/CommandPdos.h Wed Oct 24 18:21:52 2012 +0200 @@ -45,6 +45,7 @@ protected: void listSlavePdos(MasterDevice &, const ec_ioctl_slave_t &, bool); + void etherlabConfig(MasterDevice &, const ec_ioctl_slave_t &); }; /****************************************************************************/ diff -r 4151f6f4c3e1 -r 960cc1bb6b4a tool/main.cpp --- a/tool/main.cpp Tue Oct 09 09:52:50 2012 +0200 +++ b/tool/main.cpp Wed Oct 24 18:21:52 2012 +0200 @@ -85,6 +85,7 @@ bool force = false; bool helpRequested = false; string outputFile; +string skin; /*****************************************************************************/ @@ -147,6 +148,7 @@ {"domain", required_argument, NULL, 'd'}, {"type", required_argument, NULL, 't'}, {"output-file", required_argument, NULL, 'o'}, + {"skin", required_argument, NULL, 's'}, {"force", no_argument, NULL, 'f'}, {"quiet", no_argument, NULL, 'q'}, {"verbose", no_argument, NULL, 'v'}, @@ -155,7 +157,7 @@ }; do { - c = getopt_long(argc, argv, "m:a:p:d:t:o:fqvh", longOptions, NULL); + c = getopt_long(argc, argv, "m:a:p:d:t:o:s:fqvh", longOptions, NULL); switch (c) { case 'm': @@ -182,6 +184,10 @@ outputFile = optarg; break; + case 's': + skin = optarg; + break; + case 'f': force = true; break; @@ -308,6 +314,7 @@ cmd->setDomains(domains); cmd->setDataType(dataTypeStr); cmd->setOutputFile(outputFile); + cmd->setSkin(skin); cmd->setForce(force); cmd->execute(commandArgs); } catch (InvalidUsageException &e) {