| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- /**
- * CANopen Service Data Object - client protocol.
- *
- * @file CO_SDOclient.h
- * @ingroup CO_SDOclient
- * @author Janez Paternoster
- * @author Matej Severkar
- * @copyright 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_SDO_CLIENT_H
- #define CO_SDO_CLIENT_H
- #include "301/CO_driver.h"
- #include "301/CO_SDOserver.h"
- #include "301/CO_fifo.h"
- /* default configuration, see CO_config.h */
- #ifndef CO_CONFIG_SDO_CLI
- #define CO_CONFIG_SDO_CLI (0)
- #endif
- #ifndef CO_CONFIG_SDO_CLI_BUFFER_SIZE
- #if (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_BLOCK
- #define CO_CONFIG_SDO_CLI_BUFFER_SIZE 1000
- #else
- #define CO_CONFIG_SDO_CLI_BUFFER_SIZE 32
- #endif
- #endif
- #if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE) || defined CO_DOXYGEN
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * @defgroup CO_SDOclient SDO client
- * @ingroup CO_CANopen_301
- * @{
- *
- * CANopen Service Data Object - client protocol (master functionality).
- *
- * @see @ref CO_SDOserver
- */
- /**
- * SDO Client Parameter. The same as record from Object dictionary
- * (index 0x1280+).
- */
- typedef struct {
- /** Equal to 3 */
- uint8_t maxSubIndex;
- /** Communication object identifier for client transmission.
- * Meaning of the specific bits:
- - Bit 0...10: 11-bit CAN identifier.
- - Bit 11..30: reserved, set to 0.
- - Bit 31: if 1, SDO client object is not used. */
- uint32_t COB_IDClientToServer;
- /** Communication object identifier for message received from server.
- * Meaning of the specific bits:
- - Bit 0...10: 11-bit CAN identifier.
- - Bit 11..30: reserved, set to 0.
- - Bit 31: if 1, SDO client object is not used. */
- uint32_t COB_IDServerToClient;
- /** Node-ID of the SDO server */
- uint8_t nodeIDOfTheSDOServer;
- } CO_SDOclientPar_t;
- /**
- * SDO client object
- */
- typedef struct {
- #if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_LOCAL) || defined CO_DOXYGEN
- /** From CO_SDOclient_init() */
- CO_SDO_t *SDO;
- #endif
- /** From CO_SDOclient_init() */
- CO_SDOclientPar_t *SDOClientPar;
- /** From CO_SDOclient_init() */
- CO_CANmodule_t *CANdevRx;
- /** From CO_SDOclient_init() */
- uint16_t CANdevRxIdx;
- /** From CO_SDOclient_init() */
- CO_CANmodule_t *CANdevTx;
- /** From CO_SDOclient_init() */
- uint16_t CANdevTxIdx;
- /** CAN transmit buffer inside CANdevTx for CAN tx message */
- CO_CANtx_t *CANtxBuff;
- /** Index of current object in Object Dictionary */
- uint16_t index;
- /** Subindex of current object in Object Dictionary */
- uint8_t subIndex;
- /* If true, then data transfer is finished */
- bool_t finished;
- /** Size of data, which will be transferred. It is optionally indicated by
- * client in case of download or by server in case of upload. */
- size_t sizeInd;
- /** Size of data which is actually transferred. */
- size_t sizeTran;
- /** Internal state of the SDO client */
- volatile CO_SDO_state_t state;
- /** Maximum timeout time between request and response in microseconds */
- uint32_t SDOtimeoutTime_us;
- /** Timeout timer for SDO communication */
- uint32_t timeoutTimer;
- /** CO_fifo_t object for data buffer (not pointer) */
- CO_fifo_t bufFifo;
- /** Data buffer of usable size @ref CO_CONFIG_SDO_CLI_BUFFER_SIZE, used
- * inside bufFifo. Must be one byte larger for fifo usage. */
- char buf[CO_CONFIG_SDO_CLI_BUFFER_SIZE + 1];
- /** Indicates, if new SDO message received from CAN bus. It is not cleared,
- * until received message is completely processed. */
- volatile void *CANrxNew;
- /** 8 data bytes of the received message */
- uint8_t CANrxData[8];
- /** Previous value of the COB_IDClientToServer */
- uint32_t COB_IDClientToServerPrev;
- /** Previous value of the COB_IDServerToClient */
- uint32_t COB_IDServerToClientPrev;
- #if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
- /** From CO_SDOclient_initCallbackPre() or NULL */
- void (*pFunctSignal)(void *object);
- /** From CO_SDOclient_initCallbackPre() or NULL */
- void *functSignalObject;
- #endif
- #if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_SEGMENTED) || defined CO_DOXYGEN
- /** Toggle bit toggled in each segment in segmented transfer */
- uint8_t toggle;
- #endif
- #if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_BLOCK) || defined CO_DOXYGEN
- /** Timeout time for SDO sub-block upload, half of #SDOtimeoutTime_us */
- uint32_t block_SDOtimeoutTime_us;
- /** Timeout timer for SDO sub-block upload */
- uint32_t block_timeoutTimer;
- /** Sequence number of segment in block, 1..127 */
- uint8_t block_seqno;
- /** Number of segments per block, 1..127 */
- uint8_t block_blksize;
- /** Number of bytes in last segment that do not contain data */
- uint8_t block_noData;
- /** Server CRC support in block transfer */
- bool_t block_crcEnabled;
- /** Last 7 bytes of data at block upload */
- uint8_t block_dataUploadLast[7];
- /** Calculated CRC checksum */
- uint16_t block_crc;
- #endif
- } CO_SDOclient_t;
- /**
- * Initialize SDO client object.
- *
- * Function must be called in the communication reset section.
- *
- * @param SDO_C This object will be initialized.
- * @param SDO SDO server object. It is used in case, if client is accessing
- * object dictionary from its own device. If NULL, it will be ignored.
- * @param SDOClientPar Pointer to _SDO Client Parameter_ record from Object
- * dictionary (index 0x1280+). Will be written.
- * @param CANdevRx CAN device for SDO client reception.
- * @param CANdevRxIdx Index of receive buffer in the above CAN device.
- * @param CANdevTx CAN device for SDO client 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_SDOclient_init(CO_SDOclient_t *SDO_C,
- void *SDO,
- CO_SDOclientPar_t *SDOClientPar,
- CO_CANmodule_t *CANdevRx,
- uint16_t CANdevRxIdx,
- CO_CANmodule_t *CANdevTx,
- uint16_t CANdevTxIdx);
- #if ((CO_CONFIG_SDO_CLI) & CO_CONFIG_FLAG_CALLBACK_PRE) || defined CO_DOXYGEN
- /**
- * Initialize SDOclient callback function.
- *
- * Function initializes optional callback function, which should immediately
- * start processing of CO_SDOclientDownload() or CO_SDOclientUpload() function.
- * Callback is called after SDOclient message is received from the CAN bus or
- * when new call without delay is necessary (exchange data with own SDO server
- * or SDO block transfer is in progress).
- *
- * @param SDOclient This object.
- * @param object Pointer to object, which will be passed to pFunctSignal(). Can
- * be NULL.
- * @param pFunctSignal Pointer to the callback function. Not called if NULL.
- */
- void CO_SDOclient_initCallbackPre(CO_SDOclient_t *SDOclient,
- void *object,
- void (*pFunctSignal)(void *object));
- #endif
- /**
- * Setup SDO client object.
- *
- * Function must be called before new SDO communication. If previous SDO
- * communication was with the same node, function does not need to be called.
- *
- * @remark If configuring SDO client from network is required, this function
- * should be set as callback for the corresponding SDO client parameter OD
- * entry.
- *
- * @param SDO_C This object.
- * @param COB_IDClientToServer See CO_SDOclientPar_t. If zero, then
- * nodeIDOfTheSDOServer is used with default COB-ID.
- * @param COB_IDServerToClient See CO_SDOclientPar_t. If zero, then
- * nodeIDOfTheSDOServer is used with default COB-ID.
- * @param nodeIDOfTheSDOServer Node-ID of the SDO server. If zero, SDO client
- * object is not used. If it is the same as node-ID of this node, then data will
- * be exchanged with this node (without CAN communication).
- *
- * @return #CO_SDO_return_t
- */
- CO_SDO_return_t CO_SDOclient_setup(CO_SDOclient_t *SDO_C,
- uint32_t COB_IDClientToServer,
- uint32_t COB_IDServerToClient,
- uint8_t nodeIDOfTheSDOServer);
- /**
- * Initiate SDO download communication.
- *
- * Function initiates SDO download communication with server specified in
- * CO_SDOclient_init() function. Data will be written to remote node.
- * Function is non-blocking.
- *
- * @param SDO_C This object.
- * @param index Index of object in object dictionary in remote node.
- * @param subIndex Subindex of object in object dictionary in remote node.
- * @param sizeIndicated Optionally indicate size of data to be downloaded.
- * Actual data are written with one or multiple CO_SDOclientDownloadBufWrite()
- * calls.
- * - If sizeIndicated is different than 0, then total number of data
- * written by CO_SDOclientDownloadBufWrite() will be compared against
- * sizeIndicated. Also sizeIndicated info will be passed to the server, which
- * will compare actual data size downloaded. In case of mismatch, SDO abort
- * message will be generated.
- * - If sizeIndicated is 0, then actual data size will not be verified.
- * @param SDOtimeoutTime_ms Timeout time for SDO communication in milliseconds.
- * @param blockEnable Try to initiate block transfer.
- *
- * @return #CO_SDO_return_t
- */
- CO_SDO_return_t CO_SDOclientDownloadInitiate(CO_SDOclient_t *SDO_C,
- uint16_t index,
- uint8_t subIndex,
- size_t sizeIndicated,
- uint16_t SDOtimeoutTime_ms,
- bool_t blockEnable);
- /**
- * Initiate SDO download communication - update size.
- *
- * This is optional function, which updates sizeIndicated, if it was not known
- * in the CO_SDOclientDownloadInitiate() function call. This function can be
- * used after CO_SDOclientDownloadBufWrite(), but must be used before
- * CO_SDOclientDownload().
- *
- * @param SDO_C This object.
- * @param sizeIndicated Same as in CO_SDOclientDownloadInitiate().
- */
- void CO_SDOclientDownloadInitiateSize(CO_SDOclient_t *SDO_C,
- size_t sizeIndicated);
- /**
- * Write data into SDO client buffer
- *
- * This function copies data from buf into internal SDO client fifo buffer.
- * Function returns number of bytes successfully copied. If there is not enough
- * space in destination, not all bytes will be copied. Additional data can be
- * copied in next cycles. If there is enough space in destination and
- * sizeIndicated is different than zero, then all data must be written at once.
- *
- * This function is basically a wrapper for CO_fifo_write() function. As
- * alternative, other functions from CO_fifo can be used directly, for example
- * CO_fifo_cpyTok2U8() or similar.
- *
- * @param SDO_C This object.
- * @param buf Buffer which will be copied
- * @param count Number of bytes in buf
- *
- * @return number of bytes actually written.
- */
- size_t CO_SDOclientDownloadBufWrite(CO_SDOclient_t *SDO_C,
- const char *buf,
- size_t count);
- /**
- * Process SDO download communication.
- *
- * Function must be called cyclically until it returns <=0. It Proceeds SDO
- * download communication initiated with CO_SDOclientDownloadInitiate().
- * Function is non-blocking.
- *
- * If function returns #CO_SDO_RT_blockDownldInProgress and OS has buffer for
- * CAN tx messages, then this function may be called multiple times within own
- * loop. This can speed-up SDO block transfer.
- *
- * @param SDO_C This object.
- * @param timeDifference_us Time difference from previous function call in
- * [microseconds].
- * @param abort If true, SDO client will send abort message from SDOabortCode
- * and transmission will be aborted.
- * @param bufferPartial True indicates, not all data were copied to internal
- * buffer yet. Buffer will be refilled later with #CO_SDOclientDownloadBufWrite.
- * @param [out] SDOabortCode In case of error in communication, SDO abort code
- * contains reason of error. Ignored if NULL.
- * @param [out] sizeTransferred Actual size of data transferred. Ignored if NULL
- * @param [out] timerNext_us info to OS - see CO_process(). Ignored if NULL.
- *
- * @return #CO_SDO_return_t. If less than 0, then error occurred,
- * SDOabortCode contains reason and state becomes idle. If 0, communication
- * ends successfully and state becomes idle. If greater than 0, then
- * communication is in progress.
- */
- CO_SDO_return_t CO_SDOclientDownload(CO_SDOclient_t *SDO_C,
- uint32_t timeDifference_us,
- bool_t abort,
- bool_t bufferPartial,
- CO_SDO_abortCode_t *SDOabortCode,
- size_t *sizeTransferred,
- uint32_t *timerNext_us);
- /**
- * Initiate SDO upload communication.
- *
- * Function initiates SDO upload communication with server specified in
- * CO_SDOclient_init() function. Data will be read from remote node.
- * Function is non-blocking.
- *
- * @param SDO_C This object.
- * @param index Index of object in object dictionary in remote node.
- * @param subIndex Subindex of object in object dictionary in remote node.
- * @param SDOtimeoutTime_ms Timeout time for SDO communication in milliseconds.
- * @param blockEnable Try to initiate block transfer.
- *
- * @return #CO_SDO_return_t
- */
- CO_SDO_return_t CO_SDOclientUploadInitiate(CO_SDOclient_t *SDO_C,
- uint16_t index,
- uint8_t subIndex,
- uint16_t SDOtimeoutTime_ms,
- bool_t blockEnable);
- /**
- * Process SDO upload communication.
- *
- * Function must be called cyclically until it returns <=0. It Proceeds SDO
- * upload communication initiated with CO_SDOclientUploadInitiate().
- * Function is non-blocking.
- *
- * If this function returns #CO_SDO_RT_uploadDataBufferFull, then data must be
- * read from fifo buffer to make it empty. This function can then be called
- * once again immediately to speed-up block transfer. Note also, that remaining
- * data must be read after function returns #CO_SDO_RT_ok_communicationEnd.
- * Data must not be read, if function returns #CO_SDO_RT_blockUploadInProgress.
- *
- * @param SDO_C This object.
- * @param timeDifference_us Time difference from previous function call in
- * [microseconds].
- * @param abort If true, SDO client will send abort message from SDOabortCode
- * and reception will be aborted.
- * @param [out] SDOabortCode In case of error in communication, SDO abort code
- * contains reason of error. Ignored if NULL.
- * @param [out] sizeIndicated If larger than 0, then SDO server has indicated
- * size of data transfer. Ignored if NULL.
- * @param [out] sizeTransferred Actual size of data transferred. Ignored if NULL
- * @param [out] timerNext_us info to OS - see CO_process(). Ignored if NULL.
- *
- * @return #CO_SDO_return_t. If less than 0, then error occurred,
- * SDOabortCode contains reason and state becomes idle. If 0, communication
- * ends successfully and state becomes idle. If greater than 0, then
- * communication is in progress.
- */
- CO_SDO_return_t CO_SDOclientUpload(CO_SDOclient_t *SDO_C,
- uint32_t timeDifference_us,
- bool_t abort,
- CO_SDO_abortCode_t *SDOabortCode,
- size_t *sizeIndicated,
- size_t *sizeTransferred,
- uint32_t *timerNext_us);
- /**
- * Read data from SDO client buffer.
- *
- * This function copies data from internal fifo buffer of SDO client into buf.
- * Function returns number of bytes successfully copied. It can be called in
- * multiple cycles, if data length is large.
- *
- * This function is basically a wrapper for CO_fifo_read() function. As
- * alternative, other functions from CO_fifo can be used directly, for example
- * CO_fifo_readU82a() or similar.
- *
- * @warning This function (or similar) must NOT be called when
- * CO_SDOclientUpload() returns #CO_SDO_RT_blockUploadInProgress!
- *
- * @param SDO_C This object.
- * @param buf Buffer into which data will be copied
- * @param count Copy up to count bytes into buffer
- *
- * @return number of bytes actually read.
- */
- size_t CO_SDOclientUploadBufRead(CO_SDOclient_t *SDO_C,
- char *buf,
- size_t count);
- /**
- * Close SDO communication temporary.
- *
- * Function must be called after finish of each SDO client communication cycle.
- * It disables reception of SDO client CAN messages. It is necessary, because
- * CO_SDOclient_receive function may otherwise write into undefined SDO buffer.
- *
- * @param SDO_C This object.
- */
- void CO_SDOclientClose(CO_SDOclient_t *SDO_C);
- /** @} */ /* CO_SDOclient */
- #ifdef __cplusplus
- }
- #endif /*__cplusplus*/
- #endif /* (CO_CONFIG_SDO_CLI) & CO_CONFIG_SDO_CLI_ENABLE */
- #endif /* CO_SDO_CLIENT_H */
|