1 /** 2 * CANopen TIME object protocol. 3 * 4 * @file CO_TIME.c 5 * @ingroup CO_TIME 6 * @author Julien PEYREGNE 7 * @copyright 2019 - 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_TIME_H 28 #define CO_TIME_H 29 30 #include "CO_OD.h" 31 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 /** 38 * @defgroup CO_TIME TIME 39 * @ingroup CO_CANopen 40 * @{ 41 * 42 * CANopen TIME object protocol. 43 * 44 * For CAN identifier see #CO_Default_CAN_ID_t 45 * 46 * TIME message is used for time synchronization of the nodes on network. One node 47 * should be TIME producer, others can be TIME consumers. This is configured with 48 * COB_ID_TIME object 0x1012 : 49 * 50 * - bit 31 should be set for a consumer 51 * - bit 30 should be set for a producer 52 * 53 * 54 * ###TIME CONSUMER 55 * 56 * CO_TIME_init() configuration : 57 * - COB_ID_TIME : 0x80000100L -> TIME consumer with TIME_COB_ID = 0x100 58 * - TIMECyclePeriod : 59 * - 0 -> no EMCY will be transmitted in case of TIME timeout 60 * - X -> an EMCY will be transmitted in case of TIME timeout (X * 1.5) ms 61 * 62 * Latest time value is stored in \p CO->TIME->Time variable. 63 * 64 * 65 * ###TIME PRODUCER 66 * 67 * CO_TIME_init() configuration : 68 * - COB_ID_TIME : 0x40000100L -> TIME producer with TIME_COB_ID = 0x100 69 * - TIMECyclePeriod : Time transmit period in ms 70 * 71 * Write time value in \p CO->TIME->Time variable, this will be sent at TIMECyclePeriod. 72 */ 73 74 #define TIME_MSG_LENGTH 6U 75 76 /** 77 * TIME producer and consumer object. 78 */ 79 typedef struct{ 80 CO_EM_t *em; /**< From CO_TIME_init() */ 81 uint8_t *operatingState; /**< From CO_TIME_init() */ 82 /** True, if device is TIME consumer. Calculated from _COB ID TIME Message_ 83 variable from Object dictionary (index 0x1012). */ 84 bool_t isConsumer; 85 /** True, if device is TIME producer. Calculated from _COB ID TIME Message_ 86 variable from Object dictionary (index 0x1012). */ 87 bool_t isProducer; 88 uint16_t COB_ID; /**< From CO_TIME_init() */ 89 /** TIME period time in [milliseconds]. Set to TIME period to enable 90 timeout detection */ 91 uint32_t periodTime; 92 /** TIME period timeout time in [milliseconds]. 93 (periodTimeoutTime = periodTime * 1,5) */ 94 uint32_t periodTimeoutTime; 95 /** Variable indicates, if new TIME message received from CAN bus */ 96 volatile void *CANrxNew; 97 /** Timer for the TIME message in [microseconds]. 98 Set to zero after received or transmitted TIME message */ 99 uint32_t timer; 100 /** Set to nonzero value, if TIME with wrong data length is received from CAN */ 101 uint16_t receiveError; 102 CO_CANmodule_t *CANdevRx; /**< From CO_TIME_init() */ 103 uint16_t CANdevRxIdx; /**< From CO_TIME_init() */ 104 CO_CANmodule_t *CANdevTx; /**< From CO_TIME_init() */ 105 uint16_t CANdevTxIdx; /**< From CO_TIME_init() */ 106 CO_CANtx_t *TXbuff; /**< CAN transmit buffer */ 107 TIME_OF_DAY Time; 108 }CO_TIME_t; 109 110 /** 111 * Initialize TIME object. 112 * 113 * Function must be called in the communication reset section. 114 * 115 * @param TIME This object will be initialized. 116 * @param em Emergency object. 117 * @param SDO SDO server object. 118 * @param operatingState Pointer to variable indicating CANopen device NMT internal state. 119 * @param COB_ID_TIMEMessage Should be intialized with CO_CAN_ID_TIME_STAMP 120 * @param TIMECyclePeriod TIME period in ms (may also be used in consumer mode for timeout detection (1.5x period)). 121 * @param CANdevRx CAN device for TIME reception. 122 * @param CANdevRxIdx Index of receive 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_TIME_init( 127 CO_TIME_t *TIME, 128 CO_EM_t *em, 129 CO_SDO_t *SDO, 130 uint8_t *operatingState, 131 uint32_t COB_ID_TIMEMessage, 132 uint32_t TIMECyclePeriod, 133 CO_CANmodule_t *CANdevRx, 134 uint16_t CANdevRxIdx, 135 CO_CANmodule_t *CANdevTx, 136 uint16_t CANdevTxIdx); 137 138 /** 139 * Process TIME communication. 140 * 141 * Function must be called cyclically. 142 * 143 * @param TIME This object. 144 * @param timeDifference_ms Time difference from previous function call in [milliseconds]. 145 * 146 * @return 0: No special meaning. 147 * @return 1: New TIME message recently received (consumer) / transmited (producer). 148 */ 149 uint8_t CO_TIME_process( 150 CO_TIME_t *TIME, 151 uint32_t timeDifference_ms); 152 153 #ifdef __cplusplus 154 } 155 #endif /*__cplusplus*/ 156 157 /** @} */ 158 #endif 159