1 /** 2 * Main CANopen stack file. 3 * 4 * It combines Object dictionary (CO_OD) and all other CANopen source files. 5 * Configuration information are read from CO_OD.h file. This file uses one 6 * CAN module. If multiple CAN modules are to be used, then this file may be 7 * customized for different CANopen configuration. (One or multiple CANopen 8 * device on one or multiple CAN modules.) 9 * 10 * @file CANopen.h 11 * @ingroup CO_CANopen 12 * @author Janez Paternoster 13 * @author Uwe Kindler 14 * @copyright 2010 - 2020 Janez Paternoster 15 * 16 * This file is part of CANopenNode, an opensource CANopen Stack. 17 * Project home page is <https://github.com/CANopenNode/CANopenNode>. 18 * For more information on CANopen see <http://www.can-cia.org/>. 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33 34 #ifndef CANopen_H 35 #define CANopen_H 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** 42 * @defgroup CO_CANopen CANopen stack 43 * @{ 44 * 45 * CANopenNode is free and open source CANopen Stack. 46 * 47 * CANopen is the internationally standardized (EN 50325-4) (CiA DS-301) 48 * CAN-based higher-layer protocol for embedded control system. For more 49 * information on CANopen see http://www.can-cia.org/ 50 * 51 * CANopenNode homepage is https://github.com/CANopenNode/CANopenNode 52 * 53 * Licensed under the Apache License, Version 2.0 (the "License"); 54 * you may not use this file except in compliance with the License. 55 * You may obtain a copy of the License at 56 * 57 * http://www.apache.org/licenses/LICENSE-2.0 58 * 59 * Unless required by applicable law or agreed to in writing, software 60 * distributed under the License is distributed on an "AS IS" BASIS, 61 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 62 * See the License for the specific language governing permissions and 63 * limitations under the License. 64 */ 65 66 67 #include "CO_driver.h" 68 #include "CO_OD.h" 69 #include "CO_SDO.h" 70 #include "CO_Emergency.h" 71 #include "CO_NMT_Heartbeat.h" 72 #include "CO_SYNC.h" 73 #include "CO_TIME.h" 74 #include "CO_PDO.h" 75 #include "CO_HBconsumer.h" 76 #if CO_NO_SDO_CLIENT != 0 77 #include "CO_SDOmaster.h" 78 #endif 79 #if CO_NO_TRACE > 0 80 #include "CO_trace.h" 81 #endif 82 #if CO_NO_LSS_SERVER == 1 83 #include "CO_LSSslave.h" 84 #endif 85 #if CO_NO_LSS_CLIENT == 1 86 #include "CO_LSSmaster.h" 87 #endif 88 89 /** 90 * Default CANopen identifiers. 91 * 92 * Default CANopen identifiers for CANopen communication objects. Same as 93 * 11-bit addresses of CAN messages. These are default identifiers and 94 * can be changed in CANopen. Especially PDO identifiers are confgured 95 * in PDO linking phase of the CANopen network configuration. 96 */ 97 typedef enum{ 98 CO_CAN_ID_NMT_SERVICE = 0x000, /**< 0x000, Network management */ 99 CO_CAN_ID_SYNC = 0x080, /**< 0x080, Synchronous message */ 100 CO_CAN_ID_EMERGENCY = 0x080, /**< 0x080, Emergency messages (+nodeID) */ 101 CO_CAN_ID_TIME = 0x100, /**< 0x100, Time message */ 102 CO_CAN_ID_TPDO_1 = 0x180, /**< 0x180, Default TPDO1 (+nodeID) */ 103 CO_CAN_ID_RPDO_1 = 0x200, /**< 0x200, Default RPDO1 (+nodeID) */ 104 CO_CAN_ID_TPDO_2 = 0x280, /**< 0x280, Default TPDO2 (+nodeID) */ 105 CO_CAN_ID_RPDO_2 = 0x300, /**< 0x300, Default RPDO2 (+nodeID) */ 106 CO_CAN_ID_TPDO_3 = 0x380, /**< 0x380, Default TPDO3 (+nodeID) */ 107 CO_CAN_ID_RPDO_3 = 0x400, /**< 0x400, Default RPDO3 (+nodeID) */ 108 CO_CAN_ID_TPDO_4 = 0x480, /**< 0x480, Default TPDO4 (+nodeID) */ 109 CO_CAN_ID_RPDO_4 = 0x500, /**< 0x500, Default RPDO5 (+nodeID) */ 110 CO_CAN_ID_TSDO = 0x580, /**< 0x580, SDO response from server (+nodeID) */ 111 CO_CAN_ID_RSDO = 0x600, /**< 0x600, SDO request from client (+nodeID) */ 112 CO_CAN_ID_HEARTBEAT = 0x700, /**< 0x700, Heartbeat message */ 113 CO_CAN_ID_LSS_CLI = 0x7E4, /**< 0x7E4, LSS response from server to client */ 114 CO_CAN_ID_LSS_SRV = 0x7E5 /**< 0x7E5, LSS request from client to server */ 115 }CO_Default_CAN_ID_t; 116 117 118 /** 119 * CANopen stack object combines pointers to all CANopen objects. 120 */ 121 typedef struct{ 122 CO_CANmodule_t *CANmodule[1]; /**< CAN module objects */ 123 CO_SDO_t *SDO[CO_NO_SDO_SERVER]; /**< SDO object */ 124 CO_EM_t *em; /**< Emergency report object */ 125 CO_EMpr_t *emPr; /**< Emergency process object */ 126 CO_NMT_t *NMT; /**< NMT object */ 127 CO_SYNC_t *SYNC; /**< SYNC object */ 128 CO_TIME_t *TIME; /**< TIME object */ 129 CO_RPDO_t *RPDO[CO_NO_RPDO];/**< RPDO objects */ 130 CO_TPDO_t *TPDO[CO_NO_TPDO];/**< TPDO objects */ 131 CO_HBconsumer_t *HBcons; /**< Heartbeat consumer object*/ 132 #if CO_NO_LSS_SERVER == 1 133 CO_LSSslave_t *LSSslave; /**< LSS server/slave object */ 134 #endif 135 #if CO_NO_LSS_CLIENT == 1 136 CO_LSSmaster_t *LSSmaster; /**< LSS master/client object */ 137 #endif 138 #if CO_NO_SDO_CLIENT != 0 139 CO_SDOclient_t *SDOclient[CO_NO_SDO_CLIENT]; /**< SDO client object */ 140 #endif 141 #if CO_NO_TRACE > 0 142 CO_trace_t *trace[CO_NO_TRACE]; /**< Trace object for monitoring variables */ 143 #endif 144 }CO_t; 145 146 147 /** CANopen object */ 148 extern CO_t *CO; 149 150 151 /** 152 * Function CO_sendNMTcommand() is simple function, which sends CANopen message. 153 * This part of code is an example of custom definition of simple CANopen 154 * object. Follow the code in CANopen.c file. If macro CO_NO_NMT_MASTER is 1, 155 * function CO_sendNMTcommand can be used to send NMT master message. 156 * 157 * @param co CANopen object. 158 * @param command NMT command. 159 * @param nodeID Node ID. 160 * 161 * @return 0: Operation completed successfully. 162 * @return other: same as CO_CANsend(). 163 */ 164 #if CO_NO_NMT_MASTER == 1 165 CO_ReturnError_t CO_sendNMTcommand(CO_t *co, uint8_t command, uint8_t nodeID); 166 #endif 167 168 169 #if CO_NO_LSS_SERVER == 1 170 /** 171 * Allocate and initialize memory for CANopen object 172 * 173 * Function must be called in the communication reset section. 174 * 175 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT, 176 * CO_ERROR_OUT_OF_MEMORY 177 */ 178 CO_ReturnError_t CO_new(void); 179 180 181 /** 182 * Initialize CAN driver 183 * 184 * Function must be called in the communication reset section. 185 * 186 * @param CANdriverState Pointer to the CAN module, passed to CO_CANmodule_init(). 187 * @param bitRate CAN bit rate. 188 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT, 189 * CO_ERROR_ILLEGAL_BAUDRATE, CO_ERROR_OUT_OF_MEMORY 190 */ 191 CO_ReturnError_t CO_CANinit( 192 void *CANdriverState, 193 uint16_t bitRate); 194 195 196 /** 197 * Initialize CANopen LSS slave 198 * 199 * Function must be called in the communication reset section. 200 * 201 * @param nodeId Node ID of the CANopen device (1 ... 127) or CO_LSS_NODE_ID_ASSIGNMENT 202 * @param bitRate CAN bit rate. 203 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT 204 */ 205 CO_ReturnError_t CO_LSSinit( 206 uint8_t nodeId, 207 uint16_t bitRate); 208 209 210 /** 211 * Initialize CANopen stack. 212 * 213 * Function must be called in the communication reset section. 214 * 215 * @param nodeId Node ID of the CANopen device (1 ... 127). 216 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT 217 */ 218 CO_ReturnError_t CO_CANopenInit( 219 uint8_t nodeId); 220 221 222 #else /* CO_NO_LSS_SERVER == 1 */ 223 /** 224 * Initialize CANopen stack. 225 * 226 * Function must be called in the communication reset section. 227 * 228 * @param CANdriverState Pointer to the user-defined CAN base structure, passed to CO_CANmodule_init(). 229 * @param nodeId Node ID of the CANopen device (1 ... 127). 230 * @param bitRate CAN bit rate. 231 * 232 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT, 233 * CO_ERROR_OUT_OF_MEMORY, CO_ERROR_ILLEGAL_BAUDRATE 234 */ 235 CO_ReturnError_t CO_init( 236 void *CANdriverState, 237 uint8_t nodeId, 238 uint16_t bitRate); 239 240 #endif /* CO_NO_LSS_SERVER == 1 */ 241 242 243 /** 244 * Delete CANopen object and free memory. Must be called at program exit. 245 * 246 * @param CANdriverState Pointer to the user-defined CAN base structure, passed to CO_CANmodule_init(). 247 */ 248 void CO_delete(void *CANdriverState); 249 250 251 /** 252 * Process CANopen objects. 253 * 254 * Function must be called cyclically. It processes all "asynchronous" CANopen 255 * objects. 256 * 257 * @param co CANopen object. 258 * @param timeDifference_ms Time difference from previous function call in [milliseconds]. 259 * @param timerNext_ms Return value - info to OS - maximum delay after function 260 * should be called next time in [milliseconds]. Value can be used for OS 261 * sleep time. Initial value must be set to something, 50ms typically. 262 * Output will be equal or lower to initial value. If there is new object 263 * to process, delay should be suspended and this function should be 264 * called immediately. Parameter is ignored if NULL. 265 * 266 * @return #CO_NMT_reset_cmd_t from CO_NMT_process(). 267 */ 268 CO_NMT_reset_cmd_t CO_process( 269 CO_t *co, 270 uint16_t timeDifference_ms, 271 uint16_t *timerNext_ms); 272 273 274 #if CO_NO_SYNC == 1 275 /** 276 * Process CANopen SYNC objects. 277 * 278 * Function must be called cyclically from real time thread with constant 279 * interval (1ms typically). It processes SYNC CANopen objects. 280 * 281 * @param co CANopen object. 282 * @param timeDifference_us Time difference from previous function call in [microseconds]. 283 * 284 * @return True, if CANopen SYNC message was just received or transmitted. 285 */ 286 bool_t CO_process_SYNC( 287 CO_t *co, 288 uint32_t timeDifference_us); 289 #endif 290 291 /** 292 * Process CANopen RPDO objects. 293 * 294 * Function must be called cyclically from real time thread with constant. 295 * interval (1ms typically). It processes receive PDO CANopen objects. 296 * 297 * @param co CANopen object. 298 * @param syncWas True, if CANopen SYNC message was just received or transmitted. 299 */ 300 void CO_process_RPDO( 301 CO_t *co, 302 bool_t syncWas); 303 304 /** 305 * Process CANopen TPDO objects. 306 * 307 * Function must be called cyclically from real time thread with constant. 308 * interval (1ms typically). It processes transmit PDO CANopen objects. 309 * 310 * @param co CANopen object. 311 * @param syncWas True, if CANopen SYNC message was just received or transmitted. 312 * @param timeDifference_us Time difference from previous function call in [microseconds]. 313 */ 314 void CO_process_TPDO( 315 CO_t *co, 316 bool_t syncWas, 317 uint32_t timeDifference_us); 318 319 #ifdef __cplusplus 320 } 321 #endif /*__cplusplus*/ 322 323 /** @} */ 324 #endif 325