forked from CANopenNode/CANopenNode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCO_TIME.h
193 lines (178 loc) · 6.69 KB
/
CO_TIME.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* CANopen Time-stamp protocol.
*
* @file CO_TIME.h
* @ingroup CO_TIME
* @author Julien PEYREGNE
* @copyright 2019 - 2020 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CO_TIME_H
#define CO_TIME_H
#include "301/CO_driver.h"
#include "CO_OD.h"
/* default configuration, see CO_config.h */
#ifndef CO_CONFIG_TIME
#define CO_CONFIG_TIME (0)
#endif
#if ((CO_CONFIG_TIME) & CO_CONFIG_TIME_ENABLE) || defined CO_DOXYGEN
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup CO_TIME TIME
* @ingroup CO_CANopen_301
* @{
*
* CANopen Time-stamp protocol.
*
* For CAN identifier see #CO_Default_CAN_ID_t
*
* TIME message is used for time synchronization of the nodes on network. One node
* should be TIME producer, others can be TIME consumers. This is configured with
* COB_ID_TIME object 0x1012 :
*
* - bit 31 should be set for a consumer
* - bit 30 should be set for a producer
*
*
* ###TIME CONSUMER
*
* CO_TIME_init() configuration :
* - COB_ID_TIME : 0x80000100L -> TIME consumer with TIME_COB_ID = 0x100
* - TIMECyclePeriod :
* - 0 -> no EMCY will be transmitted in case of TIME timeout
* - X -> an EMCY will be transmitted in case of TIME timeout (X * 1.5) ms
*
* Latest time value is stored in \p CO->TIME->Time variable.
*
*
* ###TIME PRODUCER
*
* CO_TIME_init() configuration :
* - COB_ID_TIME : 0x40000100L -> TIME producer with TIME_COB_ID = 0x100
* - TIMECyclePeriod : Time transmit period in ms
*
* Write time value in \p CO->TIME->Time variable, this will be sent at TIMECyclePeriod.
*/
#define TIME_MSG_LENGTH 6U
/**
* TIME producer and consumer object.
*/
typedef struct{
CO_EM_t *em; /**< From CO_TIME_init() */
CO_NMT_internalState_t *operatingState; /**< From CO_TIME_init() */
/** True, if device is TIME consumer. Calculated from _COB ID TIME Message_
variable from Object dictionary (index 0x1012). */
bool_t isConsumer;
/** True, if device is TIME producer. Calculated from _COB ID TIME Message_
variable from Object dictionary (index 0x1012). */
bool_t isProducer;
uint16_t COB_ID; /**< From CO_TIME_init() */
/** TIME period time in [milliseconds]. Set to TIME period to enable
timeout detection */
uint32_t periodTime;
/** TIME period timeout time in [milliseconds].
(periodTimeoutTime = periodTime * 1,5) */
uint32_t periodTimeoutTime;
/** Variable indicates, if new TIME message received from CAN bus */
volatile void *CANrxNew;
/** Timer for the TIME message in [microseconds].
Set to zero after received or transmitted TIME message */
uint32_t timer;
/** Set to nonzero value, if TIME with wrong data length is received from CAN */
uint16_t receiveError;
#if ((CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
/** From CO_TIME_initCallbackPre() or NULL */
void (*pFunctSignalPre)(void *object);
/** From CO_TIME_initCallbackPre() or NULL */
void *functSignalObjectPre;
#endif
CO_CANmodule_t *CANdevRx; /**< From CO_TIME_init() */
uint16_t CANdevRxIdx; /**< From CO_TIME_init() */
CO_CANmodule_t *CANdevTx; /**< From CO_TIME_init() */
uint16_t CANdevTxIdx; /**< From CO_TIME_init() */
CO_CANtx_t *TXbuff; /**< CAN transmit buffer */
TIME_OF_DAY Time;
}CO_TIME_t;
/**
* Initialize TIME object.
*
* Function must be called in the communication reset section.
*
* @param TIME This object will be initialized.
* @param em Emergency object.
* @param SDO SDO server object.
* @param operatingState Pointer to variable indicating CANopen device NMT internal state.
* @param COB_ID_TIMEMessage Should be intialized with CO_CAN_ID_TIME_STAMP
* @param TIMECyclePeriod TIME period in ms (may also be used in consumer mode for timeout detection (1.5x period)).
* @param CANdevRx CAN device for TIME reception.
* @param CANdevRxIdx Index of receive buffer in the above CAN device.
* @param CANdevTx CAN device for TIME transmission.
* @param CANdevTxIdx Index of transmit buffer in the above CAN device.
*
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
CO_ReturnError_t CO_TIME_init(
CO_TIME_t *TIME,
CO_EM_t *em,
CO_SDO_t *SDO,
CO_NMT_internalState_t *operatingState,
uint32_t COB_ID_TIMEMessage,
uint32_t TIMECyclePeriod,
CO_CANmodule_t *CANdevRx,
uint16_t CANdevRxIdx,
CO_CANmodule_t *CANdevTx,
uint16_t CANdevTxIdx);
#if ((CO_CONFIG_TIME) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
/**
* Initialize TIME callback function.
*
* Function initializes optional callback function, which should immediately
* start processing of CO_TIME_process() function.
* Callback is called after TIME message is received from the CAN bus.
*
* @param TIME This object.
* @param object Pointer to object, which will be passed to pFunctSignalPre(). Can be NULL
* @param pFunctSignalPre Pointer to the callback function. Not called if NULL.
*/
void CO_TIME_initCallbackPre(
CO_TIME_t *TIME,
void *object,
void (*pFunctSignalPre)(void *object));
#endif
/**
* Process TIME communication.
*
* Function must be called cyclically.
*
* @param TIME This object.
* @param timeDifference_us Time difference from previous function call in [microseconds].
*
* @return 0: No special meaning.
* @return 1: New TIME message recently received (consumer) / transmited (producer).
*/
uint8_t CO_TIME_process(
CO_TIME_t *TIME,
uint32_t timeDifference_us);
/** @} */ /* CO_TIME */
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /* (CO_CONFIG_TIME) & CO_CONFIG_TIME_ENABLE */
#endif /* CO_TIME_H */