1 /** 2 * CANopen SYNC object protocol. 3 * 4 * @file CO_SYNC.h 5 * @ingroup CO_SYNC 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_SYNC_H 28 #define CO_SYNC_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /** 35 * @defgroup CO_SYNC SYNC 36 * @ingroup CO_CANopen 37 * @{ 38 * 39 * CANopen SYNC object protocol. 40 * 41 * For CAN identifier see #CO_Default_CAN_ID_t 42 * 43 * SYNC message is used for synchronization of the nodes on network. One node 44 * can be SYNC producer, others can be SYNC consumers. Synchronous TPDOs are 45 * transmitted after the CANopen SYNC message. Synchronous received PDOs are 46 * accepted(copied to OD) immediatelly after the reception of the next SYNC 47 * message. 48 * 49 * ####Contents of SYNC message 50 * By default SYNC message has no data. If _Synchronous counter overflow value_ 51 * from Object dictionary (index 0x1019) is different than 0, SYNC message has 52 * one data byte: _counter_ incremented by 1 with every SYNC transmission. 53 * 54 * ####SYNC in CANopenNode 55 * According to CANopen, synchronous RPDOs must be processed after reception of 56 * the next sync messsage. For that reason, there is a double receive buffer 57 * for each synchronous RPDO. At the moment, when SYNC is received or 58 * transmitted, internal variable CANrxToggle toggles. That variable is then 59 * used by synchronous RPDO to determine, which of the two buffers is used for 60 * RPDO reception and which for RPDO processing. 61 */ 62 63 64 /** 65 * SYNC producer and consumer object. 66 */ 67 typedef struct{ 68 CO_EM_t *em; /**< From CO_SYNC_init() */ 69 uint8_t *operatingState; /**< From CO_SYNC_init() */ 70 /** True, if device is SYNC producer. Calculated from _COB ID SYNC Message_ 71 variable from Object dictionary (index 0x1005). */ 72 bool_t isProducer; 73 /** COB_ID of SYNC message. Calculated from _COB ID SYNC Message_ 74 variable from Object dictionary (index 0x1005). */ 75 uint16_t COB_ID; 76 /** Sync period time in [microseconds]. Calculated from _Communication cycle period_ 77 variable from Object dictionary (index 0x1006). */ 78 uint32_t periodTime; 79 /** Sync period timeout time in [microseconds]. 80 (periodTimeoutTime = periodTime * 1,5) */ 81 uint32_t periodTimeoutTime; 82 /** Value from _Synchronous counter overflow value_ variable from Object 83 dictionary (index 0x1019) */ 84 uint8_t counterOverflowValue; 85 /** True, if current time is inside synchronous window. 86 In this case synchronous PDO may be sent. */ 87 bool_t curentSyncTimeIsInsideWindow; 88 /** Indicates, if new SYNC message received from CAN bus */ 89 volatile void *CANrxNew; 90 /** Variable toggles, if new SYNC message received from CAN bus */ 91 bool_t CANrxToggle; 92 /** Counter of the SYNC message if counterOverflowValue is different than zero */ 93 uint8_t counter; 94 /** Timer for the SYNC message in [microseconds]. 95 Set to zero after received or transmitted SYNC message */ 96 uint32_t timer; 97 /** Set to nonzero value, if SYNC with wrong data length is received from CAN */ 98 uint16_t receiveError; 99 CO_CANmodule_t *CANdevRx; /**< From CO_SYNC_init() */ 100 uint16_t CANdevRxIdx; /**< From CO_SYNC_init() */ 101 CO_CANmodule_t *CANdevTx; /**< From CO_SYNC_init() */ 102 CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer inside CANdevTx */ 103 uint16_t CANdevTxIdx; /**< From CO_SYNC_init() */ 104 }CO_SYNC_t; 105 106 107 /** 108 * Initialize SYNC object. 109 * 110 * Function must be called in the communication reset section. 111 * 112 * @param SYNC This object will be initialized. 113 * @param em Emergency object. 114 * @param SDO SDO server object. 115 * @param operatingState Pointer to variable indicating CANopen device NMT internal state. 116 * @param COB_ID_SYNCMessage From Object dictionary (index 0x1005). 117 * @param communicationCyclePeriod From Object dictionary (index 0x1006). 118 * @param synchronousCounterOverflowValue From Object dictionary (index 0x1019). 119 * @param CANdevRx CAN device for SYNC reception. 120 * @param CANdevRxIdx Index of receive buffer in the above CAN device. 121 * @param CANdevTx CAN device for SYNC transmission. 122 * @param CANdevTxIdx Index of transmit buffer in the above CAN device. 123 * 124 * @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT. 125 */ 126 CO_ReturnError_t CO_SYNC_init( 127 CO_SYNC_t *SYNC, 128 CO_EM_t *em, 129 CO_SDO_t *SDO, 130 uint8_t *operatingState, 131 uint32_t COB_ID_SYNCMessage, 132 uint32_t communicationCyclePeriod, 133 uint8_t synchronousCounterOverflowValue, 134 CO_CANmodule_t *CANdevRx, 135 uint16_t CANdevRxIdx, 136 CO_CANmodule_t *CANdevTx, 137 uint16_t CANdevTxIdx); 138 139 140 /** 141 * Process SYNC communication. 142 * 143 * Function must be called cyclically. 144 * 145 * @param SYNC This object. 146 * @param timeDifference_us Time difference from previous function call in [microseconds]. 147 * @param ObjDict_synchronousWindowLength _Synchronous window length_ variable from 148 * Object dictionary (index 0x1007). 149 * 150 * @return 0: No special meaning. 151 * @return 1: New SYNC message recently received or was just transmitted. 152 * @return 2: SYNC time was just passed out of window. 153 */ 154 uint8_t CO_SYNC_process( 155 CO_SYNC_t *SYNC, 156 uint32_t timeDifference_us, 157 uint32_t ObjDict_synchronousWindowLength); 158 159 #ifdef __cplusplus 160 } 161 #endif /*__cplusplus*/ 162 163 /** @} */ 164 #endif 165