MindSDK_MM32F5270/components/canopen/CO_PDO.h

388 lines
16 KiB
C

/**
* CANopen Process Data Object protocol.
*
* @file CO_PDO.h
* @ingroup CO_PDO
* @author Janez Paternoster
* @copyright 2004 - 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_PDO_H
#define CO_PDO_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup CO_PDO PDO
* @ingroup CO_CANopen
* @{
*
* CANopen Process Data Object protocol.
*
* Process data objects are used for real-time data transfer with no protocol
* overhead.
*
* TPDO with specific identifier is transmitted by one device and recieved by
* zero or more devices as RPDO. PDO communication parameters(COB-ID,
* transmission type, etc.) are in Object Dictionary at index 0x1400+ and
* 0x1800+. PDO mapping parameters (size and contents of the PDO) are in Object
* Dictionary at index 0x1600+ and 0x1A00+.
*
* Features of the PDO as implemented here, in CANopenNode:
* - Dynamic PDO mapping.
* - Map granularity of one byte.
* - After RPDO is received from CAN bus, its data are copied to buffer.
* Function CO_RPDO_process() (called by application) copies data to
* mapped objects in Object Dictionary. Synchronous RPDOs are processed AFTER
* reception of the next SYNC message.
* - Function CO_TPDO_process() (called by application) sends TPDO if
* necessary. There are possible different transmission types, including
* automatic detection of Change of State of specific variable.
*/
/**
* RPDO communication parameter. The same as record from Object dictionary (index 0x1400+).
*/
typedef struct{
uint8_t maxSubIndex; /**< Equal to 2 */
/** Communication object identifier for message received. Meaning of the specific bits:
- Bit 0-10: COB-ID for PDO, to change it bit 31 must be set.
- Bit 11-29: set to 0 for 11 bit COB-ID.
- Bit 30: If true, rtr are NOT allowed for PDO.
- Bit 31: If true, node does NOT use the PDO. */
uint32_t COB_IDUsedByRPDO;
/** Transmission type. Values:
- 0-240: Reciving is synchronous, process after next reception of the SYNC object.
- 241-253: Not used.
- 254: Manufacturer specific.
- 255: Asynchronous. */
uint8_t transmissionType;
}CO_RPDOCommPar_t;
/**
* RPDO mapping parameter. The same as record from Object dictionary (index 0x1600+).
*/
typedef struct{
/** Actual number of mapped objects from 0 to 8. To change mapped object,
this value must be 0. */
uint8_t numberOfMappedObjects;
/** Location and size of the mapped object. Bit meanings `0xIIIISSLL`:
- Bit 0-7: Data Length in bits.
- Bit 8-15: Subindex from object distionary.
- Bit 16-31: Index from object distionary. */
uint32_t mappedObject1;
uint32_t mappedObject2; /**< Same */
uint32_t mappedObject3; /**< Same */
uint32_t mappedObject4; /**< Same */
uint32_t mappedObject5; /**< Same */
uint32_t mappedObject6; /**< Same */
uint32_t mappedObject7; /**< Same */
uint32_t mappedObject8; /**< Same */
}CO_RPDOMapPar_t;
/**
* TPDO communication parameter. The same as record from Object dictionary (index 0x1800+).
*/
typedef struct{
uint8_t maxSubIndex; /**< Equal to 6 */
/** Communication object identifier for transmitting message. Meaning of the specific bits:
- Bit 0-10: COB-ID for PDO, to change it bit 31 must be set.
- Bit 11-29: set to 0 for 11 bit COB-ID.
- Bit 30: If true, rtr are NOT allowed for PDO.
- Bit 31: If true, node does NOT use the PDO. */
uint32_t COB_IDUsedByTPDO;
/** Transmission type. Values:
- 0: Transmiting is synchronous, specification in device profile.
- 1-240: Transmiting is synchronous after every N-th SYNC object.
- 241-251: Not used.
- 252-253: Transmited only on reception of Remote Transmission Request.
- 254: Manufacturer specific.
- 255: Asinchronous, specification in device profile. */
uint8_t transmissionType;
/** Minimum time between transmissions of the PDO in 100micro seconds.
Zero disables functionality. */
uint16_t inhibitTime;
/** Not used */
uint8_t compatibilityEntry;
/** Time between periodic transmissions of the PDO in milliseconds.
Zero disables functionality. */
uint16_t eventTimer;
/** Used with numbered SYNC messages. Values:
- 0: Counter of the SYNC message shall not be processed.
- 1-240: The SYNC message with the counter value equal to this value
shall be regarded as the first received SYNC message. */
uint8_t SYNCStartValue;
}CO_TPDOCommPar_t;
/**
* TPDO mapping parameter. The same as record from Object dictionary (index 0x1A00+).
*/
typedef struct{
/** Actual number of mapped objects from 0 to 8. To change mapped object,
this value must be 0. */
uint8_t numberOfMappedObjects;
/** Location and size of the mapped object. Bit meanings `0xIIIISSLL`:
- Bit 0-7: Data Length in bits.
- Bit 8-15: Subindex from object distionary.
- Bit 16-31: Index from object distionary. */
uint32_t mappedObject1;
uint32_t mappedObject2; /**< Same */
uint32_t mappedObject3; /**< Same */
uint32_t mappedObject4; /**< Same */
uint32_t mappedObject5; /**< Same */
uint32_t mappedObject6; /**< Same */
uint32_t mappedObject7; /**< Same */
uint32_t mappedObject8; /**< Same */
}CO_TPDOMapPar_t;
/**
* RPDO object.
*/
typedef struct{
CO_EM_t *em; /**< From CO_RPDO_init() */
CO_SDO_t *SDO; /**< From CO_RPDO_init() */
CO_SYNC_t *SYNC; /**< From CO_RPDO_init() */
const CO_RPDOCommPar_t *RPDOCommPar;/**< From CO_RPDO_init() */
const CO_RPDOMapPar_t *RPDOMapPar; /**< From CO_RPDO_init() */
uint8_t *operatingState; /**< From CO_RPDO_init() */
uint8_t nodeId; /**< From CO_RPDO_init() */
uint16_t defaultCOB_ID; /**< From CO_RPDO_init() */
uint8_t restrictionFlags;/**< From CO_RPDO_init() */
/** True, if PDO is enabled and valid */
bool_t valid;
/** True, if PDO synchronous (transmissionType <= 240) */
bool_t synchronous;
/** Data length of the received PDO message. Calculated from mapping */
uint8_t dataLength;
/** Pointers to 8 data objects, where PDO will be copied */
uint8_t *mapPointer[8];
/** Variable indicates, if new PDO message received from CAN bus. */
volatile void *CANrxNew[2];
/** 8 data bytes of the received message. */
uint8_t CANrxData[2][8];
CO_CANmodule_t *CANdevRx; /**< From CO_RPDO_init() */
uint16_t CANdevRxIdx; /**< From CO_RPDO_init() */
}CO_RPDO_t;
/**
* TPDO object.
*/
typedef struct{
CO_EM_t *em; /**< From CO_TPDO_init() */
CO_SDO_t *SDO; /**< From CO_TPDO_init() */
CO_SYNC_t *SYNC; /**< From CO_TPDO_init() */
const CO_TPDOCommPar_t *TPDOCommPar;/**< From CO_TPDO_init() */
const CO_TPDOMapPar_t *TPDOMapPar; /**< From CO_TPDO_init() */
uint8_t *operatingState; /**< From CO_TPDO_init() */
uint8_t nodeId; /**< From CO_TPDO_init() */
uint16_t defaultCOB_ID; /**< From CO_TPDO_init() */
uint8_t restrictionFlags;/**< From CO_TPDO_init() */
bool_t valid; /**< True, if PDO is enabled and valid */
/** Data length of the transmitting PDO message. Calculated from mapping */
uint8_t dataLength;
/** If application set this flag, PDO will be later sent by
function CO_TPDO_process(). Depends on transmission type. */
uint8_t sendRequest;
/** Pointers to 8 data objects, where PDO will be copied */
uint8_t *mapPointer[8];
/** Each flag bit is connected with one mapPointer. If flag bit
is true, CO_TPDO_process() functiuon will send PDO if
Change of State is detected on value pointed by that mapPointer */
uint8_t sendIfCOSFlags;
/** SYNC counter used for PDO sending */
uint8_t syncCounter;
/** Inhibit timer used for inhibit PDO sending translated to microseconds */
uint32_t inhibitTimer;
/** Event timer used for PDO sending translated to microseconds */
uint32_t eventTimer;
CO_CANmodule_t *CANdevTx; /**< From CO_TPDO_init() */
CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer inside CANdev */
uint16_t CANdevTxIdx; /**< From CO_TPDO_init() */
}CO_TPDO_t;
/**
* Initialize RPDO object.
*
* Function must be called in the communication reset section.
*
* @param RPDO 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 nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added.
* @param defaultCOB_ID Default COB ID for this PDO (without NodeId).
* See #CO_Default_CAN_ID_t
* @param restrictionFlags Flag bits indicates, how PDO communication
* and mapping parameters are handled:
* - Bit1: If true, communication parameters are writeable only in pre-operational NMT state.
* - Bit2: If true, mapping parameters are writeable only in pre-operational NMT state.
* - Bit3: If true, communication parameters are read-only.
* - Bit4: If true, mapping parameters are read-only.
* @param RPDOCommPar Pointer to _RPDO communication parameter_ record from Object
* dictionary (index 0x1400+).
* @param RPDOMapPar Pointer to _RPDO mapping parameter_ record from Object
* dictionary (index 0x1600+).
* @param idx_RPDOCommPar Index in Object Dictionary.
* @param idx_RPDOMapPar Index in Object Dictionary.
* @param CANdevRx CAN device for PDO reception.
* @param CANdevRxIdx Index of receive buffer in the above CAN device.
*
* @return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
*/
CO_ReturnError_t CO_RPDO_init(
CO_RPDO_t *RPDO,
CO_EM_t *em,
CO_SDO_t *SDO,
CO_SYNC_t *SYNC,
uint8_t *operatingState,
uint8_t nodeId,
uint16_t defaultCOB_ID,
uint8_t restrictionFlags,
const CO_RPDOCommPar_t *RPDOCommPar,
const CO_RPDOMapPar_t *RPDOMapPar,
uint16_t idx_RPDOCommPar,
uint16_t idx_RPDOMapPar,
CO_CANmodule_t *CANdevRx,
uint16_t CANdevRxIdx);
/**
* Initialize TPDO object.
*
* Function must be called in the communication reset section.
*
* @param TPDO This object will be initialized.
* @param em Emergency object.
* @param SDO SDO object.
* @param operatingState Pointer to variable indicating CANopen device NMT internal state.
* @param nodeId CANopen Node ID of this device. If default COB_ID is used, value will be added.
* @param defaultCOB_ID Default COB ID for this PDO (without NodeId).
* See #CO_Default_CAN_ID_t
* @param restrictionFlags Flag bits indicates, how PDO communication
* and mapping parameters are handled:
* - Bit1: If true, communication parameters are writeable only in pre-operational NMT state.
* - Bit2: If true, mapping parameters are writeable only in pre-operational NMT state.
* - Bit3: If true, communication parameters are read-only.
* - Bit4: If true, mapping parameters are read-only.
* @param TPDOCommPar Pointer to _TPDO communication parameter_ record from Object
* dictionary (index 0x1400+).
* @param TPDOMapPar Pointer to _TPDO mapping parameter_ record from Object
* dictionary (index 0x1600+).
* @param idx_TPDOCommPar Index in Object Dictionary.
* @param idx_TPDOMapPar Index in Object Dictionary.
* @param CANdevTx CAN device used for PDO 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_TPDO_init(
CO_TPDO_t *TPDO,
CO_EM_t *em,
CO_SDO_t *SDO,
CO_SYNC_t *SYNC,
uint8_t *operatingState,
uint8_t nodeId,
uint16_t defaultCOB_ID,
uint8_t restrictionFlags,
const CO_TPDOCommPar_t *TPDOCommPar,
const CO_TPDOMapPar_t *TPDOMapPar,
uint16_t idx_TPDOCommPar,
uint16_t idx_TPDOMapPar,
CO_CANmodule_t *CANdevTx,
uint16_t CANdevTxIdx);
/**
* Verify Change of State of the PDO.
*
* Function verifies if variable mapped to TPDO has changed its value. Verified
* are only variables, which has set attribute _CO_ODA_TPDO_DETECT_COS_ in
* #CO_SDO_OD_attributes_t.
*
* Function may be called by application just before CO_TPDO_process() function,
* for example: `TPDOx->sendRequest = CO_TPDOisCOS(TPDOx); CO_TPDO_process(TPDOx, ....`
*
* @param TPDO TPDO object.
*
* @return True if COS was detected.
*/
uint8_t CO_TPDOisCOS(CO_TPDO_t *TPDO);
/**
* Send TPDO message.
*
* Function prepares TPDO data from Object Dictionary variables. It should not
* be called by application, it is called from CO_TPDO_process().
*
*
* @param TPDO TPDO object.
*
* @return Same as CO_CANsend().
*/
int16_t CO_TPDOsend(CO_TPDO_t *TPDO);
/**
* Process received PDO messages.
*
* Function must be called cyclically in any NMT state. It copies data from RPDO
* to Object Dictionary variables if: new PDO receives and PDO is valid and NMT
* operating state is operational. It does not verify _transmission type_.
*
* @param RPDO This object.
* @param syncWas True, if CANopen SYNC message was just received or transmitted.
*/
void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas);
/**
* Process transmitting PDO messages.
*
* Function must be called cyclically in any NMT state. It prepares and sends
* TPDO if necessary. If Change of State needs to be detected, function
* CO_TPDOisCOS() must be called before.
*
* @param TPDO This object.
* @param SYNC SYNC object. Ignored if NULL.
* @param syncWas True, if CANopen SYNC message was just received or transmitted.
* @param timeDifference_us Time difference from previous function call in [microseconds].
*/
void CO_TPDO_process(
CO_TPDO_t *TPDO,
bool_t syncWas,
uint32_t timeDifference_us);
#ifdef __cplusplus
}
#endif /*__cplusplus*/
/** @} */
#endif