/*!
**
**
** @param d
** @param m
**
** @return
**/
UNS8
proceedPDO (CO_Data * d, Message * m)
{
UNS8 numPdo;
UNS8 numMap; /* Number of the mapped varable */
UNS8 *pMappingCount = NULL; /* count of mapped objects... */
/* pointer to the var which is mapped to a pdo... */
/* void * pMappedAppObject = NULL; */
/* pointer fo the var which holds the mapping parameter of an
mapping entry */
UNS32 *pMappingParameter = NULL;
UNS8 *pTransmissionType = NULL; /* pointer to the transmission
type */
UNS16 *pwCobId = NULL;
UNS8 Size;
UNS8 offset;
UNS8 status;
UNS32 objDict;
UNS16 offsetObjdict;
UNS16 lastIndex;
status = state2;
MSG_WAR (0x3935, "proceedPDO, cobID : ", (UNS16_LE(m->cob_id) & 0x7ff));
offset = 0x00;
numPdo = 0;
numMap = 0;
if ((*m).rtr == NOT_A_REQUEST)
{
offsetObjdict = d->firstIndex->PDO_RCV;
lastIndex = d->lastIndex->PDO_RCV;
if (offsetObjdict)
while (offsetObjdict <= lastIndex)
{
switch (status)
{
case state2:
pwCobId = d->objdict[offsetObjdict].pSubindex[1].pObject;
if (*pwCobId == UNS16_LE(m->cob_id))
{
/* The cobId is recognized */
status = state4;
MSG_WAR (0x3936, "cobId found at index ",
0x1400 + numPdo);
break;
}
else
{
/* received cobId does not match */
numPdo++;
offsetObjdict++;
status = state2;
break;
}
case state4: /* Get Mapped Objects Number */
/* The cobId of the message received has been found in the
dictionnary. */
offsetObjdict = d->firstIndex->PDO_RCV_MAP;
lastIndex = d->lastIndex->PDO_RCV_MAP;
pMappingCount =
(UNS8 *) (d->objdict + offsetObjdict +
numPdo)->pSubindex[0].pObject;
numMap = 0;
while (numMap < *pMappingCount)
{
UNS8 tmp[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
UNS32 ByteSize;
pMappingParameter =
(UNS32 *) (d->objdict + offsetObjdict +
numPdo)->pSubindex[numMap + 1].pObject;
if (pMappingParameter == NULL)
{
MSG_ERR (0x1937, "Couldn't get mapping parameter : ",
numMap + 1);
return 0xFF;
}
/* Get the addresse of the mapped variable. */
/* detail of *pMappingParameter : */
/* The 16 hight bits contains the index, the medium 8 bits
contains the subindex, */
/* and the lower 8 bits contains the size of the mapped
variable. */
Size = (UNS8) (*pMappingParameter & (UNS32) 0x000000FF);
/* set variable only if Size != 0 and
* Size is lower than remaining bits in the PDO */
if (Size && ((offset + Size) <= (m->len << 3)))
{
/* copy bit per bit in little endian */
CopyBits (Size, (UNS8 *) & m->data[offset >> 3],
offset % 8, 0, ((UNS8 *) tmp), 0, 0);
/*1->8 => 1 ; 9->16 =>2, ... */
ByteSize = (UNS32)(1 + ((Size - 1) >> 3));
objDict =
setODentry (d, (UNS16) ((*pMappingParameter) >> 16),
(UNS8) (((*pMappingParameter) >> 8) &
0xFF), tmp, &ByteSize, 0);
if (objDict != OD_SUCCESSFUL)
{
MSG_ERR (0x1938,
"error accessing to the mapped var : ",
numMap + 1);
MSG_WAR (0x2939, " Mapped at index : ",
(*pMappingParameter) >> 16);
MSG_WAR (0x2940, " subindex : ",
((*pMappingParameter) >> 8) & 0xFF);
return 0xFF;
}
MSG_WAR (0x3942,
"Variable updated by PDO cobid : ",
UNS16_LE(m->cob_id));
MSG_WAR (0x3943, " Mapped at index : ",
(*pMappingParameter) >> 16);
MSG_WAR (0x3944, " subindex : ",
((*pMappingParameter) >> 8) & 0xFF);
offset += Size;
}
numMap++;
} /* end loop while on mapped variables */
if (d->RxPDO_EventTimers)
{
TIMEVAL EventTimerDuration = *(UNS16 *)d->objdict[offsetObjdict].pSubindex[5].pObject;
if(EventTimerDuration){
DelAlarm (d->RxPDO_EventTimers[numPdo]);
d->RxPDO_EventTimers[numPdo] = SetAlarm (d, numPdo, d->RxPDO_EventTimers_Handler,
MS_TO_TIMEVAL (EventTimerDuration), 0);
}
}
return 0;
} /* end switch status */
} /* end while */
} /* end if Donnees */
else if ((*m).rtr == REQUEST)
{
MSG_WAR (0x3946, "Receive a PDO request cobId : ", UNS16_LE(m->cob_id));
status = state1;
offsetObjdict = d->firstIndex->PDO_TRS;
lastIndex = d->lastIndex->PDO_TRS;
if (offsetObjdict)
while (offsetObjdict <= lastIndex)
{
/* study of all PDO stored in the objects dictionary */
switch (status)
{
case state1: /* check the CobId */
/* get CobId of the dictionary which match to the received PDO
*/
pwCobId =
(d->objdict +
offsetObjdict)->pSubindex[1].pObject;
if (*pwCobId == UNS16_LE(m->cob_id))
{
status = state4;
break;
}
else
{
numPdo++;
offsetObjdict++;
}
status = state1;
break;
case state4: /* check transmission type */
pTransmissionType =
(UNS8 *) d->objdict[offsetObjdict].pSubindex[2].pObject;
/* If PDO is to be sampled and send on RTR, do it */
if ((*pTransmissionType == TRANS_RTR))
{
status = state5;
break;
}
/* RTR_SYNC means data prepared at SYNC, transmitted on RTR */
else if ((*pTransmissionType == TRANS_RTR_SYNC))
{
if (d->PDO_status[numPdo].
transmit_type_parameter & PDO_RTR_SYNC_READY)
{
/*Data ready, just send */
canSend (d->canHandle,
&d->PDO_status[numPdo].last_message);
return 0;
}
else
{
/* if SYNC did never occur, transmit current data */
/* DS301 do not tell what to do in such a case... */
MSG_ERR (0x1947,
"Not ready RTR_SYNC TPDO send current data : ",
UNS16_LE(m->cob_id));
status = state5;
}
break;
}
else if ((*pTransmissionType == TRANS_EVENT_PROFILE) ||
(*pTransmissionType == TRANS_EVENT_SPECIFIC))
{
/* Zap all timers and inhibit flag */
d->PDO_status[numPdo].event_timer =
DelAlarm (d->PDO_status[numPdo].event_timer);
d->PDO_status[numPdo].inhibit_timer =
DelAlarm (d->PDO_status[numPdo].inhibit_timer);
d->PDO_status[numPdo].transmit_type_parameter &=
~PDO_INHIBITED;
/* Call PDOEventTimerAlarm for this TPDO,
* this will trigger emission et reset timers */
PDOEventTimerAlarm (d, numPdo);
return 0;
}
else
{
/* The requested PDO is not to send on request. So, does
nothing. */
MSG_WAR (0x2947, "PDO is not to send on request : ",
UNS16_LE(m->cob_id));
return 0xFF;
}
case state5: /* build and send requested PDO */
{
Message pdo;
if (buildPDO (d, numPdo, &pdo))
{
MSG_ERR (0x1948, " Couldn't build TPDO number : ", numPdo);
return 0xFF;
}
canSend (d->canHandle, &pdo);
return 0;
}
} /* end switch status */
} /* end while */
} /* end if Requete */
return 0;
} |