Time base CHANGED TO MICROSECONDS in all objects. FIX OS!
- Necessary to update Time base in OS too - call to CO_process() function. - timerNext_us info to OS implemented in in all objects. - CO_NMT_blinkingProcess50ms() moved inside CO_NMT_process(). - CO_HBconsumer_process() function optimized and revised. - Bugfix "timeDifference_us = 0;" inside the for loop.
This commit is contained in:
parent
1d051aa3d2
commit
c19879b659
22 changed files with 441 additions and 396 deletions
34
CANopen.c
34
CANopen.c
|
|
@ -525,6 +525,7 @@ CO_ReturnError_t CO_CANopenInit(
|
|||
CO_OD_NoOfElements,
|
||||
CO_SDO_ODExtensions,
|
||||
nodeId,
|
||||
1000,
|
||||
CO->CANmodule[0],
|
||||
CO_RXCAN_SDO_SRV+i,
|
||||
CO->CANmodule[0],
|
||||
|
|
@ -815,63 +816,52 @@ void CO_delete(void *CANptr){
|
|||
/******************************************************************************/
|
||||
CO_NMT_reset_cmd_t CO_process(
|
||||
CO_t *co,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t *timerNext_ms)
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
uint8_t i;
|
||||
bool_t NMTisPreOrOperational = false;
|
||||
CO_NMT_reset_cmd_t reset = CO_RESET_NOT;
|
||||
#ifdef CO_USE_LEDS
|
||||
static uint16_t ms50 = 0;
|
||||
#endif /* CO_USE_LEDS */
|
||||
|
||||
if(co->NMT->operatingState == CO_NMT_PRE_OPERATIONAL || co->NMT->operatingState == CO_NMT_OPERATIONAL)
|
||||
NMTisPreOrOperational = true;
|
||||
|
||||
#ifdef CO_USE_LEDS
|
||||
ms50 += timeDifference_ms;
|
||||
if(ms50 >= 50){
|
||||
ms50 -= 50;
|
||||
CO_NMT_blinkingProcess50ms(co->NMT);
|
||||
}
|
||||
#endif /* CO_USE_LEDS */
|
||||
|
||||
for(i=0; i<CO_NO_SDO_SERVER; i++){
|
||||
CO_SDO_process(
|
||||
co->SDO[i],
|
||||
NMTisPreOrOperational,
|
||||
timeDifference_ms,
|
||||
1000,
|
||||
timerNext_ms);
|
||||
timeDifference_us,
|
||||
timerNext_us);
|
||||
}
|
||||
|
||||
CO_EM_process(
|
||||
co->emPr,
|
||||
NMTisPreOrOperational,
|
||||
timeDifference_ms * 10,
|
||||
timeDifference_us,
|
||||
OD_inhibitTimeEMCY,
|
||||
timerNext_ms);
|
||||
timerNext_us);
|
||||
|
||||
|
||||
reset = CO_NMT_process(
|
||||
co->NMT,
|
||||
timeDifference_ms,
|
||||
timeDifference_us,
|
||||
OD_producerHeartbeatTime,
|
||||
OD_NMTStartup,
|
||||
OD_errorRegister,
|
||||
OD_errorBehavior,
|
||||
timerNext_ms);
|
||||
timerNext_us);
|
||||
|
||||
|
||||
CO_HBconsumer_process(
|
||||
co->HBcons,
|
||||
NMTisPreOrOperational,
|
||||
timeDifference_ms);
|
||||
timeDifference_us,
|
||||
timerNext_us);
|
||||
|
||||
#if CO_NO_TIME == 1
|
||||
CO_TIME_process(
|
||||
co->TIME,
|
||||
timeDifference_ms);
|
||||
timeDifference_us);
|
||||
#endif
|
||||
|
||||
return reset;
|
||||
|
|
|
|||
14
CANopen.h
14
CANopen.h
|
|
@ -200,10 +200,10 @@ void CO_delete(void *CANptr);
|
|||
* objects.
|
||||
*
|
||||
* @param co CANopen object.
|
||||
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
|
||||
* @param timerNext_ms Return value - info to OS - maximum delay after function
|
||||
* should be called next time in [milliseconds]. Value can be used for OS
|
||||
* sleep time. Initial value must be set to something, 50ms typically.
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param timerNext_us [out] info to OS - maximum delay after function
|
||||
* should be called next time in [microseconds]. Value can be used for OS
|
||||
* sleep time. Initial value must be set to something, 50000us typically.
|
||||
* Output will be equal or lower to initial value. If there is new object
|
||||
* to process, delay should be suspended and this function should be
|
||||
* called immediately. Parameter is ignored if NULL.
|
||||
|
|
@ -212,8 +212,8 @@ void CO_delete(void *CANptr);
|
|||
*/
|
||||
CO_NMT_reset_cmd_t CO_process(
|
||||
CO_t *co,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t *timerNext_ms);
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
|
||||
#if CO_NO_SYNC == 1
|
||||
|
|
@ -271,7 +271,7 @@ void CO_process_TPDO(
|
|||
*
|
||||
* @param CO This object.
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param timerNext_us Return value - info to OS - maximum delay after function
|
||||
* @param timerNext_us [out] info to OS - maximum delay after function
|
||||
* should be called next time in [microseconds]. Value can be used for OS
|
||||
* sleep time. Initial value must be set to something, 1000us typically.
|
||||
* Output will be equal or lower to initial value. If there is new object
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
/*
|
||||
* CAN module object for Linux socketCAN.
|
||||
*
|
||||
* This file is a template for other microcontrollers.
|
||||
* Linux socketCAN interface for CANopenNode.
|
||||
*
|
||||
* @file CO_driver.c
|
||||
* @ingroup CO_driver
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
/**
|
||||
* CAN module object for Linux socketCAN.
|
||||
*
|
||||
* This file is a template for other microcontrollers.
|
||||
* Notify pipe for Linux threads.
|
||||
*
|
||||
* @file CO_notify_pipe.h
|
||||
* @ingroup CO_driver
|
||||
|
|
|
|||
|
|
@ -232,15 +232,16 @@ void CO_EM_initCallbackRx(
|
|||
void CO_EM_process(
|
||||
CO_EMpr_t *emPr,
|
||||
bool_t NMTisPreOrOperational,
|
||||
uint16_t timeDifference_100us,
|
||||
uint16_t emInhTime,
|
||||
uint16_t *timerNext_ms)
|
||||
uint32_t timeDifference_us,
|
||||
uint16_t emInhTime_100us,
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
|
||||
CO_EM_t *em = emPr->em;
|
||||
uint8_t errorRegister;
|
||||
uint8_t errorMask;
|
||||
uint8_t i;
|
||||
uint32_t emInhTime_us = (uint32_t)emInhTime_100us * 100;
|
||||
|
||||
/* verify errors from driver and other */
|
||||
CO_CANverifyErrors(emPr->CANdev);
|
||||
|
|
@ -270,8 +271,8 @@ void CO_EM_process(
|
|||
*emPr->errorRegister = (*emPr->errorRegister & errorMask) | errorRegister;
|
||||
|
||||
/* inhibit time */
|
||||
if(emPr->inhibitEmTimer < emInhTime){
|
||||
emPr->inhibitEmTimer += timeDifference_100us;
|
||||
if (emPr->inhibitEmTimer < emInhTime_us) {
|
||||
emPr->inhibitEmTimer += timeDifference_us;
|
||||
}
|
||||
|
||||
/* send Emergency message. */
|
||||
|
|
@ -282,7 +283,7 @@ void CO_EM_process(
|
|||
uint32_t preDEF; /* preDefinedErrorField */
|
||||
uint16_t diff;
|
||||
|
||||
if (emPr->inhibitEmTimer >= emInhTime) {
|
||||
if (emPr->inhibitEmTimer >= emInhTime_us) {
|
||||
/* inhibit time elapsed, send message */
|
||||
|
||||
/* add error register */
|
||||
|
|
@ -323,11 +324,12 @@ void CO_EM_process(
|
|||
/* send CAN message */
|
||||
CO_CANsend(emPr->CANdev, emPr->CANtxBuff);
|
||||
}
|
||||
|
||||
/* check again after inhibit time elapsed */
|
||||
diff = (emInhTime + 9) / 10; /* time difference in ms, always round up */
|
||||
if (timerNext_ms != NULL && *timerNext_ms > diff) {
|
||||
*timerNext_ms = diff;
|
||||
else if (timerNext_us != NULL) {
|
||||
/* check again after inhibit time elapsed */
|
||||
diff = emInhTime_us - emPr->inhibitEmTimer;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ typedef struct{
|
|||
uint32_t *preDefErr; /**< From CO_EM_init() */
|
||||
uint8_t preDefErrSize; /**< From CO_EM_init() */
|
||||
uint8_t preDefErrNoOfErrors;/**< Number of active errors in preDefErr */
|
||||
uint16_t inhibitEmTimer; /**< Internal timer for emergency message */
|
||||
uint32_t inhibitEmTimer; /**< Internal timer for emergency message */
|
||||
CO_EM_t *em; /**< CO_EM_t sub object is included here */
|
||||
CO_CANmodule_t *CANdev; /**< From CO_EM_init() */
|
||||
CO_CANtx_t *CANtxBuff; /**< CAN transmit buffer */
|
||||
|
|
@ -432,16 +432,16 @@ void CO_EM_initCallbackRx(
|
|||
*
|
||||
* @param emPr This object.
|
||||
* @param NMTisPreOrOperational True if this node is NMT_PRE_OPERATIONAL or NMT_OPERATIONAL.
|
||||
* @param timeDifference_100us Time difference from previous function call in [100 * microseconds].
|
||||
* @param emInhTime _Inhibit time EMCY_ (object dictionary, index 0x1015).
|
||||
* @param timerNext_ms Return value - info to OS - see CO_process().
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param emInhTime _Inhibit time EMCY_ in [100*us] (object dictionary, index 0x1015).
|
||||
* @param timerNext_us [out] info to OS - see CO_process().
|
||||
*/
|
||||
void CO_EM_process(
|
||||
CO_EMpr_t *emPr,
|
||||
bool_t NMTisPreOrOperational,
|
||||
uint16_t timeDifference_100us,
|
||||
uint32_t timeDifference_us,
|
||||
uint16_t emInhTime,
|
||||
uint16_t *timerNext_ms);
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -52,52 +52,6 @@ static void CO_HBcons_receive(void *object, void *msg){
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure one monitored node.
|
||||
*/
|
||||
static void CO_HBcons_monitoredNodeConfig(
|
||||
CO_HBconsumer_t *HBcons,
|
||||
uint8_t idx,
|
||||
uint8_t nodeId,
|
||||
uint16_t time)
|
||||
{
|
||||
uint16_t COB_ID;
|
||||
CO_HBconsNode_t *monitoredNode;
|
||||
|
||||
if(idx >= HBcons->numberOfMonitoredNodes) return;
|
||||
|
||||
monitoredNode = &HBcons->monitoredNodes[idx];
|
||||
monitoredNode->nodeId = nodeId;
|
||||
monitoredNode->time = time;
|
||||
monitoredNode->NMTstate = CO_NMT_INITIALIZING;
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNCONFIGURED;
|
||||
CO_CANrxNew_CLEAR(monitoredNode->CANrxNew);
|
||||
|
||||
/* is channel used */
|
||||
if(monitoredNode->nodeId && monitoredNode->time){
|
||||
COB_ID = monitoredNode->nodeId + CO_CAN_ID_HEARTBEAT;
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNKNOWN;
|
||||
|
||||
}
|
||||
else{
|
||||
COB_ID = 0;
|
||||
monitoredNode->time = 0;
|
||||
}
|
||||
|
||||
/* configure Heartbeat consumer CAN reception */
|
||||
if (monitoredNode->HBstate != CO_HBconsumer_UNCONFIGURED) {
|
||||
CO_CANrxBufferInit(
|
||||
HBcons->CANdevRx,
|
||||
HBcons->CANdevRxIdxStart + idx,
|
||||
COB_ID,
|
||||
0x7FF,
|
||||
0,
|
||||
(void*)&HBcons->monitoredNodes[idx],
|
||||
CO_HBcons_receive);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OD function for accessing _Consumer Heartbeat Time_ (index 0x1016) from SDO server.
|
||||
*
|
||||
|
|
@ -156,7 +110,9 @@ CO_ReturnError_t CO_HBconsumer_init(
|
|||
HBcons->HBconsTime = HBconsTime;
|
||||
HBcons->monitoredNodes = monitoredNodes;
|
||||
HBcons->numberOfMonitoredNodes = numberOfMonitoredNodes;
|
||||
HBcons->allMonitoredOperational = 0;
|
||||
HBcons->allMonitoredActive = false;
|
||||
HBcons->allMonitoredOperational = CO_NMT_INITIALIZING;
|
||||
HBcons->NMTisPreOrOperationalPrev = false;
|
||||
HBcons->CANdevRx = CANdevRx;
|
||||
HBcons->CANdevRxIdxStart = CANdevRxIdxStart;
|
||||
|
||||
|
|
@ -178,7 +134,7 @@ CO_ReturnError_t CO_HBconsumer_initEntry(
|
|||
CO_HBconsumer_t *HBcons,
|
||||
uint8_t idx,
|
||||
uint8_t nodeId,
|
||||
uint16_t consumerTime)
|
||||
uint16_t consumerTime_ms)
|
||||
{
|
||||
CO_ReturnError_t ret = CO_ERROR_NO;
|
||||
|
||||
|
|
@ -187,7 +143,7 @@ CO_ReturnError_t CO_HBconsumer_initEntry(
|
|||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
if((consumerTime != 0) && (nodeId != 0)){
|
||||
if((consumerTime_ms != 0) && (nodeId != 0)){
|
||||
uint8_t i;
|
||||
/* there must not be more entries with same index and time different than zero */
|
||||
for(i = 0U; i<HBcons->numberOfMonitoredNodes; i++){
|
||||
|
|
@ -200,9 +156,37 @@ CO_ReturnError_t CO_HBconsumer_initEntry(
|
|||
}
|
||||
}
|
||||
|
||||
/* Configure */
|
||||
if(ret == CO_ERROR_NO){
|
||||
CO_HBcons_monitoredNodeConfig(HBcons, idx, nodeId, consumerTime);
|
||||
/* Configure one monitored node */
|
||||
if (ret == CO_ERROR_NO && idx < HBcons->numberOfMonitoredNodes ) {
|
||||
uint16_t COB_ID;
|
||||
|
||||
CO_HBconsNode_t * monitoredNode = &HBcons->monitoredNodes[idx];
|
||||
monitoredNode->nodeId = nodeId;
|
||||
monitoredNode->time_us = (int32_t)consumerTime_ms * 1000;
|
||||
monitoredNode->NMTstate = CO_NMT_INITIALIZING;
|
||||
CO_CANrxNew_CLEAR(monitoredNode->CANrxNew);
|
||||
|
||||
/* is channel used */
|
||||
if (monitoredNode->nodeId && monitoredNode->time_us) {
|
||||
COB_ID = monitoredNode->nodeId + CO_CAN_ID_HEARTBEAT;
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNKNOWN;
|
||||
}
|
||||
else {
|
||||
COB_ID = 0;
|
||||
monitoredNode->time_us = 0;
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNCONFIGURED;
|
||||
}
|
||||
|
||||
/* configure Heartbeat consumer CAN reception */
|
||||
if (monitoredNode->HBstate != CO_HBconsumer_UNCONFIGURED) {
|
||||
CO_CANrxBufferInit(HBcons->CANdevRx,
|
||||
HBcons->CANdevRxIdxStart + idx,
|
||||
COB_ID,
|
||||
0x7FF,
|
||||
0,
|
||||
(void*)&HBcons->monitoredNodes[idx],
|
||||
CO_HBcons_receive);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -264,102 +248,120 @@ void CO_HBconsumer_initCallbackRemoteReset(
|
|||
monitoredNode->functSignalObjectRemoteReset = object;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void CO_HBconsumer_process(
|
||||
CO_HBconsumer_t *HBcons,
|
||||
bool_t NMTisPreOrOperational,
|
||||
uint16_t timeDifference_ms)
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t emcyHeartbeatTimeoutActive = 0;
|
||||
uint8_t emcyRemoteResetActive = 0;
|
||||
uint8_t AllMonitoredOperationalCopy;
|
||||
CO_HBconsNode_t *monitoredNode;
|
||||
bool_t allMonitoredActiveCurrent = true;
|
||||
uint8_t allMonitoredOperationalCurrent = CO_NMT_OPERATIONAL;
|
||||
CO_HBconsNode_t *monitoredNode = &HBcons->monitoredNodes[0];
|
||||
|
||||
AllMonitoredOperationalCopy = 5;
|
||||
monitoredNode = &HBcons->monitoredNodes[0];
|
||||
if (NMTisPreOrOperational && HBcons->NMTisPreOrOperationalPrev) {
|
||||
for (i=0; i<HBcons->numberOfMonitoredNodes; i++) {
|
||||
uint32_t timeDifference_us_copy = timeDifference_us;
|
||||
|
||||
if(NMTisPreOrOperational){
|
||||
for(i=0; i<HBcons->numberOfMonitoredNodes; i++){
|
||||
if(monitoredNode->time > 0){/* is node monitored */
|
||||
/* Verify if received message is heartbeat or bootup */
|
||||
if(CO_CANrxNew_READ(monitoredNode->CANrxNew)){
|
||||
if(monitoredNode->NMTstate == CO_NMT_INITIALIZING){
|
||||
/* bootup message, call callback */
|
||||
if (monitoredNode->pFunctSignalRemoteReset != NULL) {
|
||||
monitoredNode->pFunctSignalRemoteReset(monitoredNode->nodeId, i,
|
||||
monitoredNode->functSignalObjectRemoteReset);
|
||||
}
|
||||
if (monitoredNode->HBstate == CO_HBconsumer_UNCONFIGURED) {
|
||||
/* continue, if node is not monitored */
|
||||
continue;
|
||||
}
|
||||
/* Verify if received message is heartbeat or bootup */
|
||||
if (CO_CANrxNew_READ(monitoredNode->CANrxNew)) {
|
||||
if (monitoredNode->NMTstate == CO_NMT_INITIALIZING) {
|
||||
/* bootup message, call callback */
|
||||
if (monitoredNode->pFunctSignalRemoteReset != NULL) {
|
||||
monitoredNode->pFunctSignalRemoteReset(
|
||||
monitoredNode->nodeId, i,
|
||||
monitoredNode->functSignalObjectRemoteReset);
|
||||
}
|
||||
else {
|
||||
/* heartbeat message */
|
||||
if (monitoredNode->HBstate!=CO_HBconsumer_ACTIVE &&
|
||||
monitoredNode->pFunctSignalHbStarted!=NULL) {
|
||||
monitoredNode->pFunctSignalHbStarted(monitoredNode->nodeId, i,
|
||||
monitoredNode->functSignalObjectHbStarted);
|
||||
}
|
||||
monitoredNode->HBstate = CO_HBconsumer_ACTIVE;
|
||||
monitoredNode->timeoutTimer = 0; /* reset timer */
|
||||
timeDifference_ms = 0;
|
||||
if (monitoredNode->HBstate == CO_HBconsumer_ACTIVE) {
|
||||
CO_errorReport(HBcons->em,
|
||||
CO_EM_HB_CONSUMER_REMOTE_RESET,
|
||||
CO_EMC_HEARTBEAT, i);
|
||||
}
|
||||
CO_CANrxNew_CLEAR(monitoredNode->CANrxNew);
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNKNOWN;
|
||||
|
||||
}
|
||||
else {
|
||||
/* heartbeat message, call callback */
|
||||
if (monitoredNode->HBstate != CO_HBconsumer_ACTIVE &&
|
||||
monitoredNode->pFunctSignalHbStarted != NULL) {
|
||||
monitoredNode->pFunctSignalHbStarted(
|
||||
monitoredNode->nodeId, i,
|
||||
monitoredNode->functSignalObjectHbStarted);
|
||||
}
|
||||
monitoredNode->HBstate = CO_HBconsumer_ACTIVE;
|
||||
/* reset timer */
|
||||
monitoredNode->timeoutTimer = 0;
|
||||
timeDifference_us_copy = 0;
|
||||
}
|
||||
CO_CANrxNew_CLEAR(monitoredNode->CANrxNew);
|
||||
}
|
||||
|
||||
/* Verify timeout */
|
||||
if (monitoredNode->HBstate == CO_HBconsumer_ACTIVE) {
|
||||
monitoredNode->timeoutTimer += timeDifference_us_copy;
|
||||
|
||||
if (monitoredNode->timeoutTimer >= monitoredNode->time_us) {
|
||||
/* timeout expired, call callback */
|
||||
if (monitoredNode->pFunctSignalTimeout!=NULL) {
|
||||
monitoredNode->pFunctSignalTimeout(
|
||||
monitoredNode->nodeId, i,
|
||||
monitoredNode->functSignalObjectTimeout);
|
||||
}
|
||||
CO_errorReport(HBcons->em, CO_EM_HEARTBEAT_CONSUMER,
|
||||
CO_EMC_HEARTBEAT, i);
|
||||
monitoredNode->NMTstate = CO_NMT_INITIALIZING;
|
||||
monitoredNode->HBstate = CO_HBconsumer_TIMEOUT;
|
||||
}
|
||||
|
||||
/* Verify timeout */
|
||||
if(monitoredNode->timeoutTimer < monitoredNode->time) {
|
||||
monitoredNode->timeoutTimer += timeDifference_ms;
|
||||
}
|
||||
if(monitoredNode->HBstate!=CO_HBconsumer_UNCONFIGURED &&
|
||||
monitoredNode->HBstate!=CO_HBconsumer_UNKNOWN) {
|
||||
if(monitoredNode->timeoutTimer >= monitoredNode->time){
|
||||
/* timeout expired */
|
||||
CO_errorReport(HBcons->em, CO_EM_HEARTBEAT_CONSUMER, CO_EMC_HEARTBEAT, i);
|
||||
emcyHeartbeatTimeoutActive = 1;
|
||||
|
||||
monitoredNode->NMTstate = CO_NMT_INITIALIZING;
|
||||
if (monitoredNode->HBstate!=CO_HBconsumer_TIMEOUT &&
|
||||
monitoredNode->pFunctSignalTimeout!=NULL) {
|
||||
monitoredNode->pFunctSignalTimeout(monitoredNode->nodeId, i,
|
||||
monitoredNode->functSignalObjectTimeout);
|
||||
}
|
||||
monitoredNode->HBstate = CO_HBconsumer_TIMEOUT;
|
||||
}
|
||||
else if(monitoredNode->NMTstate == CO_NMT_INITIALIZING){
|
||||
/* there was a bootup message */
|
||||
CO_errorReport(HBcons->em, CO_EM_HB_CONSUMER_REMOTE_RESET, CO_EMC_HEARTBEAT, i);
|
||||
emcyRemoteResetActive = 1;
|
||||
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNKNOWN;
|
||||
else if (timerNext_us != NULL) {
|
||||
/* Calculate timerNext_us for next timeout checking. */
|
||||
uint32_t diff = monitoredNode->time_us
|
||||
- monitoredNode->timeoutTimer;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
}
|
||||
if(monitoredNode->NMTstate != CO_NMT_OPERATIONAL) {
|
||||
AllMonitoredOperationalCopy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(monitoredNode->HBstate != CO_HBconsumer_ACTIVE) {
|
||||
allMonitoredActiveCurrent = false;
|
||||
}
|
||||
if (monitoredNode->NMTstate != CO_NMT_OPERATIONAL) {
|
||||
allMonitoredOperationalCurrent = CO_NMT_INITIALIZING;
|
||||
}
|
||||
monitoredNode++;
|
||||
}
|
||||
}
|
||||
else{ /* not in (pre)operational state */
|
||||
for(i=0; i<HBcons->numberOfMonitoredNodes; i++){
|
||||
else if (NMTisPreOrOperational || HBcons->NMTisPreOrOperationalPrev) {
|
||||
/* (pre)operational state changed, clear variables */
|
||||
for(i=0; i<HBcons->numberOfMonitoredNodes; i++) {
|
||||
monitoredNode->NMTstate = CO_NMT_INITIALIZING;
|
||||
CO_CANrxNew_CLEAR(monitoredNode->CANrxNew);
|
||||
if(monitoredNode->HBstate != CO_HBconsumer_UNCONFIGURED){
|
||||
if (monitoredNode->HBstate != CO_HBconsumer_UNCONFIGURED) {
|
||||
monitoredNode->HBstate = CO_HBconsumer_UNKNOWN;
|
||||
}
|
||||
monitoredNode++;
|
||||
}
|
||||
AllMonitoredOperationalCopy = 0;
|
||||
allMonitoredActiveCurrent = false;
|
||||
allMonitoredOperationalCurrent = CO_NMT_INITIALIZING;
|
||||
}
|
||||
/* clear emergencies. We only have one emergency index for all
|
||||
* monitored nodes! */
|
||||
if ( ! emcyHeartbeatTimeoutActive) {
|
||||
|
||||
/* Clear emergencies when all monitored nodes becomes active.
|
||||
* We only have one emergency index for all monitored nodes! */
|
||||
if (!HBcons->allMonitoredActive && allMonitoredActiveCurrent) {
|
||||
CO_errorReset(HBcons->em, CO_EM_HEARTBEAT_CONSUMER, 0);
|
||||
}
|
||||
if ( ! emcyRemoteResetActive) {
|
||||
CO_errorReset(HBcons->em, CO_EM_HB_CONSUMER_REMOTE_RESET, 0);
|
||||
}
|
||||
|
||||
HBcons->allMonitoredOperational = AllMonitoredOperationalCopy;
|
||||
HBcons->allMonitoredActive = allMonitoredActiveCurrent;
|
||||
HBcons->allMonitoredOperational = allMonitoredOperationalCurrent;
|
||||
HBcons->NMTisPreOrOperationalPrev = NMTisPreOrOperational;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ typedef struct{
|
|||
uint8_t nodeId; /**< Node Id of the monitored node */
|
||||
CO_NMT_internalState_t NMTstate; /**< Of the remote node (Heartbeat payload) */
|
||||
CO_HBconsumer_state_t HBstate; /**< Current heartbeat state */
|
||||
uint16_t timeoutTimer; /**< Time since last heartbeat received */
|
||||
uint16_t time; /**< Consumer heartbeat time from OD */
|
||||
uint32_t timeoutTimer; /**< Time since last heartbeat received */
|
||||
uint32_t time_us; /**< Consumer heartbeat time from OD */
|
||||
volatile void *CANrxNew; /**< Indication if new Heartbeat message received from the CAN bus */
|
||||
/** Callback for heartbeat state change to active event */
|
||||
void (*pFunctSignalHbStarted)(uint8_t nodeId, uint8_t idx, void *object); /**< From CO_HBconsumer_initTimeoutCallback() or NULL */
|
||||
|
|
@ -94,9 +94,13 @@ typedef struct{
|
|||
const uint32_t *HBconsTime; /**< From CO_HBconsumer_init() */
|
||||
CO_HBconsNode_t *monitoredNodes; /**< From CO_HBconsumer_init() */
|
||||
uint8_t numberOfMonitoredNodes; /**< From CO_HBconsumer_init() */
|
||||
/** True, if all monitored nodes are active or no node is
|
||||
monitored. Can be read by the application */
|
||||
bool_t allMonitoredActive;
|
||||
/** True, if all monitored nodes are NMT operational or no node is
|
||||
monitored. Can be read by the application */
|
||||
uint8_t allMonitoredOperational;
|
||||
bool_t NMTisPreOrOperationalPrev; /**< previous state of var */
|
||||
CO_CANmodule_t *CANdevRx; /**< From CO_HBconsumer_init() */
|
||||
uint16_t CANdevRxIdxStart; /**< From CO_HBconsumer_init() */
|
||||
}CO_HBconsumer_t;
|
||||
|
|
@ -142,14 +146,14 @@ CO_ReturnError_t CO_HBconsumer_init(
|
|||
* @param HBcons This object.
|
||||
* @param idx index of the node in HBcons object
|
||||
* @param nodeId see OD 0x1016 description
|
||||
* @param consumerTime see OD 0x1016 description
|
||||
* @param consumerTime in milliseconds. see OD 0x1016 description
|
||||
* @return
|
||||
*/
|
||||
CO_ReturnError_t CO_HBconsumer_initEntry(
|
||||
CO_HBconsumer_t *HBcons,
|
||||
uint8_t idx,
|
||||
uint8_t nodeId,
|
||||
uint16_t consumerTime);
|
||||
uint16_t consumerTime_ms);
|
||||
|
||||
/**
|
||||
* Initialize Heartbeat consumer started callback function.
|
||||
|
|
@ -213,12 +217,14 @@ void CO_HBconsumer_initCallbackRemoteReset(
|
|||
*
|
||||
* @param HBcons This object.
|
||||
* @param NMTisPreOrOperational True if this node is NMT_PRE_OPERATIONAL or NMT_OPERATIONAL.
|
||||
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param timerNext_us [out] info to OS - see CO_process().
|
||||
*/
|
||||
void CO_HBconsumer_process(
|
||||
CO_HBconsumer_t *HBcons,
|
||||
bool_t NMTisPreOrOperational,
|
||||
uint16_t timeDifference_ms);
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
/**
|
||||
* Get the heartbeat producer object index by node ID
|
||||
|
|
|
|||
|
|
@ -112,12 +112,12 @@ static void CO_LSSmaster_receive(void *object, void *msg)
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_check_timeout(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms)
|
||||
uint32_t timeDifference_us)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_WAIT_SLAVE;
|
||||
|
||||
LSSmaster->timeoutTimer += timeDifference_ms;
|
||||
if (LSSmaster->timeoutTimer >= LSSmaster->timeout) {
|
||||
LSSmaster->timeoutTimer += timeDifference_us;
|
||||
if (LSSmaster->timeoutTimer >= LSSmaster->timeout_us) {
|
||||
LSSmaster->timeoutTimer = 0;
|
||||
ret = CO_LSSmaster_TIMEOUT;
|
||||
}
|
||||
|
|
@ -142,7 +142,7 @@ CO_ReturnError_t CO_LSSmaster_init(
|
|||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
LSSmaster->timeout = timeout_ms;
|
||||
LSSmaster->timeout_us = (uint32_t)timeout_ms * 1000;
|
||||
LSSmaster->state = CO_LSSmaster_STATE_WAITING;
|
||||
LSSmaster->command = CO_LSSmaster_COMMAND_WAITING;
|
||||
LSSmaster->timeoutTimer = 0;
|
||||
|
|
@ -181,7 +181,7 @@ void CO_LSSmaster_changeTimeout(
|
|||
uint16_t timeout_ms)
|
||||
{
|
||||
if (LSSmaster != NULL) {
|
||||
LSSmaster->timeout = timeout_ms;
|
||||
LSSmaster->timeout_us = (uint32_t)timeout_ms * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,7 +251,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_switchStateSelectInitiate(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_switchStateSelectWait(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms)
|
||||
uint32_t timeDifference_us)
|
||||
{
|
||||
CO_LSSmaster_return_t ret;
|
||||
|
||||
|
|
@ -264,11 +264,11 @@ static CO_LSSmaster_return_t CO_LSSmaster_switchStateSelectWait(
|
|||
ret = CO_LSSmaster_OK;
|
||||
}
|
||||
else {
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -277,7 +277,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_switchStateSelectWait(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_switchStateSelect(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSS_address_t *lssAddress)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_INVALID_STATE;
|
||||
|
|
@ -294,7 +294,7 @@ CO_LSSmaster_return_t CO_LSSmaster_switchStateSelect(
|
|||
}
|
||||
/* Wait for confirmation */
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_SWITCH_STATE) {
|
||||
ret = CO_LSSmaster_switchStateSelectWait(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_switchStateSelectWait(LSSmaster, timeDifference_us);
|
||||
}
|
||||
|
||||
if (ret!=CO_LSSmaster_INVALID_STATE && ret!=CO_LSSmaster_WAIT_SLAVE) {
|
||||
|
|
@ -360,7 +360,7 @@ CO_LSSmaster_return_t CO_LSSmaster_switchStateDeselect(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_configureCheckWait(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint8_t csWait)
|
||||
{
|
||||
CO_LSSmaster_return_t ret;
|
||||
|
|
@ -382,11 +382,11 @@ static CO_LSSmaster_return_t CO_LSSmaster_configureCheckWait(
|
|||
}
|
||||
}
|
||||
else {
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
}
|
||||
|
||||
if (ret!=CO_LSSmaster_INVALID_STATE && ret!=CO_LSSmaster_WAIT_SLAVE) {
|
||||
|
|
@ -400,7 +400,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_configureCheckWait(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint16_t bit)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_INVALID_STATE;
|
||||
|
|
@ -442,7 +442,7 @@ CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
|
|||
/* Wait for confirmation */
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_CFG_BIT_TIMING) {
|
||||
|
||||
ret = CO_LSSmaster_configureCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_configureCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_CFG_BIT_TIMING);
|
||||
}
|
||||
|
||||
|
|
@ -457,7 +457,7 @@ CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_configureNodeId(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint8_t nodeId)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_INVALID_STATE;
|
||||
|
|
@ -487,7 +487,7 @@ CO_LSSmaster_return_t CO_LSSmaster_configureNodeId(
|
|||
/* Wait for confirmation */
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_CFG_NODE_ID) {
|
||||
|
||||
ret = CO_LSSmaster_configureCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_configureCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_CFG_NODE_ID);
|
||||
}
|
||||
|
||||
|
|
@ -502,7 +502,7 @@ CO_LSSmaster_return_t CO_LSSmaster_configureNodeId(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_configureStore(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms)
|
||||
uint32_t timeDifference_us)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_INVALID_STATE;
|
||||
|
||||
|
|
@ -527,7 +527,7 @@ CO_LSSmaster_return_t CO_LSSmaster_configureStore(
|
|||
/* Wait for confirmation */
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_CFG_STORE) {
|
||||
|
||||
ret = CO_LSSmaster_configureCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_configureCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_CFG_STORE);
|
||||
}
|
||||
|
||||
|
|
@ -588,7 +588,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_inquireInitiate(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_inquireCheckWait(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint8_t csWait,
|
||||
uint32_t *value)
|
||||
{
|
||||
|
|
@ -603,11 +603,11 @@ static CO_LSSmaster_return_t CO_LSSmaster_inquireCheckWait(
|
|||
ret = CO_LSSmaster_OK;
|
||||
}
|
||||
else {
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -616,7 +616,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_inquireCheckWait(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSS_address_t *lssAddress)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_INVALID_STATE;
|
||||
|
|
@ -629,7 +629,7 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
|||
/* Check for reply */
|
||||
if (LSSmaster->command == CO_LSSmaster_COMMAND_INQUIRE_VENDOR) {
|
||||
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_INQUIRE_VENDOR, &lssAddress->identity.vendorID);
|
||||
if (ret == CO_LSSmaster_OK) {
|
||||
/* Start next request */
|
||||
|
|
@ -639,7 +639,7 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
|||
}
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_INQUIRE_PRODUCT) {
|
||||
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_INQUIRE_PRODUCT, &lssAddress->identity.productCode);
|
||||
if (ret == CO_LSSmaster_OK) {
|
||||
/* Start next request */
|
||||
|
|
@ -649,7 +649,7 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
|||
}
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_INQUIRE_REV) {
|
||||
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_INQUIRE_REV, &lssAddress->identity.revisionNumber);
|
||||
if (ret == CO_LSSmaster_OK) {
|
||||
/* Start next request */
|
||||
|
|
@ -659,7 +659,7 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
|||
}
|
||||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_INQUIRE_SERIAL) {
|
||||
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_INQUIRE_SERIAL, &lssAddress->identity.serialNumber);
|
||||
}
|
||||
/* Check for next request */
|
||||
|
|
@ -703,7 +703,7 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_InquireNodeId(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint8_t *nodeId)
|
||||
{
|
||||
CO_LSSmaster_return_t ret = CO_LSSmaster_INVALID_STATE;
|
||||
|
|
@ -726,7 +726,7 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireNodeId(
|
|||
else if (LSSmaster->command == CO_LSSmaster_COMMAND_INQUIRE_NODE_ID) {
|
||||
uint32_t tmp = 0;
|
||||
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_inquireCheckWait(LSSmaster, timeDifference_us,
|
||||
CO_LSS_INQUIRE_NODE_ID, &tmp);
|
||||
|
||||
*nodeId = tmp & 0xff;
|
||||
|
|
@ -765,11 +765,11 @@ static void CO_LSSmaster_FsSendMsg(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_FsCheckWait(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms)
|
||||
uint32_t timeDifference_us)
|
||||
{
|
||||
CO_LSSmaster_return_t ret;
|
||||
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
if (ret == CO_LSSmaster_TIMEOUT) {
|
||||
ret = CO_LSSmaster_SCAN_NOACK;
|
||||
|
||||
|
|
@ -792,7 +792,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_FsCheckWait(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_FsScanInitiate(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSSmaster_scantype_t scan,
|
||||
CO_LSS_fastscan_lss_sub_next lssSub)
|
||||
{
|
||||
|
|
@ -824,7 +824,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_FsScanInitiate(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_FsScanWait(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSSmaster_scantype_t scan)
|
||||
{
|
||||
CO_LSSmaster_return_t ret;
|
||||
|
|
@ -840,7 +840,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_FsScanWait(
|
|||
return CO_LSSmaster_SCAN_FAILED;
|
||||
}
|
||||
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
if (ret == CO_LSSmaster_TIMEOUT) {
|
||||
|
||||
ret = CO_LSSmaster_WAIT_SLAVE;
|
||||
|
|
@ -880,7 +880,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_FsScanWait(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_FsVerifyInitiate(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSSmaster_scantype_t scan,
|
||||
uint32_t idNumberCheck,
|
||||
CO_LSS_fastscan_lss_sub_next lssNext)
|
||||
|
|
@ -913,7 +913,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_FsVerifyInitiate(
|
|||
*/
|
||||
static CO_LSSmaster_return_t CO_LSSmaster_FsVerifyWait(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSSmaster_scantype_t scan,
|
||||
uint32_t *idNumberRet)
|
||||
{
|
||||
|
|
@ -923,7 +923,7 @@ static CO_LSSmaster_return_t CO_LSSmaster_FsVerifyWait(
|
|||
return CO_LSSmaster_SCAN_FAILED;
|
||||
}
|
||||
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_check_timeout(LSSmaster, timeDifference_us);
|
||||
if (ret == CO_LSSmaster_TIMEOUT) {
|
||||
|
||||
*idNumberRet = 0;
|
||||
|
|
@ -970,7 +970,7 @@ static CO_LSS_fastscan_lss_sub_next CO_LSSmaster_FsSearchNext(
|
|||
/******************************************************************************/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSSmaster_fastscan_t *fastscan)
|
||||
{
|
||||
uint8_t i;
|
||||
|
|
@ -1036,12 +1036,12 @@ CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
|
|||
* and the correspondign error is returned. */
|
||||
switch (LSSmaster->fsState) {
|
||||
case CO_LSSmaster_FS_STATE_CHECK:
|
||||
ret = CO_LSSmaster_FsCheckWait(LSSmaster, timeDifference_ms);
|
||||
ret = CO_LSSmaster_FsCheckWait(LSSmaster, timeDifference_us);
|
||||
if (ret == CO_LSSmaster_SCAN_FINISHED) {
|
||||
CO_memset((uint8_t*)&fastscan->found, 0, sizeof(fastscan->found));
|
||||
|
||||
/* start scanning procedure by triggering vendor ID scan */
|
||||
CO_LSSmaster_FsScanInitiate(LSSmaster, timeDifference_ms,
|
||||
CO_LSSmaster_FsScanInitiate(LSSmaster, timeDifference_us,
|
||||
fastscan->scan[CO_LSS_FASTSCAN_VENDOR_ID],
|
||||
CO_LSS_FASTSCAN_VENDOR_ID);
|
||||
ret = CO_LSSmaster_WAIT_SLAVE;
|
||||
|
|
@ -1050,14 +1050,14 @@ CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
|
|||
}
|
||||
break;
|
||||
case CO_LSSmaster_FS_STATE_SCAN:
|
||||
ret = CO_LSSmaster_FsScanWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_FsScanWait(LSSmaster, timeDifference_us,
|
||||
fastscan->scan[LSSmaster->fsLssSub]);
|
||||
if (ret == CO_LSSmaster_SCAN_FINISHED) {
|
||||
/* scanning finished, initiate verifcation. The verification
|
||||
* message also contains the node state machine "switch to
|
||||
* next state" request */
|
||||
next = CO_LSSmaster_FsSearchNext(LSSmaster, fastscan);
|
||||
ret = CO_LSSmaster_FsVerifyInitiate(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_FsVerifyInitiate(LSSmaster, timeDifference_us,
|
||||
fastscan->scan[LSSmaster->fsLssSub],
|
||||
fastscan->match.addr[LSSmaster->fsLssSub], next);
|
||||
|
||||
|
|
@ -1065,7 +1065,7 @@ CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
|
|||
}
|
||||
break;
|
||||
case CO_LSSmaster_FS_STATE_VERIFY:
|
||||
ret = CO_LSSmaster_FsVerifyWait(LSSmaster, timeDifference_ms,
|
||||
ret = CO_LSSmaster_FsVerifyWait(LSSmaster, timeDifference_us,
|
||||
fastscan->scan[LSSmaster->fsLssSub],
|
||||
&fastscan->found.addr[LSSmaster->fsLssSub]);
|
||||
if (ret == CO_LSSmaster_SCAN_FINISHED) {
|
||||
|
|
@ -1082,7 +1082,7 @@ CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
|
|||
else {
|
||||
/* initiate scan for next part of LSS address */
|
||||
ret = CO_LSSmaster_FsScanInitiate(LSSmaster,
|
||||
timeDifference_ms, fastscan->scan[next], next);
|
||||
timeDifference_us, fastscan->scan[next], next);
|
||||
if (ret == CO_LSSmaster_SCAN_FINISHED) {
|
||||
/* Scanning is not requested. Initiate verification
|
||||
* step in next function call */
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ typedef enum {
|
|||
* LSS master object.
|
||||
*/
|
||||
typedef struct{
|
||||
uint16_t timeout; /**< LSS response timeout in ms */
|
||||
uint16_t timeout_us; /**< LSS response timeout in us */
|
||||
|
||||
uint8_t state; /**< Node is currently selected */
|
||||
uint8_t command; /**< Active command */
|
||||
uint16_t timeoutTimer; /**< Timeout timer for LSS communication */
|
||||
uint32_t timeoutTimer; /**< Timeout timer for LSS communication */
|
||||
|
||||
uint8_t fsState; /**< Current state of fastscan master state machine */
|
||||
uint8_t fsLssSub; /**< Current state of node state machine */
|
||||
|
|
@ -212,15 +212,15 @@ void CO_LSSmaster_initCallback(
|
|||
* @remark Only one selection can be active at any time.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @param lssAddress LSS target address. If NULL, all nodes are selected
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
* #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT
|
||||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_switchStateSelect(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSS_address_t *lssAddress);
|
||||
|
||||
|
||||
|
|
@ -251,8 +251,8 @@ CO_LSSmaster_return_t CO_LSSmaster_switchStateDeselect(
|
|||
* Function is non-blocking.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @param bit new bit rate
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
* #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT,
|
||||
|
|
@ -260,7 +260,7 @@ CO_LSSmaster_return_t CO_LSSmaster_switchStateDeselect(
|
|||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint16_t bit);
|
||||
|
||||
|
||||
|
|
@ -275,8 +275,8 @@ CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
|
|||
* Function is non-blocking.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @param nodeId new node ID. Special value #CO_LSS_NODE_ID_ASSIGNMENT can be
|
||||
* used to invalidate node ID.
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
|
|
@ -285,7 +285,7 @@ CO_LSSmaster_return_t CO_LSSmaster_configureBitTiming(
|
|||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_configureNodeId(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint8_t nodeId);
|
||||
|
||||
|
||||
|
|
@ -301,15 +301,15 @@ CO_LSSmaster_return_t CO_LSSmaster_configureNodeId(
|
|||
* Function is non-blocking.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
* #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT,
|
||||
* #CO_LSSmaster_OK_MANUFACTURER, #CO_LSSmaster_OK_ILLEGAL_ARGUMENT
|
||||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_configureStore(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms);
|
||||
uint32_t timeDifference_us);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -348,15 +348,15 @@ CO_LSSmaster_return_t CO_LSSmaster_ActivateBit(
|
|||
* Function is non-blocking.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @param lssAddress [out] read result when function returns successfully
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
* #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT
|
||||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSS_address_t *lssAddress);
|
||||
|
||||
|
||||
|
|
@ -371,15 +371,15 @@ CO_LSSmaster_return_t CO_LSSmaster_InquireLssAddress(
|
|||
* Function is non-blocking.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @param nodeId [out] read result when function returns successfully
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
* #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_OK, #CO_LSSmaster_TIMEOUT
|
||||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_InquireNodeId(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
uint8_t *nodeId);
|
||||
|
||||
|
||||
|
|
@ -448,8 +448,8 @@ fastscan.scan[CO_LSS_FASTSCAN_SERIAL] = CO_LSSmaster_FS_SCAN;
|
|||
* Function is non-blocking.
|
||||
*
|
||||
* @param LSSmaster This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in
|
||||
* [milliseconds]. Zero when request is started.
|
||||
* @param timeDifference_us Time difference from previous function call in
|
||||
* [microseconds]. Zero when request is started.
|
||||
* @param fastscan struct according to #CO_LSSmaster_fastscan_t.
|
||||
* @return #CO_LSSmaster_ILLEGAL_ARGUMENT, #CO_LSSmaster_INVALID_STATE,
|
||||
* #CO_LSSmaster_WAIT_SLAVE, #CO_LSSmaster_SCAN_FINISHED, #CO_LSSmaster_SCAN_NOACK,
|
||||
|
|
@ -457,7 +457,7 @@ fastscan.scan[CO_LSS_FASTSCAN_SERIAL] = CO_LSSmaster_FS_SCAN;
|
|||
*/
|
||||
CO_LSSmaster_return_t CO_LSSmaster_IdentifyFastscan(
|
||||
CO_LSSmaster_t *LSSmaster,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
CO_LSSmaster_fastscan_t *fastscan);
|
||||
|
||||
/** @} */ /*@defgroup CO_LSSmaster*/
|
||||
|
|
|
|||
|
|
@ -498,17 +498,17 @@ CO_LSS_state_t CO_LSSslave_getState(
|
|||
/******************************************************************************/
|
||||
bool_t CO_LSSslave_LEDprocess(
|
||||
CO_LSSslave_t *LSSslave,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
bool_t *LEDon)
|
||||
{
|
||||
static uint16_t ms50 = 0;
|
||||
static uint32_t ms50 = 0;
|
||||
static int8_t flash1, flash2;
|
||||
|
||||
if (LSSslave == NULL || LEDon == NULL)
|
||||
return false;
|
||||
ms50 += timeDifference_ms;
|
||||
if(ms50 >= 50) {
|
||||
ms50 -= 50;
|
||||
ms50 += timeDifference_us;
|
||||
if(ms50 >= 50000) {
|
||||
ms50 -= 50000;
|
||||
/* 4 cycles on, 50 cycles off */
|
||||
if(++flash1 >= 4) flash1 = -50;
|
||||
|
||||
|
|
|
|||
|
|
@ -332,14 +332,14 @@ CO_LSS_state_t CO_LSSslave_getState(
|
|||
* If none of above conditions apply, returns false.
|
||||
*
|
||||
* @param LSSslave This object.
|
||||
* @param timeDifference_ms The amount of time elapsed since the last call
|
||||
* @param timeDifference_us The amount of time elapsed since the last call
|
||||
* @param LEDon [out] LED state
|
||||
*
|
||||
* @return true if LSS is involved (unconfigured node or selected node)
|
||||
*/
|
||||
bool_t CO_LSSslave_LEDprocess(
|
||||
CO_LSSslave_t *LSSslave,
|
||||
uint16_t timeDifference_ms,
|
||||
uint32_t timeDifference_us,
|
||||
bool_t *LEDon);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ CO_ReturnError_t CO_NMT_init(
|
|||
CO_NMT_t *NMT,
|
||||
CO_EMpr_t *emPr,
|
||||
uint8_t nodeId,
|
||||
uint16_t firstHBTime,
|
||||
uint16_t firstHBTime_ms,
|
||||
CO_CANmodule_t *NMT_CANdev,
|
||||
uint16_t NMT_rxIdx,
|
||||
uint16_t CANidRxNMT,
|
||||
|
|
@ -97,26 +97,25 @@ CO_ReturnError_t CO_NMT_init(
|
|||
return CO_ERROR_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
|
||||
/* blinking bytes */
|
||||
/* blinking bytes and LEDS */
|
||||
#ifdef CO_USE_LEDS
|
||||
NMT->LEDtimer = 0;
|
||||
NMT->LEDflickering = 0;
|
||||
NMT->LEDblinking = 0;
|
||||
NMT->LEDsingleFlash = 0;
|
||||
NMT->LEDdoubleFlash = 0;
|
||||
NMT->LEDtripleFlash = 0;
|
||||
NMT->LEDquadrupleFlash = 0;
|
||||
NMT->LEDgreenRun = -1;
|
||||
NMT->LEDredError = 1;
|
||||
#endif /* CO_USE_LEDS */
|
||||
|
||||
/* Configure object variables */
|
||||
NMT->operatingState = CO_NMT_INITIALIZING;
|
||||
#ifdef CO_USE_LEDS
|
||||
NMT->LEDgreenRun = -1;
|
||||
NMT->LEDredError = 1;
|
||||
#endif /* CO_USE_LEDS */
|
||||
NMT->nodeId = nodeId;
|
||||
NMT->firstHBTime = firstHBTime;
|
||||
NMT->firstHBTime = (int32_t)firstHBTime_ms * 1000;
|
||||
NMT->resetCommand = 0;
|
||||
NMT->HBproducerTimer = 0xFFFF;
|
||||
NMT->HBproducerTimer = 0;
|
||||
NMT->emPr = emPr;
|
||||
NMT->pFunctNMT = NULL;
|
||||
|
||||
|
|
@ -158,64 +157,25 @@ void CO_NMT_initCallback(
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
#ifdef CO_USE_LEDS
|
||||
void CO_NMT_blinkingProcess50ms(CO_NMT_t *NMT){
|
||||
|
||||
if(++NMT->LEDflickering >= 1) NMT->LEDflickering = -1;
|
||||
|
||||
if(++NMT->LEDblinking >= 4) NMT->LEDblinking = -4;
|
||||
|
||||
if(++NMT->LEDsingleFlash >= 4) NMT->LEDsingleFlash = -20;
|
||||
|
||||
switch(++NMT->LEDdoubleFlash){
|
||||
case 4: NMT->LEDdoubleFlash = -104; break;
|
||||
case -100: NMT->LEDdoubleFlash = 100; break;
|
||||
case 104: NMT->LEDdoubleFlash = -20; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(++NMT->LEDtripleFlash){
|
||||
case 4: NMT->LEDtripleFlash = -104; break;
|
||||
case -100: NMT->LEDtripleFlash = 100; break;
|
||||
case 104: NMT->LEDtripleFlash = -114; break;
|
||||
case -110: NMT->LEDtripleFlash = 110; break;
|
||||
case 114: NMT->LEDtripleFlash = -20; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch(++NMT->LEDquadrupleFlash){
|
||||
case 4: NMT->LEDquadrupleFlash = -104; break;
|
||||
case -100: NMT->LEDquadrupleFlash = 100; break;
|
||||
case 104: NMT->LEDquadrupleFlash = -114; break;
|
||||
case -110: NMT->LEDquadrupleFlash = 110; break;
|
||||
case 114: NMT->LEDquadrupleFlash = -124; break;
|
||||
case -120: NMT->LEDquadrupleFlash = 120; break;
|
||||
case 124: NMT->LEDquadrupleFlash = -20; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif /* CO_USE_LEDS */
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
CO_NMT_reset_cmd_t CO_NMT_process(
|
||||
CO_NMT_t *NMT,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t HBtime,
|
||||
uint32_t timeDifference_us,
|
||||
uint16_t HBtime_ms,
|
||||
uint32_t NMTstartup,
|
||||
uint8_t errorRegister,
|
||||
const uint8_t errorBehavior[],
|
||||
uint16_t *timerNext_ms)
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
uint8_t CANpassive;
|
||||
|
||||
uint8_t currentOperatingState = NMT->operatingState;
|
||||
uint32_t HBtime = (uint32_t)HBtime_ms * 1000;
|
||||
|
||||
NMT->HBproducerTimer += timeDifference_ms;
|
||||
NMT->HBproducerTimer += timeDifference_us;
|
||||
|
||||
/* Heartbeat producer message & Bootup message */
|
||||
if((HBtime != 0 && NMT->HBproducerTimer >= HBtime) || NMT->operatingState == CO_NMT_INITIALIZING){
|
||||
if ((HBtime != 0 && NMT->HBproducerTimer >= HBtime) || NMT->operatingState == CO_NMT_INITIALIZING) {
|
||||
|
||||
/* Start from the beginning. If OS is slow, time sliding may occur. However, heartbeat is
|
||||
* not for synchronization, it is for health report. */
|
||||
|
|
@ -224,10 +184,12 @@ CO_NMT_reset_cmd_t CO_NMT_process(
|
|||
NMT->HB_TXbuff->data[0] = NMT->operatingState;
|
||||
CO_CANsend(NMT->HB_CANdev, NMT->HB_TXbuff);
|
||||
|
||||
if(NMT->operatingState == CO_NMT_INITIALIZING){
|
||||
if(HBtime > NMT->firstHBTime) NMT->HBproducerTimer = HBtime - NMT->firstHBTime;
|
||||
else NMT->HBproducerTimer = 0;
|
||||
|
||||
if (NMT->operatingState == CO_NMT_INITIALIZING) {
|
||||
/* After bootup messages send first heartbeat earlier */
|
||||
if (HBtime > NMT->firstHBTime) {
|
||||
NMT->HBproducerTimer = HBtime - NMT->firstHBTime;
|
||||
}
|
||||
|
||||
/* NMT slave self starting */
|
||||
if (NMTstartup == 0x00000008U) NMT->operatingState = CO_NMT_OPERATIONAL;
|
||||
else NMT->operatingState = CO_NMT_PRE_OPERATIONAL;
|
||||
|
|
@ -235,19 +197,6 @@ CO_NMT_reset_cmd_t CO_NMT_process(
|
|||
}
|
||||
|
||||
|
||||
/* Calculate, when next Heartbeat needs to be send and lower timerNext_ms if necessary. */
|
||||
if(HBtime != 0 && timerNext_ms != NULL){
|
||||
if(NMT->HBproducerTimer < HBtime){
|
||||
uint16_t diff = HBtime - NMT->HBproducerTimer;
|
||||
if(*timerNext_ms > diff){
|
||||
*timerNext_ms = diff;
|
||||
}
|
||||
}else{
|
||||
*timerNext_ms = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* CAN passive flag */
|
||||
CANpassive = 0;
|
||||
if(CO_isError(NMT->emPr->em, CO_EM_CAN_TX_BUS_PASSIVE) || CO_isError(NMT->emPr->em, CO_EM_CAN_RX_BUS_PASSIVE))
|
||||
|
|
@ -255,6 +204,51 @@ CO_NMT_reset_cmd_t CO_NMT_process(
|
|||
|
||||
|
||||
#ifdef CO_USE_LEDS
|
||||
NMT->LEDtimer += timeDifference_us;
|
||||
if (NMT->LEDtimer >= 50000) {
|
||||
NMT->LEDtimer -= 50000;
|
||||
|
||||
if (timerNext_us != NULL) {
|
||||
uint32_t diff = 50000 - NMT->LEDtimer;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
}
|
||||
|
||||
if (++NMT->LEDflickering >= 1) NMT->LEDflickering = -1;
|
||||
|
||||
if (++NMT->LEDblinking >= 4) NMT->LEDblinking = -4;
|
||||
|
||||
if (++NMT->LEDsingleFlash >= 4) NMT->LEDsingleFlash = -20;
|
||||
|
||||
switch (++NMT->LEDdoubleFlash) {
|
||||
case 4: NMT->LEDdoubleFlash = -104; break;
|
||||
case -100: NMT->LEDdoubleFlash = 100; break;
|
||||
case 104: NMT->LEDdoubleFlash = -20; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (++NMT->LEDtripleFlash) {
|
||||
case 4: NMT->LEDtripleFlash = -104; break;
|
||||
case -100: NMT->LEDtripleFlash = 100; break;
|
||||
case 104: NMT->LEDtripleFlash = -114; break;
|
||||
case -110: NMT->LEDtripleFlash = 110; break;
|
||||
case 114: NMT->LEDtripleFlash = -20; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
switch (++NMT->LEDquadrupleFlash) {
|
||||
case 4: NMT->LEDquadrupleFlash = -104; break;
|
||||
case -100: NMT->LEDquadrupleFlash = 100; break;
|
||||
case 104: NMT->LEDquadrupleFlash = -114; break;
|
||||
case -110: NMT->LEDquadrupleFlash = 110; break;
|
||||
case 114: NMT->LEDquadrupleFlash = -124; break;
|
||||
case -120: NMT->LEDquadrupleFlash = 120; break;
|
||||
case 124: NMT->LEDquadrupleFlash = -20; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* CANopen green RUN LED (DR 303-3) */
|
||||
switch(NMT->operatingState){
|
||||
case CO_NMT_STOPPED: NMT->LEDgreenRun = NMT->LEDsingleFlash; break;
|
||||
|
|
@ -335,8 +329,26 @@ CO_NMT_reset_cmd_t CO_NMT_process(
|
|||
}
|
||||
}
|
||||
|
||||
if(NMT->pFunctNMT!=NULL && currentOperatingState!=NMT->operatingState){
|
||||
NMT->pFunctNMT((CO_NMT_internalState_t) NMT->operatingState);
|
||||
if (currentOperatingState != NMT->operatingState) {
|
||||
if (NMT->pFunctNMT != NULL) {
|
||||
NMT->pFunctNMT((CO_NMT_internalState_t) NMT->operatingState);
|
||||
}
|
||||
/* execute next CANopen processing immediately */
|
||||
if (timerNext_us != NULL) {
|
||||
*timerNext_us = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate, when next Heartbeat needs to be send and lower timerNext_us if necessary. */
|
||||
if (HBtime != 0 && timerNext_us != NULL) {
|
||||
if (NMT->HBproducerTimer < HBtime) {
|
||||
uint32_t diff = HBtime - NMT->HBproducerTimer;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
} else {
|
||||
*timerNext_us = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (CO_NMT_reset_cmd_t) NMT->resetCommand;
|
||||
|
|
@ -352,4 +364,3 @@ CO_NMT_internalState_t CO_NMT_getInternalState(
|
|||
}
|
||||
return CO_NMT_INITIALIZING;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ typedef enum{
|
|||
* @ref CO_NMT_statusLEDdiodes. Object is initialized by CO_NMT_init().
|
||||
*/
|
||||
typedef struct{
|
||||
uint8_t operatingState; /**< See @ref CO_NMT_internalState_t */
|
||||
#ifdef CO_USE_LEDS
|
||||
uint32_t LEDtimer; /**< 50ms led timer */
|
||||
int8_t LEDflickering; /**< See @ref CO_NMT_statusLEDdiodes */
|
||||
int8_t LEDblinking; /**< See @ref CO_NMT_statusLEDdiodes */
|
||||
int8_t LEDsingleFlash; /**< See @ref CO_NMT_statusLEDdiodes */
|
||||
|
|
@ -141,10 +141,11 @@ typedef struct{
|
|||
int8_t LEDredError; /**< See @ref CO_NMT_statusLEDdiodes */
|
||||
#endif /* CO_USE_LEDS */
|
||||
|
||||
uint8_t operatingState; /**< See @ref CO_NMT_internalState_t */
|
||||
uint8_t resetCommand; /**< If different than zero, device will reset */
|
||||
uint8_t nodeId; /**< CANopen Node ID of this device */
|
||||
uint16_t HBproducerTimer;/**< Internal timer for HB producer */
|
||||
uint16_t firstHBTime; /**< From CO_NMT_init() */
|
||||
uint32_t HBproducerTimer;/**< Internal timer for HB producer */
|
||||
uint32_t firstHBTime; /**< From CO_NMT_init() */
|
||||
CO_EMpr_t *emPr; /**< From CO_NMT_init() */
|
||||
CO_CANmodule_t *HB_CANdev; /**< From CO_NMT_init() */
|
||||
void (*pFunctNMT)(CO_NMT_internalState_t state); /**< From CO_NMT_initCallback() or NULL */
|
||||
|
|
@ -176,7 +177,7 @@ CO_ReturnError_t CO_NMT_init(
|
|||
CO_NMT_t *NMT,
|
||||
CO_EMpr_t *emPr,
|
||||
uint8_t nodeId,
|
||||
uint16_t firstHBTime,
|
||||
uint16_t firstHBTime_ms,
|
||||
CO_CANmodule_t *NMT_CANdev,
|
||||
uint16_t NMT_rxIdx,
|
||||
uint16_t CANidRxNMT,
|
||||
|
|
@ -203,43 +204,31 @@ void CO_NMT_initCallback(
|
|||
void (*pFunctNMT)(CO_NMT_internalState_t state));
|
||||
|
||||
|
||||
/**
|
||||
* Calculate blinking bytes.
|
||||
*
|
||||
* Function must be called cyclically every 50 milliseconds. See @ref CO_NMT_statusLEDdiodes.
|
||||
*
|
||||
* @param NMT NMT object.
|
||||
*/
|
||||
#ifdef CO_USE_LEDS
|
||||
void CO_NMT_blinkingProcess50ms(CO_NMT_t *NMT);
|
||||
#endif /* CO_USE_LEDS */
|
||||
|
||||
|
||||
/**
|
||||
* Process received NMT and produce Heartbeat messages.
|
||||
*
|
||||
* Function must be called cyclically.
|
||||
*
|
||||
* @param NMT This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param HBtime _Producer Heartbeat time_ (object dictionary, index 0x1017).
|
||||
* @param NMTstartup _NMT startup behavior_ (object dictionary, index 0x1F80).
|
||||
* @param errorRegister _Error register_ (object dictionary, index 0x1001).
|
||||
* @param errorBehavior pointer to _Error behavior_ array (object dictionary, index 0x1029).
|
||||
* Object controls, if device should leave NMT operational state.
|
||||
* Length of array must be 6. If pointer is NULL, no calculation is made.
|
||||
* @param timerNext_ms Return value - info to OS - see CO_process().
|
||||
* @param timerNext_us [out] info to OS - see CO_process().
|
||||
*
|
||||
* @return #CO_NMT_reset_cmd_t
|
||||
*/
|
||||
CO_NMT_reset_cmd_t CO_NMT_process(
|
||||
CO_NMT_t *NMT,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t HBtime,
|
||||
uint32_t timeDifference_us,
|
||||
uint16_t HBtime_ms,
|
||||
uint32_t NMTstartup,
|
||||
uint8_t errorRegister,
|
||||
const uint8_t errorBehavior[],
|
||||
uint16_t *timerNext_ms);
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ void CO_RPDO_process(CO_RPDO_t *RPDO, bool_t syncWas);
|
|||
* @param TPDO This object.
|
||||
* @param syncWas True, if CANopen SYNC message was just received or transmitted.
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param timerNext_us Return value - info to OS - see CO_process_SYNC_PDO().
|
||||
* @param timerNext_us [out] info to OS - see CO_process_SYNC_PDO().
|
||||
*/
|
||||
void CO_TPDO_process(
|
||||
CO_TPDO_t *TPDO,
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ CO_ReturnError_t CO_SDO_init(
|
|||
uint16_t ODSize,
|
||||
CO_OD_extension_t *ODExtensions,
|
||||
uint8_t nodeId,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
uint16_t CANdevRxIdx,
|
||||
CO_CANmodule_t *CANdevTx,
|
||||
|
|
@ -317,6 +318,7 @@ CO_ReturnError_t CO_SDO_init(
|
|||
|
||||
/* Configure object variables */
|
||||
SDO->nodeId = nodeId;
|
||||
SDO->SDOtimeoutTime_us = (uint32_t)SDOtimeoutTime_ms * 1000;
|
||||
SDO->state = CO_SDO_ST_IDLE;
|
||||
CO_CANrxNew_CLEAR(SDO->CANrxNew);
|
||||
SDO->pFunctSignal = NULL;
|
||||
|
|
@ -768,9 +770,8 @@ static void CO_SDO_abort(CO_SDO_t *SDO, uint32_t code){
|
|||
int8_t CO_SDO_process(
|
||||
CO_SDO_t *SDO,
|
||||
bool_t NMTisPreOrOperational,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t SDOtimeoutTime,
|
||||
uint16_t *timerNext_ms)
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
CO_SDO_state_t state = CO_SDO_ST_IDLE;
|
||||
bool_t timeoutSubblockDownolad = false;
|
||||
|
|
@ -867,10 +868,10 @@ int8_t CO_SDO_process(
|
|||
}
|
||||
|
||||
/* verify SDO timeout */
|
||||
if(SDO->timeoutTimer < SDOtimeoutTime){
|
||||
SDO->timeoutTimer += timeDifference_ms;
|
||||
if (SDO->timeoutTimer < SDO->SDOtimeoutTime_us) {
|
||||
SDO->timeoutTimer += timeDifference_us;
|
||||
}
|
||||
if(SDO->timeoutTimer >= SDOtimeoutTime){
|
||||
if (SDO->timeoutTimer >= SDO->SDOtimeoutTime_us) {
|
||||
if((SDO->state == CO_SDO_ST_DOWNLOAD_BL_SUBBLOCK) && (SDO->sequence != 0) && (!SDO->CANtxBuff->bufferFull)){
|
||||
timeoutSubblockDownolad = true;
|
||||
state = CO_SDO_ST_DOWNLOAD_BL_SUB_RESP;
|
||||
|
|
@ -1434,9 +1435,9 @@ int8_t CO_SDO_process(
|
|||
/* send response */
|
||||
CO_CANsend(SDO->CANdevTx, SDO->CANtxBuff);
|
||||
|
||||
/* Set timerNext_ms to 0 to inform OS to call this function again without delay. */
|
||||
if(timerNext_ms != NULL){
|
||||
*timerNext_ms = 0;
|
||||
/* Set timerNext_us to 0 to inform OS to call this function again without delay. */
|
||||
if (timerNext_us != NULL) {
|
||||
*timerNext_us = 0;
|
||||
}
|
||||
|
||||
/* don't call CO_CANrxNew_CLEAR, so return directly */
|
||||
|
|
@ -1453,7 +1454,7 @@ int8_t CO_SDO_process(
|
|||
SDO->state = CO_SDO_ST_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case CO_SDO_ST_IDLE:
|
||||
{
|
||||
/* Nothing to do it seems */
|
||||
|
|
|
|||
|
|
@ -613,8 +613,10 @@ typedef struct{
|
|||
CO_SDO_state_t state;
|
||||
/** Toggle bit in segmented transfer or block sequence in block transfer */
|
||||
uint8_t sequence;
|
||||
/** Maximum timeout time between request and response in microseconds. */
|
||||
uint32_t SDOtimeoutTime_us;
|
||||
/** Timeout timer for SDO communication */
|
||||
uint16_t timeoutTimer;
|
||||
uint32_t timeoutTimer;
|
||||
/** Number of segments per block with 1 <= blksize <= 127 */
|
||||
uint8_t blksize;
|
||||
/** True, if CRC calculation by block transfer is enabled */
|
||||
|
|
@ -753,6 +755,7 @@ void CO_memcpySwap8(void* dest, const void* src);
|
|||
* @param ODExtensions Pointer to the externally defined array of the same size
|
||||
* as ODSize.
|
||||
* @param nodeId CANopen Node ID of this device.
|
||||
* @param SDOtimeoutTime_ms Timeout time for SDO communication in milliseconds.
|
||||
* @param CANdevRx CAN device for SDO server reception.
|
||||
* @param CANdevRxIdx Index of receive buffer in the above CAN device.
|
||||
* @param CANdevTx CAN device for SDO server transmission.
|
||||
|
|
@ -770,6 +773,7 @@ CO_ReturnError_t CO_SDO_init(
|
|||
uint16_t ODSize,
|
||||
CO_OD_extension_t ODExtensions[],
|
||||
uint8_t nodeId,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
CO_CANmodule_t *CANdevRx,
|
||||
uint16_t CANdevRxIdx,
|
||||
CO_CANmodule_t *CANdevTx,
|
||||
|
|
@ -799,9 +803,8 @@ void CO_SDO_initCallback(
|
|||
* @param SDO This object.
|
||||
* @param NMTisPreOrOperational Different than zero, if #CO_NMT_internalState_t is
|
||||
* NMT_PRE_OPERATIONAL or NMT_OPERATIONAL.
|
||||
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
|
||||
* @param SDOtimeoutTime Timeout time for SDO communication in milliseconds.
|
||||
* @param timerNext_ms Return value - info to OS - see CO_process().
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param timerNext_us [out] info to OS - see CO_process().
|
||||
*
|
||||
* @return 0: SDO server is idle.
|
||||
* @return 1: SDO server is in transfer state.
|
||||
|
|
@ -810,9 +813,8 @@ void CO_SDO_initCallback(
|
|||
int8_t CO_SDO_process(
|
||||
CO_SDO_t *SDO,
|
||||
bool_t NMTisPreOrOperational,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t SDOtimeoutTime,
|
||||
uint16_t *timerNext_ms);
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -330,6 +330,7 @@ CO_SDOclient_return_t CO_SDOclientDownloadInitiate(
|
|||
uint8_t subIndex,
|
||||
uint8_t *dataTx,
|
||||
uint32_t dataSize,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
uint8_t blockEnable)
|
||||
{
|
||||
/* verify parameters */
|
||||
|
|
@ -340,6 +341,8 @@ CO_SDOclient_return_t CO_SDOclientDownloadInitiate(
|
|||
/* save parameters */
|
||||
SDO_C->buffer = dataTx;
|
||||
SDO_C->bufferSize = dataSize;
|
||||
SDO_C->SDOtimeoutTimeHalf_us = (uint32_t)SDOtimeoutTime_ms * 500;
|
||||
SDO_C->SDOtimeoutTime_us = SDO_C->SDOtimeoutTimeHalf_us * 2;
|
||||
|
||||
SDO_C->state = SDO_STATE_DOWNLOAD_INITIATE;
|
||||
|
||||
|
|
@ -409,9 +412,9 @@ CO_SDOclient_return_t CO_SDOclientDownloadInitiate(
|
|||
/******************************************************************************/
|
||||
CO_SDOclient_return_t CO_SDOclientDownload(
|
||||
CO_SDOclient_t *SDO_C,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t SDOtimeoutTime,
|
||||
uint32_t *pSDOabortCode)
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *pSDOabortCode,
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
CO_SDOclient_return_t ret = CO_SDOcli_waitingServerResponse;
|
||||
|
||||
|
|
@ -614,14 +617,23 @@ CO_SDOclient_return_t CO_SDOclientDownload(
|
|||
}
|
||||
|
||||
/* TMO *********************************************************************************************** */
|
||||
if(SDO_C->timeoutTimer < SDOtimeoutTime){
|
||||
SDO_C->timeoutTimer += timeDifference_ms;
|
||||
if (SDO_C->timeoutTimer < SDO_C->SDOtimeoutTime_us) {
|
||||
SDO_C->timeoutTimer += timeDifference_us;
|
||||
}
|
||||
if(SDO_C->timeoutTimer >= SDOtimeoutTime){ /* communication TMO */
|
||||
|
||||
/* communication TMO */
|
||||
if (SDO_C->timeoutTimer >= SDO_C->SDOtimeoutTime_us) {
|
||||
*pSDOabortCode = CO_SDO_AB_TIMEOUT;
|
||||
CO_SDOclient_abort(SDO_C, *pSDOabortCode);
|
||||
return CO_SDOcli_endedWithTimeout;
|
||||
}
|
||||
else if (timerNext_us != NULL) {
|
||||
/* check again after inhibit time elapsed */
|
||||
uint32_t diff = SDO_C->SDOtimeoutTime_us - SDO_C->timeoutTimer;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
}
|
||||
|
||||
/* TX data ******************************************************************************************* */
|
||||
if(SDO_C->CANtxBuff->bufferFull) {
|
||||
|
|
@ -670,9 +682,6 @@ CO_SDOclient_return_t CO_SDOclientDownload(
|
|||
SDO_C->block_seqno += 1;
|
||||
SDO_C->CANtxBuff->data[0] = SDO_C->block_seqno;
|
||||
|
||||
if(SDO_C->block_seqno >= SDO_C->block_blksize){
|
||||
SDO_C->state = SDO_STATE_BLOCKDOWNLOAD_BLOCK_ACK;
|
||||
}
|
||||
/* set data */
|
||||
SDO_C->block_noData = 0;
|
||||
|
||||
|
|
@ -693,6 +702,13 @@ CO_SDOclient_return_t CO_SDOclientDownload(
|
|||
SDO_C->block_blksize = SDO_C->block_seqno;
|
||||
SDO_C->state = SDO_STATE_BLOCKDOWNLOAD_BLOCK_ACK;
|
||||
}
|
||||
else if (SDO_C->block_seqno >= SDO_C->block_blksize) {
|
||||
SDO_C->state = SDO_STATE_BLOCKDOWNLOAD_BLOCK_ACK;
|
||||
}
|
||||
else if (timerNext_us != NULL) {
|
||||
/* Set timerNext_us to 0 to inform OS to call this function again without delay. */
|
||||
*timerNext_us = 0;
|
||||
}
|
||||
|
||||
/* tx data */
|
||||
SDO_C->timeoutTimer = 0;
|
||||
|
|
@ -742,6 +758,7 @@ CO_SDOclient_return_t CO_SDOclientUploadInitiate(
|
|||
uint8_t subIndex,
|
||||
uint8_t *dataRx,
|
||||
uint32_t dataRxSize,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
uint8_t blockEnable)
|
||||
{
|
||||
/* verify parameters */
|
||||
|
|
@ -752,6 +769,8 @@ CO_SDOclient_return_t CO_SDOclientUploadInitiate(
|
|||
/* save parameters */
|
||||
SDO_C->buffer = dataRx;
|
||||
SDO_C->bufferSize = dataRxSize;
|
||||
SDO_C->SDOtimeoutTimeHalf_us = (uint32_t)SDOtimeoutTime_ms * 500;
|
||||
SDO_C->SDOtimeoutTime_us = SDO_C->SDOtimeoutTimeHalf_us * 2;
|
||||
|
||||
/* prepare CAN tx message */
|
||||
CO_SDOTxBufferClear(SDO_C);
|
||||
|
|
@ -814,10 +833,10 @@ CO_SDOclient_return_t CO_SDOclientUploadInitiate(
|
|||
/******************************************************************************/
|
||||
CO_SDOclient_return_t CO_SDOclientUpload(
|
||||
CO_SDOclient_t *SDO_C,
|
||||
uint16_t timeDifference_ms,
|
||||
uint16_t SDOtimeoutTime,
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *pDataSize,
|
||||
uint32_t *pSDOabortCode)
|
||||
uint32_t *pSDOabortCode,
|
||||
uint32_t *timerNext_us)
|
||||
{
|
||||
uint16_t indexTmp;
|
||||
uint32_t tmp32;
|
||||
|
|
@ -1106,19 +1125,37 @@ CO_SDOclient_return_t CO_SDOclientUpload(
|
|||
}
|
||||
|
||||
/* TMO *************************************************************************************************** */
|
||||
if(SDO_C->timeoutTimer < SDOtimeoutTime){
|
||||
SDO_C->timeoutTimer += timeDifference_ms;
|
||||
if (SDO_C->timeoutTimer < SDO_C->SDOtimeoutTime_us) {
|
||||
SDO_C->timeoutTimer += timeDifference_us;
|
||||
if (SDO_C->state == SDO_STATE_BLOCKUPLOAD_INPROGRES)
|
||||
SDO_C->timeoutTimerBLOCK += timeDifference_ms;
|
||||
SDO_C->timeoutTimerBLOCK += timeDifference_us;
|
||||
}
|
||||
if(SDO_C->timeoutTimer >= SDOtimeoutTime){ /* communication TMO */
|
||||
|
||||
/* communication TMO */
|
||||
if (SDO_C->timeoutTimer >= SDO_C->SDOtimeoutTime_us) {
|
||||
*pSDOabortCode = CO_SDO_AB_TIMEOUT;
|
||||
CO_SDOclient_abort(SDO_C, *pSDOabortCode);
|
||||
return CO_SDOcli_endedWithTimeout;
|
||||
}
|
||||
if(SDO_C->timeoutTimerBLOCK >= (SDOtimeoutTime/2)){ /* block TMO */
|
||||
else if (timerNext_us != NULL) {
|
||||
/* check again after inhibit time elapsed */
|
||||
uint32_t diff = SDO_C->SDOtimeoutTime_us - SDO_C->timeoutTimer;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
}
|
||||
|
||||
/* block TMO */
|
||||
if (SDO_C->timeoutTimerBLOCK >= SDO_C->SDOtimeoutTimeHalf_us) {
|
||||
SDO_C->state = SDO_STATE_BLOCKUPLOAD_BLOCK_ACK;
|
||||
}
|
||||
else if (timerNext_us != NULL) {
|
||||
/* check again after inhibit time elapsed */
|
||||
uint32_t diff = SDO_C->SDOtimeoutTimeHalf_us - SDO_C->timeoutTimerBLOCK;
|
||||
if (*timerNext_us > diff) {
|
||||
*timerNext_us = diff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TX data ******************************************************************************** */
|
||||
|
|
|
|||
|
|
@ -112,10 +112,14 @@ typedef struct{
|
|||
uint32_t dataSize;
|
||||
/** Data length transferred in block transfer */
|
||||
uint32_t dataSizeTransfered;
|
||||
/** Maximum timeout time between request and response in microseconds. */
|
||||
uint32_t SDOtimeoutTime_us;
|
||||
/** Half of maximum timeout time between request and response. */
|
||||
uint32_t SDOtimeoutTimeHalf_us;
|
||||
/** Timeout timer for SDO communication */
|
||||
uint16_t timeoutTimer;
|
||||
uint32_t timeoutTimer;
|
||||
/** Timeout timer for SDO block transfer */
|
||||
uint16_t timeoutTimerBLOCK;
|
||||
uint32_t timeoutTimerBLOCK;
|
||||
/** Index of current object in Object Dictionary */
|
||||
uint16_t index;
|
||||
/** Subindex of current object in Object Dictionary */
|
||||
|
|
@ -246,6 +250,7 @@ CO_SDOclient_return_t CO_SDOclient_setup(
|
|||
* format, because CANopen itself uses little-endian. Take care,
|
||||
* when using processors with big-endian.
|
||||
* @param dataSize Size of data in dataTx.
|
||||
* @param SDOtimeoutTime_ms Timeout time for SDO communication in milliseconds.
|
||||
* @param blockEnable Try to initiate block transfer.
|
||||
*
|
||||
* @return #CO_SDOclient_return_t
|
||||
|
|
@ -256,6 +261,7 @@ CO_SDOclient_return_t CO_SDOclientDownloadInitiate(
|
|||
uint8_t subIndex,
|
||||
uint8_t *dataTx,
|
||||
uint32_t dataSize,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
uint8_t blockEnable);
|
||||
|
||||
|
||||
|
|
@ -267,18 +273,18 @@ CO_SDOclient_return_t 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 timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param pSDOabortCode Pointer to external variable written by this function
|
||||
* in case of error in communication.
|
||||
* @param timerNext_us [out] info to OS - see CO_process().
|
||||
*
|
||||
* @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);
|
||||
uint32_t timeDifference_us,
|
||||
uint32_t *pSDOabortCode,
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -296,6 +302,7 @@ CO_SDOclient_return_t CO_SDOclientDownload(
|
|||
* in little-endian format, because CANopen itself uses
|
||||
* little-endian. Take care, when using processors with big-endian.
|
||||
* @param dataRxSize Size of dataRx.
|
||||
* @param SDOtimeoutTime_ms Timeout time for SDO communication in milliseconds.
|
||||
* @param blockEnable Try to initiate block transfer.
|
||||
*
|
||||
* @return #CO_SDOclient_return_t
|
||||
|
|
@ -306,6 +313,7 @@ CO_SDOclient_return_t CO_SDOclientUploadInitiate(
|
|||
uint8_t subIndex,
|
||||
uint8_t *dataRx,
|
||||
uint32_t dataRxSize,
|
||||
uint16_t SDOtimeoutTime_ms,
|
||||
uint8_t blockEnable);
|
||||
|
||||
|
||||
|
|
@ -317,21 +325,21 @@ CO_SDOclient_return_t 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 timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @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.
|
||||
* @param timerNext_us [out] info to OS - see CO_process().
|
||||
*
|
||||
* @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 timeDifference_us,
|
||||
uint32_t *pDataSize,
|
||||
uint32_t *pSDOabortCode);
|
||||
uint32_t *pSDOabortCode,
|
||||
uint32_t *timerNext_us);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ CO_ReturnError_t CO_SYNC_init(
|
|||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
* @param ObjDict_synchronousWindowLength _Synchronous window length_ variable from
|
||||
* Object dictionary (index 0x1007).
|
||||
* @param timerNext_us Return value - info to OS - see CO_process_SYNC_PDO().
|
||||
* @param timerNext_us [out] info to OS - see CO_process_SYNC_PDO().
|
||||
*
|
||||
* @return 0: No special meaning.
|
||||
* @return 1: New SYNC message recently received or was just transmitted.
|
||||
|
|
|
|||
|
|
@ -125,13 +125,14 @@ CO_ReturnError_t CO_TIME_init(
|
|||
/******************************************************************************/
|
||||
uint8_t CO_TIME_process(
|
||||
CO_TIME_t *TIME,
|
||||
uint32_t timeDifference_ms)
|
||||
uint32_t timeDifference_us)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint32_t timerNew;
|
||||
|
||||
if(*TIME->operatingState == CO_NMT_OPERATIONAL || *TIME->operatingState == CO_NMT_PRE_OPERATIONAL){
|
||||
/* update TIME timer, no overflow */
|
||||
uint32_t timeDifference_ms = (timeDifference_us+500) / 1000; //this should be optimized
|
||||
timerNew = TIME->timer + timeDifference_ms;
|
||||
if(timerNew > TIME->timer)
|
||||
TIME->timer = timerNew;
|
||||
|
|
|
|||
|
|
@ -143,14 +143,14 @@ CO_ReturnError_t CO_TIME_init(
|
|||
* Function must be called cyclically.
|
||||
*
|
||||
* @param TIME This object.
|
||||
* @param timeDifference_ms Time difference from previous function call in [milliseconds].
|
||||
* @param timeDifference_us Time difference from previous function call in [microseconds].
|
||||
*
|
||||
* @return 0: No special meaning.
|
||||
* @return 1: New TIME message recently received (consumer) / transmited (producer).
|
||||
*/
|
||||
uint8_t CO_TIME_process(
|
||||
CO_TIME_t *TIME,
|
||||
uint32_t timeDifference_ms);
|
||||
uint32_t timeDifference_us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue