Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
emcy.c
00001 /* 00002 This file is part of CanFestival, a library implementing CanOpen Stack. 00003 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN 00005 00006 See COPYING file for copyrights details. 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 USA 00022 */ 00023 00024 /*! 00025 ** @file emcy.c 00026 ** @author Luis Jimenez 00027 ** @date Wed Sep 26 2007 00028 ** 00029 ** @brief Definitions of the functions that manage EMCY (emergency) messages 00030 ** 00031 ** 00032 */ 00033 00034 #include <data.h> 00035 #include "emcy.h" 00036 #include "canfestival.h" 00037 #include "sysdep.h" 00038 00039 00040 00041 UNS32 OnNumberOfErrorsUpdate (CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex); 00042 UNS8 sendEMCY (CO_Data* d, UNS16 errCode, UNS8 errRegister); 00043 00044 00045 /*! This is called when Index 0x1003 is updated. 00046 ** 00047 ** 00048 ** @param d 00049 ** @param unsused_indextable 00050 ** @param unsused_bSubindex 00051 ** 00052 ** @return 00053 **/ 00054 UNS32 OnNumberOfErrorsUpdate (CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) 00055 { 00056 UNS8 index; 00057 // if 0, reset Pre-defined Error Field 00058 // else, don't change and give an abort message (eeror code: 0609 0030h) 00059 if (*d->error_number == 0) 00060 for (index = 0; index < d->error_history_size; ++index) 00061 *(d->error_first_element + index) = 0; /* clear all the fields in Pre-defined Error Field (1003h) */ 00062 else 00063 ;// abort message 00064 return 0; 00065 } 00066 00067 /*! start the EMCY mangagement. 00068 ** 00069 ** 00070 ** @param d 00071 **/ 00072 void emergencyInit(CO_Data* d) 00073 { 00074 RegisterSetODentryCallBack(d, 0x1003, 0x00, &OnNumberOfErrorsUpdate ); 00075 00076 *d->error_number = 0; 00077 } 00078 00079 /*! 00080 ** 00081 ** 00082 ** @param d 00083 **/ 00084 void emergencyStop(CO_Data* d) 00085 { 00086 00087 } 00088 00089 /*! 00090 ** 00091 ** 00092 ** @param d 00093 ** @param cob_id 00094 ** 00095 ** @return 00096 **/ 00097 UNS8 sendEMCY (CO_Data* d, UNS16 errCode, UNS8 errRegister) 00098 { 00099 Message m; 00100 00101 MSG_WAR(0x3051, "sendEMCY", 0); 00102 00103 m.cob_id = (UNS16)UNS16_LE(*(UNS32*)d->error_cobid); 00104 m.rtr = NOT_A_REQUEST; 00105 m.len = 8; 00106 m.data[0] = errCode & 0xFF; /* LSB */ 00107 m.data[1] = (errCode >> 8) & 0xFF; /* MSB */ 00108 m.data[2] = errRegister; 00109 m.data[3] = 0; /* Manufacturer specific Error Field still not implemented */ 00110 m.data[4] = 0; 00111 m.data[5] = 0; 00112 m.data[6] = 0; 00113 m.data[7] = 0; 00114 00115 return canSend(d->canHandle,&m); 00116 } 00117 00118 /*! Sets a new error with code errCode. Also sets corresponding bits in Error register (1001h) 00119 ** 00120 ** 00121 ** @param d 00122 ** @param errCode Code of the error 00123 ** @param errRegister Bits of Error register (1001h) to be set. 00124 ** @return 1 if error, 0 if successful 00125 */ 00126 UNS8 EMCY_setError(CO_Data* d, UNS16 errCode, UNS8 errRegMask, UNS16 addInfo) 00127 { 00128 UNS8 index; 00129 UNS8 errRegister_tmp; 00130 00131 for (index = 0; index < EMCY_MAX_ERRORS; ++index) 00132 { 00133 if (d->error_data[index].errCode == errCode) /* error already registered */ 00134 { 00135 if (d->error_data[index].active) 00136 { 00137 MSG_WAR(0x3052, "EMCY message already sent", 0); 00138 return 0; 00139 } else d->error_data[index].active = 1; /* set as active error */ 00140 break; 00141 } 00142 } 00143 00144 if (index == EMCY_MAX_ERRORS) /* if errCode not already registered */ 00145 for (index = 0; index < EMCY_MAX_ERRORS; ++index) if (d->error_data[index].active == 0) break; /* find first inactive error */ 00146 00147 if (index == EMCY_MAX_ERRORS) /* error_data full */ 00148 { 00149 MSG_ERR(0x3053, "error_data full", 0); 00150 return 1; 00151 } 00152 00153 d->error_data[index].errCode = errCode; 00154 d->error_data[index].errRegMask = errRegMask; 00155 d->error_data[index].active = 1; 00156 00157 /* set the new state in the error state machine */ 00158 d->error_state = Error_occurred; 00159 00160 /* set Error Register (1001h) */ 00161 for (index = 0, errRegister_tmp = 0; index < EMCY_MAX_ERRORS; ++index) 00162 if (d->error_data[index].active == 1) errRegister_tmp |= d->error_data[index].errRegMask; 00163 *d->error_register = errRegister_tmp; 00164 00165 /* set Pre-defined Error Field (1003h) */ 00166 for (index = d->error_history_size - 1; index > 0; --index) 00167 *(d->error_first_element + index) = *(d->error_first_element + index - 1); 00168 *(d->error_first_element) = errCode | ((UNS32)addInfo << 16); 00169 if(*d->error_number < d->error_history_size) ++(*d->error_number); 00170 00171 /* send EMCY message */ 00172 if (d->CurrentCommunicationState.csEmergency) 00173 return sendEMCY (d, errCode, *d->error_register); 00174 else return 1; 00175 } 00176 00177 /*! Deletes error errCode. Also clears corresponding bits in Error register (1001h) 00178 ** 00179 ** 00180 ** @param d 00181 ** @param errCode Code of the error 00182 ** @param errRegister Bits of Error register (1001h) to be set. 00183 ** @return 1 if error, 0 if successful 00184 */ 00185 void EMCY_errorRecovered(CO_Data* d, UNS16 errCode) 00186 { 00187 UNS8 index; 00188 UNS8 errRegister_tmp; 00189 UNS8 anyActiveError = 0; 00190 00191 for (index = 0; index < EMCY_MAX_ERRORS; ++index) 00192 if (d->error_data[index].errCode == errCode) break; /* find the position of the error */ 00193 00194 00195 if ((index != EMCY_MAX_ERRORS) && (d->error_data[index].active == 1)) 00196 { 00197 d->error_data[index].active = 0; 00198 00199 /* set Error Register (1001h) and check error state machine */ 00200 for (index = 0, errRegister_tmp = 0; index < EMCY_MAX_ERRORS; ++index) 00201 if (d->error_data[index].active == 1) 00202 { 00203 anyActiveError = 1; 00204 errRegister_tmp |= d->error_data[index].errRegMask; 00205 } 00206 if(anyActiveError == 0) 00207 { 00208 d->error_state = Error_free; 00209 /* send a EMCY message with code "Error Reset or No Error" */ 00210 if (d->CurrentCommunicationState.csEmergency) 00211 sendEMCY (d, 0x0000, 0x00); 00212 } 00213 *d->error_register = errRegister_tmp; 00214 } 00215 else 00216 MSG_WAR(0x3054, "recovered error was not active", 0); 00217 } 00218 00219 /*! This function is responsible to process an EMCY canopen-message. 00220 ** 00221 ** 00222 ** @param d 00223 ** @param m The CAN-message which has to be analysed. 00224 ** 00225 **/ 00226 void proceedEMCY(CO_Data* d, Message* m) 00227 { 00228 UNS8 nodeID; 00229 UNS16 errCode; 00230 UNS8 errReg; 00231 00232 MSG_WAR(0x3055, "EMCY received. Proceed. ", 0); 00233 00234 /* Test if the size of the EMCY is ok */ 00235 if ( m->len != 8) { 00236 MSG_ERR(0x1056, "Error size EMCY. CobId : ", m->cob_id); 00237 return; 00238 } 00239 00240 /* post the received EMCY */ 00241 nodeID = UNS16_LE(m->cob_id) & 0x7F; 00242 errCode = m->data[0] | ((UNS16)m->data[1] << 8); 00243 errReg = m->data[2]; 00244 (*d->post_emcy)(d, nodeID, errCode, errReg); 00245 } 00246 00247 void _post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg){}
Generated on Tue Jul 12 2022 17:24:12 by
1.7.2