1 /** 2 * CANopen Emergency protocol. 3 * 4 * @file CO_Emergency.h 5 * @ingroup CO_Emergency 6 * @author Janez Paternoster 7 * @copyright 2004 - 2020 Janez Paternoster 8 * 9 * This file is part of CANopenNode, an opensource CANopen Stack. 10 * Project home page is <https://github.com/CANopenNode/CANopenNode>. 11 * For more information on CANopen see <http://www.can-cia.org/>. 12 * 13 * Licensed under the Apache License, Version 2.0 (the "License"); 14 * you may not use this file except in compliance with the License. 15 * You may obtain a copy of the License at 16 * 17 * http://www.apache.org/licenses/LICENSE-2.0 18 * 19 * Unless required by applicable law or agreed to in writing, software 20 * distributed under the License is distributed on an "AS IS" BASIS, 21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the License for the specific language governing permissions and 23 * limitations under the License. 24 */ 25 26 27 #ifndef CO_EMERGENCY_H 28 #define CO_EMERGENCY_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /** 35 * @defgroup CO_Emergency Emergency 36 * @ingroup CO_CANopen 37 * @{ 38 * 39 * CANopen Emergency protocol. 40 * 41 * Error control and Emergency is used for control internal error state 42 * and for sending a CANopen Emergency message. 43 * 44 * In case of error condition stack or application calls CO_errorReport() 45 * function with indication of the error. Specific error condition is reported 46 * (with CANopen Emergency message) only the first time after it occurs. 47 * Internal state of the error condition is controlled with 48 * @ref CO_EM_errorStatusBits. Specific error condition can also be reset by 49 * CO_errorReset() function. If so, Emergency message is sent with 50 * CO_EM_NO_ERROR indication. 51 * 52 * Some error conditions are informative and some are critical. Critical error 53 * conditions sets the #CO_errorRegisterBitmask_t. 54 * 55 * Latest errors can be read from _Pre Defined Error Field_ (object dictionary, 56 * index 0x1003). @ref CO_EM_errorStatusBits can also be read form CANopen 57 * object dictionary. 58 * 59 * ###Emergency message contents: 60 * 61 * Byte | Description 62 * -----|----------------------------------------------------------- 63 * 0..1 | @ref CO_EM_errorCodes. 64 * 2 | #CO_errorRegisterBitmask_t. 65 * 3 | Index of error condition (see @ref CO_EM_errorStatusBits). 66 * 4..7 | Additional argument informative to CO_errorReport() function. 67 * 68 * ####Contents of _Pre Defined Error Field_ (object dictionary, index 0x1003): 69 * bytes 0..3 are equal to bytes 0..3 in the Emergency message. 70 * 71 * @see #CO_Default_CAN_ID_t 72 */ 73 74 75 /** 76 * CANopen Error register. 77 * 78 * In object dictionary on index 0x1001. 79 * 80 * Error register is calculated from critical internal @ref CO_EM_errorStatusBits. 81 * Generic and communication bits are calculated in CO_EM_process 82 * function, device profile or manufacturer specific bits may be calculated 83 * inside the application. 84 * 85 * Internal errors may prevent device to stay in NMT Operational state. Details 86 * are described in _Error Behavior_ object in Object Dictionary at index 0x1029. 87 */ 88 typedef enum{ 89 CO_ERR_REG_GENERIC_ERR = 0x01U, /**< bit 0, generic error */ 90 CO_ERR_REG_CURRENT = 0x02U, /**< bit 1, current */ 91 CO_ERR_REG_VOLTAGE = 0x04U, /**< bit 2, voltage */ 92 CO_ERR_REG_TEMPERATURE = 0x08U, /**< bit 3, temperature */ 93 CO_ERR_REG_COMM_ERR = 0x10U, /**< bit 4, communication error (overrun, error state) */ 94 CO_ERR_REG_DEV_PROFILE = 0x20U, /**< bit 5, device profile specific */ 95 CO_ERR_REG_RESERVED = 0x40U, /**< bit 6, reserved (always 0) */ 96 CO_ERR_REG_MANUFACTURER = 0x80U /**< bit 7, manufacturer specific */ 97 }CO_errorRegisterBitmask_t; 98 99 100 /** 101 * @defgroup CO_EM_errorCodes CANopen Error codes 102 * @{ 103 * 104 * Standard error codes according to CiA DS-301 and DS-401. 105 */ 106 #define CO_EMC_NO_ERROR 0x0000U /**< 0x00xx, error Reset or No Error */ 107 #define CO_EMC_GENERIC 0x1000U /**< 0x10xx, Generic Error */ 108 #define CO_EMC_CURRENT 0x2000U /**< 0x20xx, Current */ 109 #define CO_EMC_CURRENT_INPUT 0x2100U /**< 0x21xx, Current, device input side */ 110 #define CO_EMC_CURRENT_INSIDE 0x2200U /**< 0x22xx, Current inside the device */ 111 #define CO_EMC_CURRENT_OUTPUT 0x2300U /**< 0x23xx, Current, device output side */ 112 #define CO_EMC_VOLTAGE 0x3000U /**< 0x30xx, Voltage */ 113 #define CO_EMC_VOLTAGE_MAINS 0x3100U /**< 0x31xx, Mains Voltage */ 114 #define CO_EMC_VOLTAGE_INSIDE 0x3200U /**< 0x32xx, Voltage inside the device */ 115 #define CO_EMC_VOLTAGE_OUTPUT 0x3300U /**< 0x33xx, Output Voltage */ 116 #define CO_EMC_TEMPERATURE 0x4000U /**< 0x40xx, Temperature */ 117 #define CO_EMC_TEMP_AMBIENT 0x4100U /**< 0x41xx, Ambient Temperature */ 118 #define CO_EMC_TEMP_DEVICE 0x4200U /**< 0x42xx, Device Temperature */ 119 #define CO_EMC_HARDWARE 0x5000U /**< 0x50xx, Device Hardware */ 120 #define CO_EMC_SOFTWARE_DEVICE 0x6000U /**< 0x60xx, Device Software */ 121 #define CO_EMC_SOFTWARE_INTERNAL 0x6100U /**< 0x61xx, Internal Software */ 122 #define CO_EMC_SOFTWARE_USER 0x6200U /**< 0x62xx, User Software */ 123 #define CO_EMC_DATA_SET 0x6300U /**< 0x63xx, Data Set */ 124 #define CO_EMC_ADDITIONAL_MODUL 0x7000U /**< 0x70xx, Additional Modules */ 125 #define CO_EMC_MONITORING 0x8000U /**< 0x80xx, Monitoring */ 126 #define CO_EMC_COMMUNICATION 0x8100U /**< 0x81xx, Communication */ 127 #define CO_EMC_CAN_OVERRUN 0x8110U /**< 0x8110, CAN Overrun (Objects lost) */ 128 #define CO_EMC_CAN_PASSIVE 0x8120U /**< 0x8120, CAN in Error Passive Mode */ 129 #define CO_EMC_HEARTBEAT 0x8130U /**< 0x8130, Life Guard Error or Heartbeat Error */ 130 #define CO_EMC_BUS_OFF_RECOVERED 0x8140U /**< 0x8140, recovered from bus off */ 131 #define CO_EMC_CAN_ID_COLLISION 0x8150U /**< 0x8150, CAN-ID collision */ 132 #define CO_EMC_PROTOCOL_ERROR 0x8200U /**< 0x82xx, Protocol Error */ 133 #define CO_EMC_PDO_LENGTH 0x8210U /**< 0x8210, PDO not processed due to length error */ 134 #define CO_EMC_PDO_LENGTH_EXC 0x8220U /**< 0x8220, PDO length exceeded */ 135 #define CO_EMC_DAM_MPDO 0x8230U /**< 0x8230, DAM MPDO not processed, destination object not available */ 136 #define CO_EMC_SYNC_DATA_LENGTH 0x8240U /**< 0x8240, Unexpected SYNC data length */ 137 #define CO_EMC_RPDO_TIMEOUT 0x8250U /**< 0x8250, RPDO timeout */ 138 #define CO_EMC_TIME_DATA_LENGTH 0x8260U /**< 0x8260, Unexpected TIME data length */ 139 #define CO_EMC_EXTERNAL_ERROR 0x9000U /**< 0x90xx, External Error */ 140 #define CO_EMC_ADDITIONAL_FUNC 0xF000U /**< 0xF0xx, Additional Functions */ 141 #define CO_EMC_DEVICE_SPECIFIC 0xFF00U /**< 0xFFxx, Device specific */ 142 143 #define CO_EMC401_OUT_CUR_HI 0x2310U /**< 0x2310, DS401, Current at outputs too high (overload) */ 144 #define CO_EMC401_OUT_SHORTED 0x2320U /**< 0x2320, DS401, Short circuit at outputs */ 145 #define CO_EMC401_OUT_LOAD_DUMP 0x2330U /**< 0x2330, DS401, Load dump at outputs */ 146 #define CO_EMC401_IN_VOLT_HI 0x3110U /**< 0x3110, DS401, Input voltage too high */ 147 #define CO_EMC401_IN_VOLT_LOW 0x3120U /**< 0x3120, DS401, Input voltage too low */ 148 #define CO_EMC401_INTERN_VOLT_HI 0x3210U /**< 0x3210, DS401, Internal voltage too high */ 149 #define CO_EMC401_INTERN_VOLT_LO 0x3220U /**< 0x3220, DS401, Internal voltage too low */ 150 #define CO_EMC401_OUT_VOLT_HIGH 0x3310U /**< 0x3310, DS401, Output voltage too high */ 151 #define CO_EMC401_OUT_VOLT_LOW 0x3320U /**< 0x3320, DS401, Output voltage too low */ 152 /** @} */ 153 154 155 /** 156 * @defgroup CO_EM_errorStatusBits Error status bits 157 * @{ 158 * 159 * Internal indication of the error condition. 160 * 161 * Each error condition is specified by unique index from 0x00 up to 0xFF. 162 * Variable (from manufacturer section in the Object 163 * Dictionary) contains up to 0xFF bits (32bytes) for the identification of the 164 * specific error condition. (Type of the variable is CANopen OCTET_STRING.) 165 * 166 * If specific error occurs in the stack or in the application, CO_errorReport() 167 * sets specific bit in the _Error Status Bits_ variable. If bit was already 168 * set, function returns without any action. Otherwise it prepares emergency 169 * message. 170 * 171 * CO_errorReport(), CO_errorReset() or CO_isError() functions are called 172 * with unique index as an argument. (However CO_errorReport(), for example, may 173 * be used with the same index on multiple places in the code.) 174 * 175 * Macros defined below are combination of two constants: index and 176 * @ref CO_EM_errorCodes. They represents specific error conditions. They are 177 * used as double argument for CO_errorReport(), CO_errorReset() and 178 * CO_isError() functions. 179 * 180 * Stack uses first 6 bytes of the _Error Status Bits_ variable. Device profile 181 * or application may define own macros for Error status bits using 182 * @ref CO_EM_MANUFACTURER_START and @ref CO_EM_MANUFACTURER_END values. Note that 183 * _Error Status Bits_ must be large enough (up to 32 bytes). 184 */ 185 #define CO_EM_NO_ERROR 0x00U /**< 0x00, Error Reset or No Error */ 186 #define CO_EM_CAN_BUS_WARNING 0x01U /**< 0x01, communication, info, CAN bus warning limit reached */ 187 #define CO_EM_RXMSG_WRONG_LENGTH 0x02U /**< 0x02, communication, info, Wrong data length of the received CAN message */ 188 #define CO_EM_RXMSG_OVERFLOW 0x03U /**< 0x03, communication, info, Previous received CAN message wasn't processed yet */ 189 #define CO_EM_RPDO_WRONG_LENGTH 0x04U /**< 0x04, communication, info, Wrong data length of received PDO */ 190 #define CO_EM_RPDO_OVERFLOW 0x05U /**< 0x05, communication, info, Previous received PDO wasn't processed yet */ 191 #define CO_EM_CAN_RX_BUS_PASSIVE 0x06U /**< 0x06, communication, info, CAN receive bus is passive */ 192 #define CO_EM_CAN_TX_BUS_PASSIVE 0x07U /**< 0x07, communication, info, CAN transmit bus is passive */ 193 #define CO_EM_NMT_WRONG_COMMAND 0x08U /**< 0x08, communication, info, Wrong NMT command received */ 194 #define CO_EM_TIME_TIMEOUT 0x09U /**< 0x09, communication, info, TIME message timeout */ 195 #define CO_EM_TIME_LENGTH 0x0AU /**< 0x0A, communication, info, Unexpected TIME data length */ 196 #define CO_EM_0B_unused 0x0BU /**< 0x0B, (unused) */ 197 #define CO_EM_0C_unused 0x0CU /**< 0x0C, (unused) */ 198 #define CO_EM_0D_unused 0x0DU /**< 0x0D, (unused) */ 199 #define CO_EM_0E_unused 0x0EU /**< 0x0E, (unused) */ 200 #define CO_EM_0F_unused 0x0FU /**< 0x0F, (unused) */ 201 202 #define CO_EM_10_unused 0x10U /**< 0x10, (unused) */ 203 #define CO_EM_11_unused 0x11U /**< 0x11, (unused) */ 204 #define CO_EM_CAN_TX_BUS_OFF 0x12U /**< 0x12, communication, critical, CAN transmit bus is off */ 205 #define CO_EM_CAN_RXB_OVERFLOW 0x13U /**< 0x13, communication, critical, CAN module receive buffer has overflowed */ 206 #define CO_EM_CAN_TX_OVERFLOW 0x14U /**< 0x14, communication, critical, CAN transmit buffer has overflowed */ 207 #define CO_EM_TPDO_OUTSIDE_WINDOW 0x15U /**< 0x15, communication, critical, TPDO is outside SYNC window */ 208 #define CO_EM_16_unused 0x16U /**< 0x16, (unused) */ 209 #define CO_EM_17_unused 0x17U /**< 0x17, (unused) */ 210 #define CO_EM_SYNC_TIME_OUT 0x18U /**< 0x18, communication, critical, SYNC message timeout */ 211 #define CO_EM_SYNC_LENGTH 0x19U /**< 0x19, communication, critical, Unexpected SYNC data length */ 212 #define CO_EM_PDO_WRONG_MAPPING 0x1AU /**< 0x1A, communication, critical, Error with PDO mapping */ 213 #define CO_EM_HEARTBEAT_CONSUMER 0x1BU /**< 0x1B, communication, critical, Heartbeat consumer timeout */ 214 #define CO_EM_HB_CONSUMER_REMOTE_RESET 0x1CU /**< 0x1C, communication, critical, Heartbeat consumer detected remote node reset */ 215 #define CO_EM_1D_unused 0x1DU /**< 0x1D, (unused) */ 216 #define CO_EM_1E_unused 0x1EU /**< 0x1E, (unused) */ 217 #define CO_EM_1F_unused 0x1FU /**< 0x1F, (unused) */ 218 219 #define CO_EM_EMERGENCY_BUFFER_FULL 0x20U /**< 0x20, generic, info, Emergency buffer is full, Emergency message wasn't sent */ 220 #define CO_EM_21_unused 0x21U /**< 0x21, (unused) */ 221 #define CO_EM_MICROCONTROLLER_RESET 0x22U /**< 0x22, generic, info, Microcontroller has just started */ 222 #define CO_EM_23_unused 0x23U /**< 0x23, (unused) */ 223 #define CO_EM_24_unused 0x24U /**< 0x24, (unused) */ 224 #define CO_EM_25_unused 0x25U /**< 0x25, (unused) */ 225 #define CO_EM_26_unused 0x26U /**< 0x26, (unused) */ 226 #define CO_EM_27_unused 0x27U /**< 0x27, (unused) */ 227 228 #define CO_EM_WRONG_ERROR_REPORT 0x28U /**< 0x28, generic, critical, Wrong parameters to CO_errorReport() function */ 229 #define CO_EM_ISR_TIMER_OVERFLOW 0x29U /**< 0x29, generic, critical, Timer task has overflowed */ 230 #define CO_EM_MEMORY_ALLOCATION_ERROR 0x2AU /**< 0x2A, generic, critical, Unable to allocate memory for objects */ 231 #define CO_EM_GENERIC_ERROR 0x2BU /**< 0x2B, generic, critical, Generic error, test usage */ 232 #define CO_EM_GENERIC_SOFTWARE_ERROR 0x2CU /**< 0x2C, generic, critical, Software error */ 233 #define CO_EM_INCONSISTENT_OBJECT_DICT 0x2DU /**< 0x2D, generic, critical, Object dictionary does not match the software */ 234 #define CO_EM_CALCULATION_OF_PARAMETERS 0x2EU /**< 0x2E, generic, critical, Error in calculation of device parameters */ 235 #define CO_EM_NON_VOLATILE_MEMORY 0x2FU /**< 0x2F, generic, critical, Error with access to non volatile device memory */ 236 237 #define CO_EM_MANUFACTURER_START 0x30U /**< 0x30, manufacturer, info, This can be used by macros to calculate error codes */ 238 #define CO_EM_MANUFACTURER_END 0xFFU /**< 0xFF, manufacturer, info, This can be used by macros to check error codes */ 239 /** @} */ 240 241 242 /** 243 * Size of internal buffer, whwre emergencies are stored after CO_errorReport(). 244 * Buffer is cleared by CO_EM_process(). 245 */ 246 #define CO_EM_INTERNAL_BUFFER_SIZE 10 247 248 249 /** 250 * Emergerncy object for CO_errorReport(). It contains error buffer, to which new emergency 251 * messages are written, when CO_errorReport() is called. This object is included in 252 * CO_EMpr_t object. 253 */ 254 typedef struct{ 255 uint8_t *errorStatusBits; /**< From CO_EM_init() */ 256 uint8_t errorStatusBitsSize; /**< From CO_EM_init() */ 257 258 /** Internal buffer for storing unsent emergency messages.*/ 259 uint8_t buf[CO_EM_INTERNAL_BUFFER_SIZE * 8]; 260 uint8_t *bufEnd; /**< End+1 address of the above buffer */ 261 uint8_t *bufWritePtr; /**< Write pointer in the above buffer */ 262 uint8_t *bufReadPtr; /**< Read pointer in the above buffer */ 263 uint8_t bufFull; /**< True if above buffer is full */ 264 uint8_t wrongErrorReport; /**< Error in arguments to CO_errorReport() */ 265 266 /** From CO_EM_initCallback() or NULL */ 267 void (*pFunctSignal)(void); 268 /** From CO_EM_initCallbackRx() or NULL */ 269 void (*pFunctSignalRx)(const uint16_t ident, 270 const uint16_t errorCode, 271 const uint8_t errorRegister, 272 const uint8_t errorBit, 273 const uint32_t infoCode); 274 }CO_EM_t; 275 276 277 /** 278 * Report error condition. 279 * 280 * Function is called on any error condition inside CANopen stack and may also 281 * be called by application on custom error condition. Emergency message is sent 282 * after the first occurance of specific error. In case of critical error, device 283 * will not be able to stay in NMT_OPERATIONAL state. 284 * 285 * Function is short and may be used form any task or interrupt. 286 * 287 * @param em Emergency object. 288 * @param errorBit from @ref CO_EM_errorStatusBits. 289 * @param errorCode from @ref CO_EM_errorCodes. 290 * @param infoCode 32 bit value is passed to bytes 4...7 of the Emergency message. 291 * It contains optional additional information inside emergency message. 292 */ 293 void CO_errorReport(CO_EM_t *em, const uint8_t errorBit, const uint16_t errorCode, const uint32_t infoCode); 294 295 296 /** 297 * Reset error condition. 298 * 299 * Function is called if any error condition is solved. Emergency message is sent 300 * with @ref CO_EM_errorCodes 0x0000. 301 * 302 * Function is short and may be used form any task or interrupt. 303 * 304 * @param em Emergency object. 305 * @param errorBit from @ref CO_EM_errorStatusBits. 306 * @param infoCode 32 bit value is passed to bytes 4...7 of the Emergency message. 307 */ 308 void CO_errorReset(CO_EM_t *em, const uint8_t errorBit, const uint32_t infoCode); 309 310 311 /** 312 * Check specific error condition. 313 * 314 * Function returns 1, if specific internal error is present. Otherwise it returns 0. 315 * 316 * @param em Emergency object. 317 * @param errorBit from @ref CO_EM_errorStatusBits. 318 * 319 * @return false: Error is not present. 320 * @return true: Error is present. 321 */ 322 bool_t CO_isError(CO_EM_t *em, const uint8_t errorBit); 323 324 325 #ifdef CO_DOXYGEN 326 /** Skip section, if CO_SDO.h is not included */ 327 #define CO_SDO_H 328 #endif 329 #ifdef CO_SDO_H 330 331 332 /** 333 * Error control and Emergency object. It controls internal error state and 334 * sends emergency message, if error condition was reported. Object is initialized 335 * by CO_EM_init(). It contains CO_EM_t object. 336 */ 337 typedef struct{ 338 uint8_t *errorRegister; /**< From CO_EM_init() */ 339 uint32_t *preDefErr; /**< From CO_EM_init() */ 340 uint8_t preDefErrSize; /**< From CO_EM_init() */ 341 uint8_t preDefErrNoOfErrors;/**< Number of active errors in preDefErr */ 342 uint16_t inhibitEmTimer; /**< Internal timer for emergency message */ 343 CO_EM_t *em; /**< CO_EM_t sub object is included here */ 344 CO_CANmodule_t *CANdev; /**< From CO_EM_init() */ 345 CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer */ 346 }CO_EMpr_t; 347 348 349 /** 350 * Initialize Error control and Emergency object. 351 * 352 * Function must be called in the communication reset section. 353 * 354 * @param emPr This object will be initialized. 355 * @param em Emergency object defined separately. Will be included in emPr and 356 * initialized too. 357 * @param SDO SDO server object. 358 * @param errorStatusBits Pointer to _Error Status Bits_ array from Object Dictionary 359 * (manufacturer specific section). See @ref CO_EM_errorStatusBits. 360 * @param errorStatusBitsSize Total size of the above array. Must be >= 6. 361 * @param errorRegister Pointer to _Error Register_ (Object dictionary, index 0x1001). 362 * @param preDefErr Pointer to _Pre defined error field_ array from Object 363 * dictionary, index 0x1003. 364 * @param preDefErrSize Size of the above array. 365 * @param CANdevRx CAN device for Emergency reception. 366 * @param CANdevRxIdx Index of receive buffer in the above CAN device. 367 * @param CANdevTx CAN device for Emergency transmission. 368 * @param CANdevTxIdx Index of transmit buffer in the above CAN device. 369 * @param CANidTxEM CAN identifier for Emergency message. 370 * 371 * @return #CO_ReturnError_t CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. 372 */ 373 CO_ReturnError_t CO_EM_init( 374 CO_EM_t *em, 375 CO_EMpr_t *emPr, 376 CO_SDO_t *SDO, 377 uint8_t *errorStatusBits, 378 uint8_t errorStatusBitsSize, 379 uint8_t *errorRegister, 380 uint32_t *preDefErr, 381 uint8_t preDefErrSize, 382 CO_CANmodule_t *CANdevRx, 383 uint16_t CANdevRxIdx, 384 CO_CANmodule_t *CANdevTx, 385 uint16_t CANdevTxIdx, 386 uint16_t CANidTxEM); 387 388 389 /** 390 * Initialize Emergency callback function. 391 * 392 * Function initializes optional callback function, which executes after 393 * error condition is changed. Function may wake up external task, 394 * which processes mainline CANopen functions. 395 * 396 * @param em This object. 397 * @param pFunctSignal Pointer to the callback function. Not called if NULL. 398 */ 399 void CO_EM_initCallback( 400 CO_EM_t *em, 401 void (*pFunctSignal)(void)); 402 403 404 /** 405 * Initialize Emergency received callback function. 406 * 407 * Function initializes optional callback function, which executes after 408 * error condition is received. Function may wake up external task, 409 * which processes mainline CANopen functions. 410 * 411 * @remark Depending on the CAN driver implementation, this function is called 412 * inside an ISR 413 * 414 * @param em This object. 415 * @param pFunctSignal Pointer to the callback function. Not called if NULL. 416 */ 417 void CO_EM_initCallbackRx( 418 CO_EM_t *em, 419 void (*pFunctSignalRx)(const uint16_t ident, 420 const uint16_t errorCode, 421 const uint8_t errorRegister, 422 const uint8_t errorBit, 423 const uint32_t infoCode)); 424 425 426 /** 427 * Process Error control and Emergency object. 428 * 429 * Function must be called cyclically. It verifies some communication errors, 430 * calculates bit 0 and bit 4 from _Error register_ and sends emergency message 431 * if necessary. 432 * 433 * @param emPr This object. 434 * @param NMTisPreOrOperational True if this node is NMT_PRE_OPERATIONAL or NMT_OPERATIONAL. 435 * @param timeDifference_100us Time difference from previous function call in [100 * microseconds]. 436 * @param emInhTime _Inhibit time EMCY_ (object dictionary, index 0x1015). 437 * @param timerNext_ms Return value - info to OS - see CO_process(). 438 */ 439 void CO_EM_process( 440 CO_EMpr_t *emPr, 441 bool_t NMTisPreOrOperational, 442 uint16_t timeDifference_100us, 443 uint16_t emInhTime, 444 uint16_t *timerNext_ms); 445 446 447 #endif 448 449 #ifdef __cplusplus 450 } 451 #endif /*__cplusplus*/ 452 453 /** @} */ 454 #endif 455