1
0
Fork 0
CANopenNode/stack/CO_SDOmaster.h
2015-07-25 14:03:15 +02:00

328 lines
12 KiB
C

/**
* CANopen Service Data Object - client protocol.
*
* @file CO_SDOmaster.h
* @ingroup CO_SDOmaster
* @version SVN: \$Id$
* @author Janez Paternoster
* @author Matej Severkar
* @copyright 2004 - 2013 Janez Paternoster
*
* This file is part of CANopenNode, an opensource CANopen Stack.
* Project home page is <http://canopennode.sourceforge.net>.
* For more information on CANopen see <http://www.can-cia.org/>.
*
* CANopenNode is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CO_SDO_CLIENT_H
#define CO_SDO_CLIENT_H
/**
* @defgroup CO_SDOmaster SDO client
* @ingroup CO_CANopen
* @{
*
* CANopen Service Data Object - client protocol.
*
* @see @ref CO_SDO
*/
/**
* Return values of SDO client functions.
*/
typedef enum{
/** Transmit buffer is full. Waiting */
CO_SDOcli_transmittBufferFull = 4,
/** Block download is in progress. Sending train of messages */
CO_SDOcli_blockDownldInProgress = 3,
/** Block upload in progress. Receiving train of messages */
CO_SDOcli_blockUploadInProgress = 2,
/** Waiting server response */
CO_SDOcli_waitingServerResponse = 1,
/** Success, end of communication */
CO_SDOcli_ok_communicationEnd = 0,
/** Error in arguments */
CO_SDOcli_wrongArguments = -2,
/** Communication ended with client abort */
CO_SDOcli_endedWithClientAbort = -9,
/** Communication ended with server abort */
CO_SDOcli_endedWithServerAbort = -10,
/** Communication ended with timeout */
CO_SDOcli_endedWithTimeout = -11
}CO_SDOclient_return_t;
/**
* 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{
/** From CO_SDOclient_init() */
CO_SDOclientPar_t *SDOClientPar;
/** From CO_SDOclient_init() */
CO_SDO_t *SDO;
/** Internal state of the SDO client */
uint8_t state;
/** Pointer to data buffer supplied by user */
uint8_t *buffer;
/** By download application indicates data size in buffer.
By upload application indicates buffer size */
uint32_t bufferSize;
/** Offset in buffer of next data segment being read/written */
uint32_t bufferOffset;
/** Acknowledgement */
uint32_t bufferOffsetACK;
/** data length to be uploaded in block transfer */
uint32_t dataSize;
/** Data length transferred in block transfer */
uint32_t dataSizeTransfered;
/** Timeout timer for SDO communication */
uint16_t timeoutTimer;
/** Timeout timer for SDO block transfer */
uint16_t timeoutTimerBLOCK;
/** Index of current object in Object Dictionary */
uint16_t index;
/** Subindex of current object in Object Dictionary */
uint8_t subIndex;
/** From CO_SDOclient_init() */
CO_CANmodule_t *CANdevRx;
/** From CO_SDOclient_init() */
uint16_t CANdevRxIdx;
/** Flag indicates, if new SDO message received from CAN bus.
It is not cleared, until received message is completely processed. */
uint16_t CANrxNew; /* must be 2-byte variable because of correct alignment of CANrxData */
/** 8 data bytes of the received message */
uint8_t CANrxData[8]; /* take care for correct (word) alignment! */
/** Pointer to optional external function. If defined, it is called from high
priority interrupt after new CAN SDO response message is received. Function
may wake up external task, which processes SDO client functions */
void (*pFunctSignal)(uint32_t arg);
/** Optional argument, which is passed to above function */
uint32_t functArg;
/** From CO_SDOclient_init() */
CO_CANmodule_t *CANdevTx;
/** CAN transmit buffer inside CANdevTx for CAN tx message */
CO_CANtx_t *CANtxBuff;
/** From CO_SDOclient_init() */
uint16_t CANdevTxIdx;
/** Toggle bit toggled with each subsequent in segmented transfer */
uint8_t toggle;
/** Server threshold for switch back to segmented transfer, if data size is small.
Set in CO_SDOclient_init(). Can be changed by application. 0 Disables switching. */
uint8_t pst;
/** Maximum number of segments in one block. Set in CO_SDOclient_init(). Can
be changed by application to 2 .. 127. */
uint8_t block_size_max;
/** Last sector number */
uint8_t block_seqno;
/** Block size in current transfer */
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 */
uint8_t crcEnabled;
}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.
*/
int16_t CO_SDOclient_init(
CO_SDOclient_t *SDO_C,
CO_SDO_t *SDO,
CO_SDOclientPar_t *SDOClientPar,
CO_CANmodule_t *CANdevRx,
uint16_t CANdevRxIdx,
CO_CANmodule_t *CANdevTx,
uint16_t CANdevTxIdx);
/**
* 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.
*
* @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_SDOclient_return_t
*/
CO_SDOclient_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 dataTx Pointer to data to be written. Data must be valid until end
* of communication. Note that data are aligned in little-endian
* format, because CANopen itself uses little-endian. Take care,
* when using processors with big-endian.
* @param dataSize Size of data in dataTx.
* @param blockEnable Try to initiate block transfer.
*
* @return #CO_SDOclient_return_t
*/
CO_SDOclient_return_t CO_SDOclientDownloadInitiate(
CO_SDOclient_t *SDO_C,
uint16_t index,
uint8_t subIndex,
uint8_t *dataTx,
uint32_t dataSize,
uint8_t blockEnable);
/**
* 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.
*
* @param SDO_C This object.
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
* @param SDOtimeoutTime Timeout time for SDO communication in milliseconds.
* @param pSDOabortCode Pointer to external variable written by this function
* in case of error in communication.
*
* @return #CO_SDOclient_return_t
*/
CO_SDOclient_return_t CO_SDOclientDownload(
CO_SDOclient_t *SDO_C,
uint16_t timeDifference_ms,
uint16_t SDOtimeoutTime,
uint32_t *pSDOabortCode);
/**
* 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 dataRx Pointer to data buffer data will be written. Buffer must be
* valid until end of communication. Note that data are aligned
* in little-endian format, because CANopen itself uses
* little-endian. Take care, when using processors with big-endian.
* @param dataRxSize Size of dataRx.
* @param blockEnable Try to initiate block transfer.
*
* @return #CO_SDOclient_return_t
*/
CO_SDOclient_return_t CO_SDOclientUploadInitiate(
CO_SDOclient_t *SDO_C,
uint16_t index,
uint8_t subIndex,
uint8_t *dataRx,
uint32_t dataRxSize,
uint8_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.
*
* @param SDO_C This object.
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
* @param SDOtimeoutTime Timeout time for SDO communication in milliseconds.
* @param pDataSize pointer to external variable, where size of received
* data will be written.
* @param pSDOabortCode Pointer to external variable written by this function
* in case of error in communication.
*
* @return #CO_SDOclient_return_t
*/
CO_SDOclient_return_t CO_SDOclientUpload(
CO_SDOclient_t *SDO_C,
uint16_t timeDifference_ms,
uint16_t SDOtimeoutTime,
uint32_t *pDataSize,
uint32_t *pSDOabortCode);
/**
* 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.
*/
void CO_SDOclientClose(CO_SDOclient_t *SDO_C);
/** @} */
#endif