1
0
Fork 0

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:
Janez 2020-02-04 20:28:33 +01:00
parent 1d051aa3d2
commit c19879b659
22 changed files with 441 additions and 396 deletions

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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 */

View file

@ -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*/

View file

@ -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;

View file

@ -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);
/**

View file

@ -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;
}

View file

@ -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);
/**

View file

@ -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,

View file

@ -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 */

View file

@ -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);
/**

View file

@ -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 ******************************************************************************** */

View file

@ -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);
/**

View file

@ -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.

View file

@ -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;

View file

@ -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
}