1
0
Fork 0
This commit is contained in:
temi54c1l8 2025-08-19 12:36:25 +08:00 committed by GitHub
commit 7695e32890
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 75 additions and 6 deletions

View file

@ -867,6 +867,21 @@ CO_RPDO_process(CO_RPDO_t* RPDO,
* T P D O
******************************************************************************/
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_ENABLE) != 0
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
static void
CO_TPDO_RTR_receive(void* object, void* msg) {
CO_TPDO_t* TPDO = object;
CO_PDO_common_t* PDO = &TPDO->PDO_common;
uint8_t DLC = CO_CANrxMsg_readDLC(msg);
bool_t RTR = ( CO_CANrxMsg_readIdent(msg) & 0x0800U ) != 0U;
if ( (PDO->valid) && (DLC == 0U) && RTR ) {
TPDO->rtrRequest = true;
}
}
#endif
#if ((CO_CONFIG_PDO)&CO_CONFIG_FLAG_OD_DYNAMIC) != 0
/*
* Custom function for writing OD object "TPDO communication parameter"
@ -890,6 +905,7 @@ OD_write_18xx(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t*
uint32_t COB_ID = CO_getUint32(buf);
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FFU);
bool_t valid = (COB_ID & 0x80000000U) == 0U;
bool_t rtr_en = (COB_ID & 0x40000000U) == 0U;
/* bits 11...29 must be zero, PDO must be disabled on change, CAN_ID == 0 is
* not allowed, mapping must be configured before enabling the PDO */
@ -898,14 +914,23 @@ OD_write_18xx(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t*
return ODR_INVALID_VALUE;
}
/* For compatibility you should refuse to enable RTR if it is not supported, but for legacy (easy to use) this code is commented out
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) == 0
if( rtr_en ) {
return ODR_INVALID_VALUE;
}
#endif
*/
/* parameter changed? */
if ((valid != PDO->valid) || (CAN_ID != PDO->configuredCanId)) {
if ((valid != PDO->valid) || (CAN_ID != PDO->configuredCanId) || (rtr_en != TPDO->rtr_en)) {
/* if default CAN-ID is written, store to OD without Node-ID */
if (CAN_ID == PDO->preDefinedCanId) {
(void)CO_setUint32(bufCopy, COB_ID & 0xFFFFFF80U);
}
if (!valid) {
CAN_ID = 0;
rtr_en = false;
}
CO_CANtx_t* CANtxBuff = CO_CANtxBufferInit(
@ -919,6 +944,7 @@ OD_write_18xx(OD_stream_t* stream, const void* buf, OD_size_t count, OD_size_t*
TPDO->CANtxBuff = CANtxBuff;
PDO->valid = valid;
PDO->configuredCanId = CAN_ID;
TPDO->rtr_en = rtr_en;
}
break;
}
@ -991,7 +1017,11 @@ CO_TPDO_init(CO_TPDO_t* TPDO, OD_t* OD, CO_EM_t* em,
CO_SYNC_t* SYNC,
#endif
uint16_t preDefinedCanId, OD_entry_t* OD_18xx_TPDOCommPar, OD_entry_t* OD_1Axx_TPDOMapPar,
CO_CANmodule_t* CANdevTx, uint16_t CANdevTxIdx, uint32_t* errInfo) {
CO_CANmodule_t* CANdevTx, uint16_t CANdevTxIdx,
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
uint16_t CANdevRxIdx,
#endif
uint32_t* errInfo) {
CO_PDO_common_t* PDO = &TPDO->PDO_common;
ODR_t odRet;
@ -1045,6 +1075,7 @@ CO_TPDO_init(CO_TPDO_t* TPDO, OD_t* OD, CO_EM_t* em,
}
bool_t valid = (COB_ID & 0x80000000U) == 0U;
bool_t rtr_en = (COB_ID & 0x40000000U) == 0U;
uint16_t CAN_ID = (uint16_t)(COB_ID & 0x7FFU);
if (valid && ((PDO->mappedObjectsCount == 0U) || (CAN_ID == 0U))) {
valid = false;
@ -1059,6 +1090,7 @@ CO_TPDO_init(CO_TPDO_t* TPDO, OD_t* OD, CO_EM_t* em,
}
if (!valid) {
CAN_ID = 0;
rtr_en = false;
}
/* If default CAN-ID is stored in OD (without Node-ID), add Node-ID */
@ -1072,8 +1104,16 @@ CO_TPDO_init(CO_TPDO_t* TPDO, OD_t* OD, CO_EM_t* em,
if (TPDO->CANtxBuff == NULL) {
return CO_ERROR_ILLEGAL_ARGUMENT;
}
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
ret = CO_CANrxBufferInit(CANdevTx, CANdevRxIdx, CAN_ID, 0x7FF, true, (void*)TPDO, CO_TPDO_RTR_receive);
if (ret != CO_ERROR_NO) {
return ret;
}
#endif
PDO->valid = valid;
TPDO->rtr_en = rtr_en;
/* Configure communication parameter - inhibit time and event-timer (opt) */
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_TIMERS_ENABLE) != 0
@ -1238,6 +1278,15 @@ CO_TPDO_process(CO_TPDO_t* TPDO,
#endif
(void)syncWas;
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
if( TPDO->rtrRequest) {
TPDO->rtrRequest = false;
if( TPDO->rtr_en ) {
TPDO->sendRequest = true;
}
}
#endif
if (PDO->valid && NMTisOperational) {
/* check for event timer or application event */

View file

@ -297,7 +297,12 @@ typedef struct {
CO_CANtx_t* CANtxBuff; /**< CAN transmit buffer inside CANdev */
uint8_t transmissionType; /**< Copy of the variable from object dictionary */
bool_t sendRequest; /**< If this flag is set and TPDO is event driven (transmission type is 0, 254 or 255),
then PDO will be sent by CO_TPDO_process(). */
then PDO will be sent by CO_TPDO_process(). */
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
bool_t rtrRequest; /**< If this flag is set and the bit 30 COB-ID is set to zero,
then PDO will be sent by CO_TPDO_process(). */
#endif
bool_t rtr_en; /**< Enable RTR function according to bit 30 of COB-ID*/
#if (((CO_CONFIG_PDO)&CO_CONFIG_PDO_SYNC_ENABLE) != 0) || defined CO_DOXYGEN
CO_SYNC_t* SYNC; /**< From CO_TPDO_init() */
uint8_t syncStartValue; /**< Copy of the variable from object dictionary */
@ -336,7 +341,11 @@ CO_ReturnError_t CO_TPDO_init(CO_TPDO_t* TPDO, OD_t* OD, CO_EM_t* em,
CO_SYNC_t* SYNC,
#endif
uint16_t preDefinedCanId, OD_entry_t* OD_18xx_TPDOCommPar, OD_entry_t* OD_1Axx_TPDOMapPar,
CO_CANmodule_t* CANdevTx, uint16_t CANdevTxIdx, uint32_t* errInfo);
CO_CANmodule_t* CANdevTx, uint16_t CANdevTxIdx,
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
uint16_t CANdevRxIdx,
#endif
uint32_t* errInfo);
/**
* Request transmission of TPDO message.

View file

@ -501,6 +501,7 @@ extern "C" {
#define CO_CONFIG_TPDO_TIMERS_ENABLE 0x08
#define CO_CONFIG_PDO_SYNC_ENABLE 0x10
#define CO_CONFIG_PDO_OD_IO_ACCESS 0x20
#define CO_CONFIG_TPDO_RTR_ENABLE 0x40
/** @} */ /* CO_STACK_CONFIG_SYNC_PDO */
/**

View file

@ -199,6 +199,11 @@
#else
#define CO_TX_CNT_TPDO 0
#endif
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
#define CO_RX_CNT_TPDO_RTR CO_TX_CNT_TPDO
#else
#define CO_RX_CNT_TPDO_RTR 0
#endif
#if ((CO_CONFIG_LEDS)&CO_CONFIG_LEDS_ENABLE) != 0
#define OD_CNT_LEDS 1
@ -272,7 +277,8 @@
#define CO_RX_IDX_TIME (CO_RX_IDX_EM_CONS + (uint16_t)CO_RX_CNT_EM_CONS)
#define CO_RX_IDX_SRDO (CO_RX_IDX_TIME + (uint16_t)CO_RX_CNT_TIME)
#define CO_RX_IDX_RPDO (CO_RX_IDX_SRDO + ((uint16_t)CO_RX_CNT_SRDO * 2U))
#define CO_RX_IDX_SDO_SRV (CO_RX_IDX_RPDO + (uint16_t)CO_RX_CNT_RPDO)
#define CO_RX_IDX_TPDO_RTR (CO_RX_IDX_RPDO + (uint16_t)CO_RX_CNT_RPDO)
#define CO_RX_IDX_SDO_SRV (CO_RX_IDX_TPDO_RTR + (uint16_t)CO_RX_CNT_TPDO_RTR)
#define CO_RX_IDX_SDO_CLI (CO_RX_IDX_SDO_SRV + (uint16_t)CO_RX_CNT_SDO_SRV)
#define CO_RX_IDX_HB_CONS (CO_RX_IDX_SDO_CLI + (uint16_t)CO_RX_CNT_SDO_CLI)
#define CO_RX_IDX_NG_SLV (CO_RX_IDX_HB_CONS + (uint16_t)CO_RX_CNT_HB_CONS)
@ -1242,7 +1248,11 @@ CO_CANopenInitPDO(CO_t* co, CO_EM_t* em, OD_t* od, uint8_t nodeId, uint32_t* err
#if ((CO_CONFIG_PDO)&CO_CONFIG_PDO_SYNC_ENABLE) != 0
co->SYNC,
#endif
preDefinedCanId, TPDOcomm, TPDOmap, co->CANmodule, CO_GET_CO(TX_IDX_TPDO) + i, errInfo);
preDefinedCanId, TPDOcomm, TPDOmap, co->CANmodule, CO_GET_CO(TX_IDX_TPDO) + i,
#if ((CO_CONFIG_PDO)&CO_CONFIG_TPDO_RTR_ENABLE) != 0
CO_GET_CO(RX_IDX_TPDO_RTR) + i,
#endif
errInfo);
if (err != CO_ERROR_NO) {
return err;
}