fp@1868: /***************************************************************************** fp@1868: * fp@1868: * $Id$ fp@1868: * fp@1868: * Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH fp@1868: * fp@1868: * This file is part of the IgH EtherCAT Master. fp@1868: * fp@1868: * The IgH EtherCAT Master is free software; you can redistribute it and/or fp@1868: * modify it under the terms of the GNU General Public License version 2, as fp@1868: * published by the Free Software Foundation. fp@1868: * fp@1868: * The IgH EtherCAT Master is distributed in the hope that it will be useful, fp@1868: * but WITHOUT ANY WARRANTY; without even the implied warranty of fp@1868: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General fp@1868: * Public License for more details. fp@1868: * fp@1868: * You should have received a copy of the GNU General Public License along fp@1868: * with the IgH EtherCAT Master; if not, write to the Free Software fp@1868: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA fp@1868: * fp@1868: * --- fp@1868: * fp@1868: * The license mentioned above concerns the source code only. Using the fp@1868: * EtherCAT technology and brand is only permitted in compliance with the fp@1868: * industrial property and similar rights of Beckhoff Automation GmbH. fp@1868: * fp@1868: ****************************************************************************/ fp@1868: fp@1868: #include fp@1868: using namespace std; fp@1868: fp@1868: #include "SoeCommand.h" fp@1868: fp@1877: extern const ec_code_msg_t soe_error_codes[]; fp@1877: fp@1868: /*****************************************************************************/ fp@1868: fp@1868: uint16_t SoeCommand::parseIdn(const string &str) fp@1868: { fp@1868: uint16_t idn = 0x0000; fp@1868: stringstream s, err; fp@1868: fp@1868: if (!str.length()) { fp@1868: err << "Zero-size string not allowed!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: fp@1868: if (str[0] == 'S' || str[0] == 'P') { fp@1868: unsigned int num; fp@1868: unsigned char c; fp@1868: fp@1868: s << str; fp@1868: fp@1868: s >> c; fp@1868: if (c == 'P') { fp@1868: idn |= 0x8000; fp@1868: } fp@1868: fp@1868: s >> c; fp@1868: if (s.fail() || c != '-') { fp@1868: err << "'-' expected!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: fp@1868: s >> num; fp@1868: if (s.fail() || num > 7) { fp@1868: err << "Invalid parameter set number!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: idn |= num << 12; fp@1868: fp@1868: s >> c; fp@1868: if (s.fail() || c != '-') { fp@1868: err << "'-' expected!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: fp@1868: s >> num; fp@1868: if (s.fail() || num > 4095) { fp@1868: err << "Invalid data block number!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: idn |= num; fp@1868: fp@1868: s.peek(); fp@1868: if (!s.eof()) { fp@1868: err << "Additional input!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: } else { fp@1868: s << str; fp@1868: s >> resetiosflags(ios::basefield) >> idn; fp@1868: if (s.fail()) { fp@1868: err << "Invalid number!"; fp@1868: throw runtime_error(err.str()); fp@1868: } fp@1868: } fp@1868: fp@1868: return idn; fp@1868: } fp@1868: fp@1877: /*****************************************************************************/ fp@1877: fp@1966: string SoeCommand::outputIdn(uint16_t idn) fp@1966: { fp@1966: stringstream str; fp@1966: fp@1966: str << ((idn & 0x8000) ? 'P' : 'S') fp@1966: << "-" << ((idn >> 12) & 0x07) fp@1966: << "-" << setfill('0') << setw(4) << (idn & 0x0fff); fp@1966: fp@1966: return str.str(); fp@1966: } fp@1966: fp@1966: /*****************************************************************************/ fp@1966: fp@1877: /** Outputs an SoE error code. fp@1877: */ fp@1877: std::string SoeCommand::errorMsg(uint16_t code) fp@1877: { fp@1877: const ec_code_msg_t *error_msg; fp@1877: stringstream str; fp@1877: fp@1877: str << "0x" << hex << setfill('0') << setw(4) << code << ": "; fp@1877: fp@1877: for (error_msg = soe_error_codes; error_msg->code; error_msg++) { fp@1877: if (error_msg->code == code) { fp@1877: str << error_msg->message; fp@1877: return str.str(); fp@1877: } fp@1877: } fp@1877: fp@1877: str << "(Unknown)"; fp@1877: return str.str(); fp@1877: } fp@1877: fp@1868: /****************************************************************************/