fp@1514: /***************************************************************************** fp@1514: * fp@1524: * $Id$ fp@1514: * fp@1514: * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH fp@1514: * fp@1514: * This file is part of the IgH EtherCAT Master. fp@1514: * fp@1514: * The IgH EtherCAT Master is free software; you can redistribute it and/or fp@1514: * modify it under the terms of the GNU General Public License version 2, as fp@1514: * published by the Free Software Foundation. fp@1514: * fp@1514: * The IgH EtherCAT Master is distributed in the hope that it will be useful, fp@1514: * but WITHOUT ANY WARRANTY; without even the implied warranty of fp@1514: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General fp@1514: * Public License for more details. fp@1514: * fp@1514: * You should have received a copy of the GNU General Public License along fp@1514: * with the IgH EtherCAT Master; if not, write to the Free Software fp@1514: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA fp@1514: * fp@1514: * --- fp@1514: * fp@1514: * The license mentioned above concerns the source code only. Using the fp@1514: * EtherCAT technology and brand is only permitted in compliance with the fp@1514: * industrial property and similar rights of Beckhoff Automation GmbH. fp@1514: * fp@1879: * vim: expandtab fp@1879: * fp@1514: ****************************************************************************/ fp@1514: fp@1514: #include fp@1514: #include fp@1514: #include fp@1514: using namespace std; fp@1514: fp@1514: #include "CommandCStruct.h" fp@1826: #include "MasterDevice.h" fp@1514: fp@1514: /*****************************************************************************/ fp@1514: fp@1514: CommandCStruct::CommandCStruct(): fp@1514: Command("cstruct", "Generate slave PDO information in C language.") fp@1514: { fp@1514: } fp@1514: fp@1514: /*****************************************************************************/ fp@1514: fp@1968: string CommandCStruct::helpString(const string &binaryBaseName) const fp@1514: { fp@1514: stringstream str; fp@1514: fp@1968: str << binaryBaseName << " " << getName() << " [OPTIONS]" << endl fp@1514: << endl fp@1514: << getBriefDescription() << endl fp@1514: << endl fp@1514: << "The output C code can be used directly with the" << endl fp@1514: << "ecrt_slave_config_pdos() function of the application" << endl fp@1804: << "interface." << endl fp@1514: << endl fp@1514: << "Command-specific options:" << endl fp@1514: << " --alias -a " << endl fp@1514: << " --position -p Slave selection. See the help of" << endl fp@1514: << " the 'slaves' command." << endl fp@1514: << endl fp@1514: << numericInfo(); fp@1514: fp@1514: return str.str(); fp@1514: } fp@1514: fp@1514: /****************************************************************************/ fp@1514: fp@1826: void CommandCStruct::execute(const StringVector &args) fp@1514: { fp@1879: MasterIndexList masterIndices; fp@1514: SlaveList slaves; fp@1514: SlaveList::const_iterator si; fp@1514: fp@1514: if (args.size()) { fp@1514: stringstream err; fp@1514: err << "'" << getName() << "' takes no arguments!"; fp@1514: throwInvalidUsageException(err); fp@1514: } fp@1514: fp@1879: masterIndices = getMasterIndices(); fp@1826: MasterIndexList::const_iterator mi; fp@1869: for (mi = masterIndices.begin(); fp@1869: mi != masterIndices.end(); mi++) { fp@1826: MasterDevice m(*mi); fp@1826: m.open(MasterDevice::Read); fp@1826: slaves = selectedSlaves(m); fp@1826: fp@1826: for (si = slaves.begin(); si != slaves.end(); si++) { fp@1826: generateSlaveCStruct(m, *si); fp@1826: } fp@1514: } fp@1514: } fp@1514: fp@1514: /****************************************************************************/ fp@1514: fp@1514: void CommandCStruct::generateSlaveCStruct( fp@1514: MasterDevice &m, fp@1514: const ec_ioctl_slave_t &slave fp@1514: ) fp@1514: { fp@1514: ec_ioctl_slave_sync_t sync; fp@1514: ec_ioctl_slave_sync_pdo_t pdo; fp@1514: ec_ioctl_slave_sync_pdo_entry_t entry; fp@1514: unsigned int i, j, k, pdo_pos = 0, entry_pos = 0; fp@1514: stringstream id, syncs, pdos, entries; fp@1514: fp@1514: if (!slave.sync_count) fp@1514: return; fp@1514: fp@1514: id << "slave_" << dec << slave.position << "_"; fp@1514: fp@1514: for (i = 0; i < slave.sync_count; i++) { fp@1514: m.getSync(&sync, slave.position, i); fp@1514: fp@1949: syncs << " {" << dec << sync.sync_index fp@1514: << ", " << (EC_READ_BIT(&sync.control_register, 2) ? fp@1514: "EC_DIR_OUTPUT" : "EC_DIR_INPUT") fp@1514: << ", " << dec << (unsigned int) sync.pdo_count fp@1514: << ", "; fp@1514: if (sync.pdo_count) { fp@1514: syncs << id.str() << "pdos + " << dec << pdo_pos; fp@1514: } else { fp@1514: syncs << "NULL"; fp@1514: } fp@1514: syncs << ", " << (EC_READ_BIT(&sync.control_register, 6) ? fp@1514: "EC_WD_ENABLE" : "EC_WD_DISABLE") fp@1514: << "},"; fp@1514: syncs << endl; fp@1514: pdo_pos += sync.pdo_count; fp@1514: fp@1514: for (j = 0; j < sync.pdo_count; j++) { fp@1514: m.getPdo(&pdo, slave.position, i, j); fp@1514: fp@1949: pdos << " {0x" << hex << setfill('0') fp@1514: << setw(4) << pdo.index fp@1514: << ", " << dec << (unsigned int) pdo.entry_count fp@1514: << ", "; fp@1514: if (pdo.entry_count) { fp@1514: pdos << id.str() << "pdo_entries + " << dec << entry_pos; fp@1514: } else { fp@1514: pdos << "NULL"; fp@1514: } fp@1514: pdos << "},"; fp@1514: if (strlen((const char *) pdo.name)) { fp@1514: pdos << " /* " << pdo.name << " */"; fp@1514: } fp@1514: pdos << endl; fp@1514: entry_pos += pdo.entry_count; fp@1514: fp@1514: for (k = 0; k < pdo.entry_count; k++) { fp@1514: m.getPdoEntry(&entry, slave.position, i, j, k); fp@1514: fp@1949: entries << " {0x" << hex << setfill('0') fp@1514: << setw(4) << entry.index fp@1514: << ", 0x" << setw(2) << (unsigned int) entry.subindex fp@1514: << ", " << dec << (unsigned int) entry.bit_length fp@1514: << "},"; fp@1514: if (strlen((const char *) entry.name)) { fp@1514: entries << " /* " << entry.name << " */"; fp@1514: } fp@1514: entries << endl; fp@1514: } fp@1514: } fp@1514: } fp@1514: fp@1514: cout fp@1827: << "/* Master " << m.getIndex() << ", Slave " << slave.position; fp@1514: if (strlen(slave.order)) { fp@1514: cout << ", \"" << slave.order << "\""; fp@1514: } fp@1514: fp@1514: cout << endl fp@1514: << " * Vendor ID: 0x" << hex << setfill('0') fp@1514: << setw(8) << slave.vendor_id << endl fp@1514: << " * Product code: 0x" << hex << setfill('0') fp@1514: << setw(8) << slave.product_code << endl fp@1514: << " * Revision number: 0x" << hex << setfill('0') fp@2421: << setw(8) << slave.revision_number << endl fp@1514: << " */" << endl fp@1514: << endl; fp@1514: fp@1514: if (entry_pos) { fp@1514: cout << "ec_pdo_entry_info_t " << id.str() fp@1514: << "pdo_entries[] = {" << endl fp@1514: << entries.str() fp@1514: << "};" << endl fp@1514: << endl; fp@1514: } fp@1514: fp@1514: if (pdo_pos) { fp@1514: cout << "ec_pdo_info_t " << id.str() << "pdos[] = {" << endl fp@1514: << pdos.str() fp@1514: << "};" << endl fp@1514: << endl; fp@1514: } fp@1514: fp@1514: cout << "ec_sync_info_t " << id.str() << "syncs[] = {" << endl fp@1514: << syncs.str() fp@1949: << " {0xff}" << endl fp@1514: << "};" << endl fp@1514: << endl; fp@1514: } fp@1514: fp@1514: /*****************************************************************************/