1 /** 2 * CAN driver functions. 3 * 4 * Defines functions that must be implemented for each target. 5 * 6 * @file CO_driver.h 7 * @ingroup CO_driver 8 * @author Janez Paternoster 9 * @copyright 2004 - 2020 Janez Paternoster 10 * 11 * This file is part of CANopenNode, an opensource CANopen Stack. 12 * Project home page is <https://github.com/CANopenNode/CANopenNode>. 13 * For more information on CANopen see <http://www.can-cia.org/>. 14 * 15 * Licensed under the Apache License, Version 2.0 (the "License"); 16 * you may not use this file except in compliance with the License. 17 * You may obtain a copy of the License at 18 * 19 * http://www.apache.org/licenses/LICENSE-2.0 20 * 21 * Unless required by applicable law or agreed to in writing, software 22 * distributed under the License is distributed on an "AS IS" BASIS, 23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 * See the License for the specific language governing permissions and 25 * limitations under the License. 26 */ 27 28 #ifndef CO_DRIVER_H 29 #define CO_DRIVER_H 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif /* __cplusplus */ 34 35 #include "CO_driver_target.h" 36 #include "CO_types.h" 37 38 /* Include processor header file */ 39 #include <stdint.h> /* for 'int8_t' to 'uint64_t' */ 40 41 /** 42 * @defgroup CO_driver Driver 43 * @ingroup CO_CANopen 44 * @{ 45 * 46 * Microcontroller specific code for CANopenNode. 47 * 48 * This file contains type definitions, functions and macros for: 49 * - Basic data types. 50 * - Receive and transmit buffers for CANopen messages. 51 * - Interaction with CAN module on the microcontroller. 52 * - CAN receive and transmit interrupts. 53 * 54 * This file is not only a CAN driver. There are no classic CAN queues for CAN 55 * messages. This file provides direct connection with other CANopen 56 * objects. It tries to provide fast responses and tries to avoid unnecessary 57 * calculations and memory consumptions. 58 * 59 * CO_CANmodule_t contains an array of _Received message objects_ (of type 60 * CO_CANrx_t) and an array of _Transmit message objects_ (of type CO_CANtx_t). 61 * Each CANopen communication object owns one member in one of the arrays. 62 * For example Heartbeat producer generates one CANopen transmitting object, 63 * so it has reserved one member in CO_CANtx_t array. 64 * SYNC module may produce sync or consume sync, so it has reserved one member 65 * in CO_CANtx_t and one member in CO_CANrx_t array. 66 * 67 * ###Reception of CAN messages. 68 * Before CAN messages can be received, each member in CO_CANrx_t must be 69 * initialized. CO_CANrxBufferInit() is called by CANopen module, which 70 * uses specific member. For example @ref CO_HBconsumer uses multiple members 71 * in CO_CANrx_t array. (It monitors multiple heartbeat messages from remote 72 * nodes.) It must call CO_CANrxBufferInit() multiple times. 73 * 74 * Main arguments to the CO_CANrxBufferInit() function are CAN identifier 75 * and a pointer to callback function. Those two arguments (and some others) 76 * are copied to the member of the CO_CANrx_t array. 77 * 78 * Callback function is a function, specified by specific CANopen module 79 * (for example by @ref CO_HBconsumer). Each CANopen module defines own 80 * callback function. Callback function will process the received CAN message. 81 * It will copy the necessary data from CAN message to proper place. It may 82 * also trigger additional task, which will further process the received message. 83 * Callback function must be fast and must only make the necessary calculations 84 * and copying. 85 * 86 * Received CAN messages are processed by CAN receive interrupt function. 87 * After CAN message is received, function first tries to find matching CAN 88 * identifier from CO_CANrx_t array. If found, then a corresponding callback 89 * function is called. 90 * 91 * Callback function accepts two parameters: 92 * - object is pointer to object registered by CO_CANrxBufferInit(). 93 * - msg is pointer to CAN message of type CO_CANrxMsg_t. 94 * 95 * Callback function must return #CO_ReturnError_t: CO_ERROR_NO, 96 * CO_ERROR_RX_OVERFLOW, CO_ERROR_RX_PDO_OVERFLOW, CO_ERROR_RX_MSG_LENGTH or 97 * CO_ERROR_RX_PDO_LENGTH. 98 * 99 * 100 * ###Transmission of CAN messages. 101 * Before CAN messages can be transmitted, each member in CO_CANtx_t must be 102 * initialized. CO_CANtxBufferInit() is called by CANopen module, which 103 * uses specific member. For example Heartbeat producer must initialize it's 104 * member in CO_CANtx_t array. 105 * 106 * CO_CANtxBufferInit() returns a pointer of type CO_CANtx_t, which contains buffer 107 * where CAN message data can be written. CAN message is send with calling 108 * CO_CANsend() function. If at that moment CAN transmit buffer inside 109 * microcontroller's CAN module is free, message is copied directly to CAN module. 110 * Otherwise CO_CANsend() function sets _bufferFull_ flag to true. Message will be 111 * then sent by CAN TX interrupt as soon as CAN module is freed. Until message is 112 * not copied to CAN module, its contents must not change. There may be multiple 113 * _bufferFull_ flags in CO_CANtx_t array set to true. In that case messages with 114 * lower index inside array will be sent first. 115 */ 116 117 /** 118 * Request CAN configuration (stopped) mode and *wait* untill it is set. 119 * 120 * @param CANdriverState User-provided CAN module structure. 121 */ 122 void CO_CANsetConfigurationMode(void *CANdriverState); 123 124 125 /** 126 * Request CAN normal (opearational) mode and *wait* untill it is set. 127 * 128 * @param CANmodule This object. 129 */ 130 void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule); 131 132 133 /** 134 * Initialize CAN module object. 135 * 136 * Function must be called in the communication reset section. CAN module must 137 * be in Configuration Mode before. 138 * 139 * @param CANmodule This object will be initialized. 140 * @param CANdriverState User-provided CAN module structure.. 141 * @param rxArray Array for handling received CAN messages 142 * @param rxSize Size of the above array. Must be equal to number of receiving CAN objects. 143 * @param txArray Array for handling transmitting CAN messages 144 * @param txSize Size of the above array. Must be equal to number of transmitting CAN objects. 145 * @param CANbitRate Valid values are (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000. 146 * If value is illegal, bitrate defaults to 125. 147 * 148 * Return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. 149 */ 150 CO_ReturnError_t CO_CANmodule_init( 151 CO_CANmodule_t *CANmodule, 152 void *CANdriverState, 153 CO_CANrx_t rxArray[], 154 uint16_t rxSize, 155 CO_CANtx_t txArray[], 156 uint16_t txSize, 157 uint16_t CANbitRate); 158 159 160 /** 161 * Switch off CANmodule. Call at program exit. 162 * 163 * @param CANmodule CAN module object. 164 */ 165 void CO_CANmodule_disable(CO_CANmodule_t *CANmodule); 166 167 168 /** 169 * Read CAN identifier from received message 170 * 171 * @param rxMsg Pointer to received message 172 * @return 11-bit CAN standard identifier. 173 */ 174 uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg); 175 176 177 /** 178 * Configure CAN message receive buffer. 179 * 180 * Function configures specific CAN receive buffer. It sets CAN identifier 181 * and connects buffer with specific object. Function must be called for each 182 * member in _rxArray_ from CO_CANmodule_t. 183 * 184 * @param CANmodule This object. 185 * @param index Index of the specific buffer in _rxArray_. 186 * @param ident 11-bit standard CAN Identifier. 187 * @param mask 11-bit mask for identifier. Most usually set to 0x7FF. 188 * Received message (rcvMsg) will be accepted if the following 189 * condition is true: (((rcvMsgId ^ ident) & mask) == 0). 190 * @param rtr If true, 'Remote Transmit Request' messages will be accepted. 191 * @param object CANopen object, to which buffer is connected. It will be used as 192 * an argument to pFunct. Its type is (void), pFunct will change its 193 * type back to the correct object type. 194 * @param pFunct Pointer to function, which will be called, if received CAN 195 * message matches the identifier. It must be fast function. 196 * 197 * Return #CO_ReturnError_t: CO_ERROR_NO CO_ERROR_ILLEGAL_ARGUMENT or 198 * CO_ERROR_OUT_OF_MEMORY (not enough masks for configuration). 199 */ 200 CO_ReturnError_t CO_CANrxBufferInit( 201 CO_CANmodule_t *CANmodule, 202 uint16_t index, 203 uint16_t ident, 204 uint16_t mask, 205 bool_t rtr, 206 void *object, 207 void (*pFunct)(void *object, const CO_CANrxMsg_t *message)); 208 209 210 /** 211 * Configure CAN message transmit buffer. 212 * 213 * Function configures specific CAN transmit buffer. Function must be called for 214 * each member in _txArray_ from CO_CANmodule_t. 215 * 216 * @param CANmodule This object. 217 * @param index Index of the specific buffer in _txArray_. 218 * @param ident 11-bit standard CAN Identifier. 219 * @param rtr If true, 'Remote Transmit Request' messages will be transmitted. 220 * @param noOfBytes Length of CAN message in bytes (0 to 8 bytes). 221 * @param syncFlag This flag bit is used for synchronous TPDO messages. If it is set, 222 * message will not be sent, if curent time is outside synchronous window. 223 * 224 * @return Pointer to CAN transmit message buffer. 8 bytes data array inside 225 * buffer should be written, before CO_CANsend() function is called. 226 * Zero is returned in case of wrong arguments. 227 */ 228 CO_CANtx_t *CO_CANtxBufferInit( 229 CO_CANmodule_t *CANmodule, 230 uint16_t index, 231 uint16_t ident, 232 bool_t rtr, 233 uint8_t noOfBytes, 234 bool_t syncFlag); 235 236 237 /** 238 * Send CAN message. 239 * 240 * @param CANmodule This object. 241 * @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit(). 242 * Data bytes must be written in buffer before function call. 243 * 244 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_TX_OVERFLOW or 245 * CO_ERROR_TX_PDO_WINDOW (Synchronous TPDO is outside window). 246 */ 247 CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer); 248 249 250 /** 251 * Clear all synchronous TPDOs from CAN module transmit buffers. 252 * 253 * CANopen allows synchronous PDO communication only inside time between SYNC 254 * message and SYNC Window. If time is outside this window, new synchronous PDOs 255 * must not be sent and all pending sync TPDOs, which may be on CAN TX buffers, 256 * must be cleared. 257 * 258 * This function checks (and aborts transmission if necessary) CAN TX buffers 259 * when it is called. Function should be called by the stack in the moment, 260 * when SYNC time was just passed out of synchronous window. 261 * 262 * @param CANmodule This object. 263 */ 264 void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule); 265 266 267 /** 268 * Verify all errors of CAN module. 269 * 270 * Function is called directly from CO_EM_process() function. 271 * 272 * @param CANmodule This object. 273 */ 274 void CO_CANverifyErrors(CO_CANmodule_t *CANmodule); 275 276 #ifdef __cplusplus 277 } 278 #endif /* __cplusplus */ 279 280 /** @} */ 281 #endif /* CO_DRIVER_H */ 282