Make SYNC optional in TPDO and RPDO.
This commit is contained in:
parent
6e28914ca9
commit
ffd5027cb2
7 changed files with 85 additions and 26 deletions
62
301/CO_PDO.c
62
301/CO_PDO.c
|
|
@ -28,7 +28,9 @@
|
|||
#include "301/CO_SDOserver.h"
|
||||
#include "301/CO_Emergency.h"
|
||||
#include "301/CO_NMT_Heartbeat.h"
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
#include "301/CO_SYNC.h"
|
||||
#endif
|
||||
#include "301/CO_PDO.h"
|
||||
|
||||
/*
|
||||
|
|
@ -51,6 +53,7 @@ static void CO_PDO_receive(void *object, void *msg){
|
|||
(*RPDO->operatingState == CO_NMT_OPERATIONAL) &&
|
||||
(DLC >= RPDO->dataLength))
|
||||
{
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
if(RPDO->SYNC && RPDO->synchronous && RPDO->SYNC->CANrxToggle) {
|
||||
/* copy data into second buffer and set 'new message' flag */
|
||||
RPDO->CANrxData[1][0] = data[0];
|
||||
|
|
@ -65,6 +68,7 @@ static void CO_PDO_receive(void *object, void *msg){
|
|||
CO_FLAG_SET(RPDO->CANrxNew[1]);
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
/* copy data into default buffer and set 'new message' flag */
|
||||
RPDO->CANrxData[0][0] = data[0];
|
||||
RPDO->CANrxData[0][1] = data[1];
|
||||
|
|
@ -76,7 +80,9 @@ static void CO_PDO_receive(void *object, void *msg){
|
|||
RPDO->CANrxData[0][7] = data[7];
|
||||
|
||||
CO_FLAG_SET(RPDO->CANrxNew[0]);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,13 +111,17 @@ static void CO_RPDOconfigCom(CO_RPDO_t* RPDO, uint32_t COB_IDUsedByRPDO){
|
|||
/* is used default COB-ID? */
|
||||
if(ID == RPDO->defaultCOB_ID) ID += RPDO->nodeId;
|
||||
RPDO->valid = true;
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
RPDO->synchronous = (RPDO->RPDOCommPar->transmissionType <= 240) ? true : false;
|
||||
#endif
|
||||
}
|
||||
else{
|
||||
ID = 0;
|
||||
RPDO->valid = false;
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[0]);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[1]);
|
||||
#endif
|
||||
}
|
||||
r = CO_CANrxBufferInit(
|
||||
RPDO->CANdevRx, /* CAN device */
|
||||
|
|
@ -124,7 +134,9 @@ static void CO_RPDOconfigCom(CO_RPDO_t* RPDO, uint32_t COB_IDUsedByRPDO){
|
|||
if(r != CO_ERROR_NO){
|
||||
RPDO->valid = false;
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[0]);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[1]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -467,6 +479,7 @@ static CO_SDO_abortCode_t CO_ODF_RPDOcom(CO_ODF_arg_t *ODF_arg){
|
|||
}
|
||||
else if(ODF_arg->subIndex == 2){ /* Transmission_type */
|
||||
uint8_t *value = (uint8_t*) ODF_arg->data;
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
bool_t synchronousPrev = RPDO->synchronous;
|
||||
|
||||
/* values from 241...253 are not valid */
|
||||
|
|
@ -479,6 +492,11 @@ static CO_SDO_abortCode_t CO_ODF_RPDOcom(CO_ODF_arg_t *ODF_arg){
|
|||
if(RPDO->synchronous != synchronousPrev) {
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[1]);
|
||||
}
|
||||
#else
|
||||
/* values from 0...253 are not valid */
|
||||
if(*value <= 253)
|
||||
return CO_SDO_AB_INVALID_VALUE; /* Invalid value for parameter (download only). */
|
||||
#endif
|
||||
}
|
||||
|
||||
return CO_SDO_AB_NONE;
|
||||
|
|
@ -541,16 +559,24 @@ static CO_SDO_abortCode_t CO_ODF_TPDOcom(CO_ODF_arg_t *ODF_arg){
|
|||
|
||||
/* configure TPDO */
|
||||
CO_TPDOconfigCom(TPDO, value, TPDO->CANtxBuff->syncFlag);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
TPDO->syncCounter = 255;
|
||||
#endif
|
||||
}
|
||||
else if(ODF_arg->subIndex == 2){ /* Transmission_type */
|
||||
uint8_t *value = (uint8_t*) ODF_arg->data;
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
/* values from 241...253 are not valid */
|
||||
if(*value >= 241 && *value <= 253)
|
||||
return CO_SDO_AB_INVALID_VALUE; /* Invalid value for parameter (download only). */
|
||||
TPDO->CANtxBuff->syncFlag = (*value <= 240) ? 1 : 0;
|
||||
TPDO->syncCounter = 255;
|
||||
#else
|
||||
/* values from 0...253 are not valid */
|
||||
if(*value <= 253)
|
||||
return CO_SDO_AB_INVALID_VALUE; /* Invalid value for parameter (download only). */
|
||||
#endif
|
||||
}
|
||||
else if(ODF_arg->subIndex == 3){ /* Inhibit_Time */
|
||||
/* if PDO is valid, value can not be changed */
|
||||
|
|
@ -717,7 +743,7 @@ CO_ReturnError_t CO_RPDO_init(
|
|||
CO_RPDO_t *RPDO,
|
||||
CO_EM_t *em,
|
||||
CO_SDO_t *SDO,
|
||||
CO_SYNC_t *SYNC,
|
||||
void *SYNC,
|
||||
CO_NMT_internalState_t *operatingState,
|
||||
uint8_t nodeId,
|
||||
uint16_t defaultCOB_ID,
|
||||
|
|
@ -738,7 +764,9 @@ CO_ReturnError_t CO_RPDO_init(
|
|||
/* Configure object variables */
|
||||
RPDO->em = em;
|
||||
RPDO->SDO = SDO;
|
||||
RPDO->SYNC = SYNC;
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
RPDO->SYNC = (CO_SYNC_t *)SYNC;
|
||||
#endif
|
||||
RPDO->RPDOCommPar = RPDOCommPar;
|
||||
RPDO->RPDOMapPar = RPDOMapPar;
|
||||
RPDO->operatingState = operatingState;
|
||||
|
|
@ -752,7 +780,9 @@ CO_ReturnError_t CO_RPDO_init(
|
|||
|
||||
/* configure communication and mapping */
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[0]);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[1]);
|
||||
#endif
|
||||
RPDO->CANdevRx = CANdevRx;
|
||||
RPDO->CANdevRxIdx = CANdevRxIdx;
|
||||
|
||||
|
|
@ -768,7 +798,7 @@ CO_ReturnError_t CO_TPDO_init(
|
|||
CO_TPDO_t *TPDO,
|
||||
CO_EM_t *em,
|
||||
CO_SDO_t *SDO,
|
||||
CO_SYNC_t *SYNC,
|
||||
void *SYNC,
|
||||
CO_NMT_internalState_t *operatingState,
|
||||
uint8_t nodeId,
|
||||
uint16_t defaultCOB_ID,
|
||||
|
|
@ -789,7 +819,9 @@ CO_ReturnError_t CO_TPDO_init(
|
|||
/* Configure object variables */
|
||||
TPDO->em = em;
|
||||
TPDO->SDO = SDO;
|
||||
TPDO->SYNC = SYNC;
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
TPDO->SYNC = (CO_SYNC_t *)SYNC;
|
||||
#endif
|
||||
TPDO->TPDOCommPar = TPDOCommPar;
|
||||
TPDO->TPDOMapPar = TPDOMapPar;
|
||||
TPDO->operatingState = operatingState;
|
||||
|
|
@ -804,12 +836,13 @@ CO_ReturnError_t CO_TPDO_init(
|
|||
/* configure communication and mapping */
|
||||
TPDO->CANdevTx = CANdevTx;
|
||||
TPDO->CANdevTxIdx = CANdevTxIdx;
|
||||
TPDO->syncCounter = 255;
|
||||
TPDO->inhibitTimer = 0;
|
||||
TPDO->eventTimer = ((uint32_t) TPDOCommPar->eventTimer) * 1000;
|
||||
if(TPDOCommPar->transmissionType>=254) TPDO->sendRequest = 1;
|
||||
|
||||
CO_TPDOconfigMap(TPDO, TPDOMapPar->numberOfMappedObjects);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
TPDO->syncCounter = 255;
|
||||
CO_TPDOconfigCom(TPDO, TPDOCommPar->COB_IDUsedByTPDO, ((TPDOCommPar->transmissionType<=240) ? 1 : 0));
|
||||
|
||||
if((TPDOCommPar->transmissionType>240 &&
|
||||
|
|
@ -817,6 +850,11 @@ CO_ReturnError_t CO_TPDO_init(
|
|||
TPDOCommPar->SYNCStartValue>240){
|
||||
TPDO->valid = false;
|
||||
}
|
||||
#else
|
||||
CO_TPDOconfigCom(TPDO, TPDOCommPar->COB_IDUsedByTPDO, 0);
|
||||
if(TPDOCommPar->transmissionType<254)
|
||||
TPDO->valid = false;
|
||||
#endif
|
||||
|
||||
return CO_ERROR_NO;
|
||||
}
|
||||
|
|
@ -898,13 +936,21 @@ int16_t CO_TPDOsend(CO_TPDO_t *TPDO){
|
|||
//#define RPDO_CALLS_EXTENSION
|
||||
/******************************************************************************/
|
||||
void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas){
|
||||
bool_t process_rpdo = true;
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
if(RPDO->synchronous && !syncWas)
|
||||
process_rpdo = false;
|
||||
#endif
|
||||
|
||||
if(!RPDO->valid || !(*RPDO->operatingState == CO_NMT_OPERATIONAL))
|
||||
{
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[0]);
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
CO_FLAG_CLEAR(RPDO->CANrxNew[1]);
|
||||
#endif
|
||||
}
|
||||
else if(!RPDO->synchronous || syncWas)
|
||||
else if(process_rpdo)
|
||||
{
|
||||
#if defined(RPDO_CALLS_EXTENSION)
|
||||
bool_t update = false;
|
||||
|
|
@ -912,10 +958,12 @@ void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas){
|
|||
|
||||
uint8_t bufNo = 0;
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
/* Determine, which of the two rx buffers, contains relevant message. */
|
||||
if(RPDO->SYNC && RPDO->synchronous && !RPDO->SYNC->CANrxToggle) {
|
||||
bufNo = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(CO_FLAG_READ(RPDO->CANrxNew[bufNo])){
|
||||
int16_t i;
|
||||
|
|
@ -1002,6 +1050,7 @@ void CO_TPDO_process(
|
|||
#endif
|
||||
}
|
||||
|
||||
#if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
|
||||
/* Synchronous PDOs */
|
||||
else if(TPDO->SYNC && syncWas){
|
||||
/* send synchronous acyclic PDO */
|
||||
|
|
@ -1031,6 +1080,7 @@ void CO_TPDO_process(
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else{
|
||||
|
|
|
|||
35
301/CO_PDO.h
35
301/CO_PDO.h
|
|
@ -165,7 +165,6 @@ typedef struct{
|
|||
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() */
|
||||
CO_NMT_internalState_t *operatingState; /**< From CO_RPDO_init() */
|
||||
|
|
@ -174,16 +173,22 @@ typedef struct{
|
|||
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];
|
||||
#if ((CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE) || defined CO_DOXYGEN
|
||||
CO_SYNC_t *SYNC; /**< From CO_RPDO_init() */
|
||||
/** True, if PDO synchronous (transmissionType <= 240) */
|
||||
bool_t synchronous;
|
||||
/** 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];
|
||||
#else
|
||||
volatile void *CANrxNew[1];
|
||||
uint8_t CANrxData[1][8];
|
||||
#endif
|
||||
CO_CANmodule_t *CANdevRx; /**< From CO_RPDO_init() */
|
||||
uint16_t CANdevRxIdx; /**< From CO_RPDO_init() */
|
||||
}CO_RPDO_t;
|
||||
|
|
@ -195,7 +200,6 @@ typedef struct{
|
|||
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() */
|
||||
CO_NMT_internalState_t *operatingState; /**< From CO_TPDO_init() */
|
||||
|
|
@ -210,16 +214,19 @@ typedef struct{
|
|||
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;
|
||||
/** 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;
|
||||
#if ((CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE) || defined CO_DOXYGEN
|
||||
/** SYNC counter used for PDO sending */
|
||||
uint8_t syncCounter;
|
||||
CO_SYNC_t *SYNC; /**< From CO_TPDO_init() */
|
||||
#endif
|
||||
CO_CANmodule_t *CANdevTx; /**< From CO_TPDO_init() */
|
||||
CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer inside CANdev */
|
||||
uint16_t CANdevTxIdx; /**< From CO_TPDO_init() */
|
||||
|
|
@ -234,7 +241,7 @@ typedef struct{
|
|||
* @param RPDO This object will be initialized.
|
||||
* @param em Emergency object.
|
||||
* @param SDO SDO server object.
|
||||
* @param SYNC SYNC object.
|
||||
* @param SYNC void pointer to SYNC object or NULL.
|
||||
* @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).
|
||||
|
|
@ -260,7 +267,7 @@ CO_ReturnError_t CO_RPDO_init(
|
|||
CO_RPDO_t *RPDO,
|
||||
CO_EM_t *em,
|
||||
CO_SDO_t *SDO,
|
||||
CO_SYNC_t *SYNC,
|
||||
void *SYNC,
|
||||
CO_NMT_internalState_t *operatingState,
|
||||
uint8_t nodeId,
|
||||
uint16_t defaultCOB_ID,
|
||||
|
|
@ -281,7 +288,7 @@ CO_ReturnError_t CO_RPDO_init(
|
|||
* @param TPDO This object will be initialized.
|
||||
* @param em Emergency object.
|
||||
* @param SDO SDO object.
|
||||
* @param SYNC SYNC object.
|
||||
* @param SYNC void pointer to SYNC object or NULL.
|
||||
* @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).
|
||||
|
|
@ -307,7 +314,7 @@ CO_ReturnError_t CO_TPDO_init(
|
|||
CO_TPDO_t *TPDO,
|
||||
CO_EM_t *em,
|
||||
CO_SDO_t *SDO,
|
||||
CO_SYNC_t *SYNC,
|
||||
void *SYNC,
|
||||
CO_NMT_internalState_t *operatingState,
|
||||
uint8_t nodeId,
|
||||
uint16_t defaultCOB_ID,
|
||||
|
|
|
|||
|
|
@ -195,10 +195,12 @@ extern "C" {
|
|||
* Possible flags, can be ORed:
|
||||
* - #CO_CONFIG_FLAG_TIMERNEXT - Enable calculation of timerNext_us variable
|
||||
* inside CO_TPDO_process().
|
||||
* - CO_CONFIG_PDO_SYNC_ENABLE - Enable SYNC object inside PDO objects.
|
||||
*/
|
||||
#ifdef CO_DOXYGEN
|
||||
#define CO_CONFIG_PDO CO_CONFIG_FLAG_TIMERNEXT
|
||||
#define CO_CONFIG_PDO CO_CONFIG_FLAG_TIMERNEXT | CO_CONFIG_PDO_SYNC_ENABLE
|
||||
#endif
|
||||
#define CO_CONFIG_PDO_SYNC_ENABLE 0x01
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifndef CO_CONFIG_PDO
|
||||
#define CO_CONFIG_PDO 0
|
||||
#define CO_CONFIG_PDO CO_CONFIG_PDO_SYNC_ENABLE
|
||||
#endif
|
||||
|
||||
#ifndef CO_CONFIG_SYNC
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ CO_ReturnError_t CO_CANopenInit(uint8_t nodeId) {
|
|||
err = CO_RPDO_init(CO->RPDO[i],
|
||||
CO->em,
|
||||
CO->SDO[0],
|
||||
CO->SYNC,
|
||||
(void *)CO->SYNC,
|
||||
&CO->NMT->operatingState,
|
||||
nodeId,
|
||||
((i < 4) ? (CO_CAN_ID_RPDO_1 + i * 0x100) : 0),
|
||||
|
|
@ -544,7 +544,7 @@ CO_ReturnError_t CO_CANopenInit(uint8_t nodeId) {
|
|||
err = CO_TPDO_init(CO->TPDO[i],
|
||||
CO->em,
|
||||
CO->SDO[0],
|
||||
CO->SYNC,
|
||||
(void *)CO->SYNC,
|
||||
&CO->NMT->operatingState,
|
||||
nodeId,
|
||||
((i < 4) ? (CO_CAN_ID_TPDO_1 + i * 0x100) : 0),
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifndef CO_CONFIG_PDO
|
||||
#define CO_CONFIG_PDO CO_CONFIG_FLAG_TIMERNEXT
|
||||
#define CO_CONFIG_PDO CO_CONFIG_FLAG_TIMERNEXT | CO_CONFIG_PDO_SYNC_ENABLE
|
||||
#endif
|
||||
|
||||
#ifndef CO_CONFIG_SYNC
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifndef CO_CONFIG_PDO
|
||||
#define CO_CONFIG_PDO CO_CONFIG_FLAG_TIMERNEXT
|
||||
#define CO_CONFIG_PDO CO_CONFIG_FLAG_TIMERNEXT | CO_CONFIG_PDO_SYNC_ENABLE
|
||||
#endif
|
||||
|
||||
#ifndef CO_CONFIG_SYNC
|
||||
|
|
|
|||
Loading…
Reference in a new issue