Go to the documentation of this file.00001 #include <canopen_master/canopen.h>
00002 #include <socketcan_interface/string.h>
00003
00004 using namespace canopen;
00005
00006 #pragma pack(push)
00007 #pragma pack(1)
00008
00009 struct EMCYid{
00010 uint32_t id:29;
00011 uint32_t extended:1;
00012 uint32_t :1;
00013 uint32_t invalid:1;
00014 EMCYid(uint32_t val){
00015 *(uint32_t*) this = val;
00016 }
00017 can::Header header() {
00018 return can::Header(id, extended, false, false);
00019 }
00020 const uint32_t get() const { return *(uint32_t*) this; }
00021 };
00022
00023 struct EMCYfield{
00024 uint32_t error_code:16;
00025 uint32_t addition_info:16;
00026 EMCYfield(uint32_t val){
00027 *(uint32_t*) this = val;
00028 }
00029 };
00030
00031 struct EMCYmsg{
00032 uint16_t error_code;
00033 uint8_t error_register;
00034 uint8_t manufacturer_specific_error_field[5];
00035
00036 struct Frame: public FrameOverlay<EMCYmsg>{
00037 Frame(const can::Frame &f) : FrameOverlay(f){ }
00038 };
00039 };
00040
00041 #pragma pack(pop)
00042
00043 void EMCYHandler::handleEMCY(const can::Frame & msg){
00044 EMCYmsg::Frame em(msg);
00045 LOG("EMCY: " << can::tostring(msg, false));
00046 has_error_ = (em.data.error_register & ~32) != 0;
00047 }
00048
00049 EMCYHandler::EMCYHandler(const boost::shared_ptr<can::CommInterface> interface, const boost::shared_ptr<ObjectStorage> storage): Layer("EMCY handler"), storage_(storage), has_error_(true){
00050 storage_->entry(error_register_, 0x1001);
00051 try{
00052 storage_->entry(num_errors_, 0x1003,0);
00053 }
00054 catch(...){
00055
00056 }
00057 try{
00058 EMCYid emcy_id(storage_->entry<uint32_t>(0x1014).get_cached());
00059 emcy_listener_ = interface->createMsgListener( emcy_id.header(), can::CommInterface::FrameDelegate(this, &EMCYHandler::handleEMCY));
00060 }
00061 catch(...){
00062
00063 }
00064 }
00065
00066 void EMCYHandler::handleRead(LayerStatus &status, const LayerState ¤t_state) {
00067 if(current_state == Ready){
00068 if(has_error_){
00069 status.error("Node has emergency error");
00070 }
00071 }
00072 }
00073 void EMCYHandler::handleWrite(LayerStatus &status, const LayerState ¤t_state) {
00074
00075 }
00076
00077 void EMCYHandler::handleDiag(LayerReport &report){
00078 uint8_t error_register = 0;
00079 if(!error_register_.get(error_register)){
00080 report.error("Could not read error error_register");
00081 return;
00082 }
00083
00084 if(error_register){
00085 if(error_register & 1){
00086 report.error("Node has emergency error");
00087 }else if(error_register & ~32){
00088 report.warn("Error register is not zero");
00089 }
00090 report.add("error_register", (uint32_t) error_register);
00091
00092 uint8_t num = num_errors_.valid() ? num_errors_.get() : 0;
00093 std::stringstream buf;
00094 for(size_t i = 0; i < num; ++i) {
00095 if( i!= 0){
00096 buf << ", ";
00097 }
00098 try{
00099 ObjectStorage::Entry<uint32_t> error;
00100 storage_->entry(error, 0x1003,i+1);
00101 EMCYfield field(error.get());
00102 buf << std::hex << field.error_code << "#" << field.addition_info;
00103 }
00104 catch (const std::out_of_range & e){
00105 buf << "NOT_IN_DICT!";
00106 }
00107 catch (const TimeoutException & e){
00108 buf << "LIST_UNDERFLOW!";
00109 break;
00110 }
00111
00112 }
00113 report.add("errors", buf.str());
00114
00115 }
00116 }
00117 void EMCYHandler::handleInit(LayerStatus &status){
00118 uint8_t error_register = 0;
00119 if(!error_register_.get(error_register)){
00120 status.error("Could not read error error_register");
00121 return;
00122 }else if(error_register & 1){
00123 LOG("ER: " << int(error_register));
00124 status.error("Node has emergency error");
00125 return;
00126 }
00127
00128 resetErrors(status);
00129 }
00130 void EMCYHandler::resetErrors(LayerStatus &status){
00131 if(num_errors_.valid()) num_errors_.set(0);
00132 has_error_ = false;
00133 }
00134
00135 void EMCYHandler::handleRecover(LayerStatus &status){
00136 handleInit(status);
00137 }
00138 void EMCYHandler::handleShutdown(LayerStatus &status){
00139 }
00140 void EMCYHandler::handleHalt(LayerStatus &status){
00141
00142 }