/* ======================================================================== *\ ! ! * ! * This file is part of Stesy, the MAGIC Steering System ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz , 2001 ! ! Copyright: MAGIC Software Development, 2000-2001 ! ! \* ======================================================================== */ /////////////////////////////////////////////////////////////////////// // // NodeDrv // // Base class for a class describing the interface for the CAN nodes. // // to be overloaded: // virtual void Init() // virtual void StopDevice() // virtual void HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv) // virtual void HandleSDOOK(WORD_t idx, BYTE_t subidx) // virtual void HandleSDOError(LWORD_t data) // virtual void HandlePDO1(BYTE_t *data, timeval_t *tv) // virtual void HandlePDO2(BYTE_t *data, timeval_t *tv) // virtual void HandlePDO3(BYTE_t *data, timeval_t *tv) // virtual void HandlePDO4(BYTE_t *data, timeval_t *tv) // virtual bool Reboot(); // virtual void CheckConnection(); // /////////////////////////////////////////////////////////////////////// #include "nodedrv.h" #include #include #include "network.h" #include "MLogManip.h" ClassImp(NodeDrv); // -------------------------------------------------------------------------- // // Constructor for one node. Sets the Node Id (<32) the logging stream // and the node name. The name is a name for debug output. // NodeDrv::NodeDrv(BYTE_t nodeid, const char *name, MLog &out) : Log(out), fNetwork(NULL), fId(32), fError(0), fIsZombie(kTRUE) { if (nodeid>0x1f) { cout << "SetNode - Error: Only node Numbers < 32 are allowed"<< endl; return; } fId = nodeid; if (name) fName = name; else { fName = "Node#"; fName += (int)nodeid; } lout << "- Node #" << (int)nodeid << " (" << name << ") initialized." << endl; } // -------------------------------------------------------------------------- // // Empty destructor // NodeDrv::~NodeDrv() { } // -------------------------------------------------------------------------- // // This should be called from a master or main thread to get a node out // of the Zombie-Status. Overload it by your needs. // bool NodeDrv::Reboot() { fIsZombie = false; Init(); return !fIsZombie; } // -------------------------------------------------------------------------- // // Init device, sets the pointer to the whole network and enables // the Can messages to be passed through the interface: // PDO1 tx // PDO2 tx // PDO3 tx // PDO4 tx // SDO rx // SDO tx // bool NodeDrv::InitDevice(Network *net) { fNetwork = net; EnableCanMsg(kPDO1_TX); EnableCanMsg(kPDO2_TX); EnableCanMsg(kPDO3_TX); EnableCanMsg(kPDO4_TX); EnableCanMsg(kSDO_RX); EnableCanMsg(kSDO_TX); fIsZombie = kFALSE; Init(); return !fIsZombie; } // -------------------------------------------------------------------------- // // Print an "SDO idx/subidx set." from this device message. // This output is never redirected to the GUI // void NodeDrv::HandleSDOOK(WORD_t idx, BYTE_t subidx) { const Bool_t gui = lout.IsOutputDeviceEnabled(MLog::eGui); if (gui) lout << ddev(MLog::eGui); lout << hex << setfill('0'); lout << "Sdo=" << idx << "/" << (int)subidx << " set."; lout << endl; if (gui) lout << edev(MLog::eGui); } // -------------------------------------------------------------------------- // // Print an error message with the corresponding data from this device. // void NodeDrv::HandleSDOError(LWORD_t data) { lout << "Nodedrv: SDO Error: Entry not found in dictionary (data=0x"; lout << hex << setfill('0') << setw(4) << data << ")"; lout << endl; } // -------------------------------------------------------------------------- // // Prints the received SDo from this device // void NodeDrv::HandleSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, timeval_t *tv) { cout << "SdoRx: Idx=0x"<< hex << idx << "/" << (int)subidx; cout << ", val=0x" << val << endl; } // -------------------------------------------------------------------------- // // Sends the given PDO1 through the network to this device // A PDO is carrying up to eight bytes of information. // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendPDO1(BYTE_t data[8]) { if (!fIsZombie) fNetwork->SendPDO1(fId, data); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given PDO2 through the network to this device // A PDO is carrying up to eight bytes of information. // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendPDO2(BYTE_t data[8]) { if (!fIsZombie) fNetwork->SendPDO2(fId, data); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given PDO1 through the network to this device // A PDO is carrying up to eight bytes of information. // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendPDO1(BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0, BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0) { if (!fIsZombie) fNetwork->SendPDO1(fId, m0, m1, m2, m3, m4, m5, m6, m7); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given PDO2 through the network to this device // A PDO is carrying up to eight bytes of information. // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendPDO2(BYTE_t m0=0, BYTE_t m1=0, BYTE_t m2=0, BYTE_t m3=0, BYTE_t m4=0, BYTE_t m5=0, BYTE_t m6=0, BYTE_t m7=0) { if (!fIsZombie) fNetwork->SendPDO2(fId, m0, m1, m2, m3, m4, m5, m6, m7); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given SDO through the network to this device // An SDO message contains // an address (this device) // an index of the dictionary entry to address // a subindex of this dictionary entry to access // and a value to set for this dictionary entry // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendSDO(WORD_t idx, BYTE_t subidx, BYTE_t val, bool store) { if (!fIsZombie) fNetwork->SendSDO(fId, idx, subidx, val, store); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given SDO through the network to this device // An SDO message contains // an address (this device) // an index of the dictionary entry to address // a subindex of this dictionary entry to access // and a value to set for this dictionary entry // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendSDO(WORD_t idx, BYTE_t subidx, WORD_t val, bool store) { if (!fIsZombie) fNetwork->SendSDO(fId, idx, subidx, val, store); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given SDO through the network to this device // An SDO message contains // an address (this device) // an index of the dictionary entry to address // a subindex of this dictionary entry to access // and a value to set for this dictionary entry // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendSDO(WORD_t idx, BYTE_t subidx, LWORD_t val, bool store) { if (!fIsZombie) fNetwork->SendSDO(fId, idx, subidx, val, store); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given SDO through the network to this device // An SDO message contains // an address (this device) // an index of the dictionary entry to address // a subindex of this dictionary entry to access // and a value to set for this dictionary entry // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendSDO(WORD_t idx, BYTE_t val) { if (!fIsZombie) fNetwork->SendSDO(fId, idx, val, true); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given SDO through the network to this device // An SDO message contains // an address (this device) // an index of the dictionary entry to address // a subindex of this dictionary entry to access // and a value to set for this dictionary entry // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendSDO(WORD_t idx, WORD_t val) { if (!fIsZombie) fNetwork->SendSDO(fId, idx, val, true); return !fIsZombie; } // -------------------------------------------------------------------------- // // Sends the given SDO through the network to this device // An SDO message contains // an address (this device) // an index of the dictionary entry to address // a subindex of this dictionary entry to access // and a value to set for this dictionary entry // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendSDO(WORD_t idx, LWORD_t val) { if (!fIsZombie) fNetwork->SendSDO(fId, idx, val, true); return !fIsZombie; } // -------------------------------------------------------------------------- // // Request a SDO for a given idx/subidx // An SDO message contains // an address (this device) // an index of the dictionary entry to read // a subindex of this dictionary entry to access // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::RequestSDO(WORD_t idx, BYTE_t subidx) { if (!fIsZombie) fNetwork->RequestSDO(fId, idx, subidx); return !fIsZombie; } // -------------------------------------------------------------------------- // // Send an NMT message (command) to this device // // The message is not send if the node has the status Zombie. // In this case false is returned, otherwise true // bool NodeDrv::SendNMT(BYTE_t cmd) { if (!fIsZombie) fNetwork->SendNMT(fId, cmd); return !fIsZombie; } // -------------------------------------------------------------------------- // // Enable passthrough for the given functioncode of this device // void NodeDrv::EnableCanMsg(BYTE_t fcode) { fNetwork->EnableCanMsg(fId, fcode, TRUE); } // -------------------------------------------------------------------------- // // Wait a given timeout until the SDO with the given idx/subidx from // this device has been received. // You can stop waiting by StopWaitingForSDO. // Return false if waiting timed out. // If waiting timed out the node is set to status Zombie. // // If the node is already a zombie node, the message is deleted from the // queue and no waiting is done, false is returned.. // bool NodeDrv::WaitForSdo(WORD_t idx, BYTE_t subidx, WORDS_t timeout) { bool rc = fNetwork->WaitForSdo(fId, idx, subidx, fIsZombie?-1:timeout); if (!rc) fIsZombie = kTRUE; return fIsZombie ? false : rc; } /* void NodeDrv::WaitForSdos() { while (fNetwork->WaitingForSdo(fId)) usleep(1); } */ // -------------------------------------------------------------------------- // // Waits until the next Pdo1 from this device has been received // void NodeDrv::WaitForNextPdo1() { fNetwork->WaitForNextPdo1(fId); } // -------------------------------------------------------------------------- // // Waits until the next Pdo2 from this device has been received // void NodeDrv::WaitForNextPdo2() { fNetwork->WaitForNextPdo2(fId); } // -------------------------------------------------------------------------- // // Waits until the next Pdo3 from this device has been received // void NodeDrv::WaitForNextPdo3() { fNetwork->WaitForNextPdo3(fId); } // -------------------------------------------------------------------------- // // Waits until the next Pdo4 from this device has been received // void NodeDrv::WaitForNextPdo4() { fNetwork->WaitForNextPdo4(fId); }