| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /**
- * 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"
- /* 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
- #ifndef timeOfDay_t
- typedef union {
- unsigned long long ullValue;
- struct {
- unsigned long ms:28;
- unsigned reserved:4;
- unsigned days:16;
- unsigned reserved2:16;
- };
- } timeOfDay_t;
- #endif
- typedef timeOfDay_t TIME_OF_DAY;
- typedef timeOfDay_t TIME_DIFFERENCE;
- /**
- * 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 */
|