📄 pdo.c
字号:
/***************************************************************************
pdo.c - description
-------------------
begin : Fri May 17 2002
copyright : (C) 2002 by Raphael Zulliger
email : zulli@hsr.ch
***************************************************************************/
/***************************************************************************
* *
* This library is Copyright (c) Raphael Zulliger <zulli@gmx.net>. *
* It is licensed under the GNU Library General Public License (LGPL). *
* *
***************************************************************************/
#include <pdo.h>
#include <def.h>
#include <objacces.h>
#include <general.h>
#include <canop.h>
#include <objdict.h>
#include <init.h>
// GNU C-compiler accepts empty initialization of arrays like this one:
// s_pdo_mapping_parameter TxMap1 = { 0, { } };
// but Microchip C18 doesn't... therefore create this define...
#define FILL_DATA 0, 0, 0, 0, 0
/** The variable thats stores all received PDOs
*/
s_pdo_receive_transfer_table static RAM RxPDOTransferTable[MAX_COUNT_OF_PDO] =
{
{ 0, TRUE, 0, { FILL_DATA } }//,
// { 0, TRUE, 0, { FILL_DATA } },
// { 0, TRUE, 0, { FILL_DATA } },
// { 0, TRUE, 0, { FILL_DATA } }
};
#undef FILL_DATA
void CopyBits(int NbBits,
char* SrcByteIndex, // source Byte index
int SrcBitIndex, // source bit index
BOOL SrcLittleEndian, // is source data littleendian? if yes: true, else false
char* DestByteIndex,
int DestBitIndex,
BOOL DestLittleEndian); // is destination data little endian?
/** some data definitions */
typedef struct sd_pdo_transmit_transfer_table
{
Message canMessage; // holds the whole canmessage including RTR, len, data, ...
UNSIGNED8 transmissionType; // represents the transmission type of a PDO
BOOL sent; // if true, then it is allready sent
UNSIGNED8 syncCount; // count of syncs since last send (only important if transmissiontype 1-240)
UNSIGNED8 prevData[8]; // holds the previous Datavalue
BOOL dataValid; // unless the first time data has be set to valid data, this is set to FALSE
} s_pdo_transmit_transfer_table;
/** for the next two vars: adjust the count of lines according to the value of MAX_COUNT_OF_PDO, to avoid
* unexpected things... */
#define FILL_IN_DATA 0, 0, 0, 0, 0, 0, 0, 0
#define FILL_IN_MESSAGE_DATA 0, 0, 0, 0
s_pdo_transmit_transfer_table static TxPDOTransferTable[MAX_COUNT_OF_PDO] =
{
{ { FILL_IN_MESSAGE_DATA }, 0 ,0 , 0, { FILL_IN_DATA } ,TRUE }//,
// { { FILL_IN_MESSAGE_DATA }, 0 ,0 , 0, { FILL_IN_DATA } ,TRUE },
// { { FILL_IN_MESSAGE_DATA }, 0 ,0 , 0, { FILL_IN_DATA } ,TRUE },
// { { FILL_IN_MESSAGE_DATA }, 0 ,0 , 0, { FILL_IN_DATA } ,TRUE }
};
#undef FILL_IN_DATA
#undef FILL_IN_MESSAGE_DATA
void processSendPDO( void )
{
// !!!!!!!!!!!!!!!!!!!!!!! for the moment: all PDOs are sent! of course this is not the way it should...
static BOOL bFirstTime = TRUE; // because the first time this function is called, the stored pdo-data
// are invalid and therefore they shouldn't be checked...
BYTE psp_i,
psp_j,
psp_k;
BYTE copiedBytes;
DWORD XDATA* pSize;
DWORD size;
BYTE XHUGE* pMappingCount; // number of available mapping parameters
DWORD XHUGE* pMappedAppObject; // e.g. 60000108
void XHUGE* pObject; // the object to send (the pointer to the object)
WORD XHUGE* pwCobId; // cob-id of the variable
BYTE XHUGE* pbTransmissionType; // e.g. 255
BYTE XHUGE* pbCommParamCount; // count of pdo communication parameter (subindex 0)
pSize = &size;
// first make sure we are in OPERATIONAL state. only in OPERATIONAL state PDO transfer is allowed
if( bStateMachineState == (BYTE)OPERATIONAL )
{
// processes all available mapping parameters...
for( psp_i=(BYTE)0x00; psp_i<(BYTE)MAX_COUNT_OF_PDO; psp_i++ )
{
// for each mapping parameter... canopen sais: there can maximum be 64.
// gets the count of mapping paramters for each TxPDO
if( getODEntry( (WORD)0x1A00 | psp_i, (BYTE)0, (void XHUGE* XDATA*)&pMappingCount, pSize ) == SUCCESSFUL )
{ // ok. we've got the count of mapping paramters for the actual TransmitPDO
// now we are getting each mapping parameter...
copiedBytes = (BYTE)0;
for( psp_k=(BYTE)0x00; psp_k<*pMappingCount; psp_k++ )
{
// gets the mapping parameter e.g. 0x60000108
if( getODEntry( (WORD)0x1A00 | (BYTE)psp_i, (BYTE)psp_k+(BYTE)0x01, (void XHUGE* XDATA*)&pMappedAppObject, pSize ) == SUCCESSFUL )
{
// gets the value of the process var...
if( getODEntry( (WORD)( ( *pMappedAppObject & 0xFFFF0000 ) >> 16 ), (BYTE)( (*pMappedAppObject & 0x0000FF00 ) >> 8 ), (void XHUGE* XDATA*)&pObject, pSize ) == SUCCESSFUL )
{ // now we've got the value. we have to copy it into the can message...
memcpy( (void*)&TxPDOTransferTable[psp_i].canMessage.data[copiedBytes], (void*)pObject, size ); // copy size bytes into the can-message data.
copiedBytes += (BYTE)size; // increse count of copied bytes
}
}
} // now the data should be in the can-message struct... (m.data)
if( copiedBytes > (BYTE)0x00 )
{ // if there were no mapping params, we don't have to send anything
// test wheter the entries in the Object dictionary are valid...
if( getODEntry( (WORD)0x1800 | (BYTE)psp_i, (BYTE)0, (void XHUGE* XDATA*)&pbCommParamCount, pSize ) == SUCCESSFUL ) // gets the tranmission type
{
if( *pbCommParamCount >= (BYTE)0x02 )
{
if( getODEntry( (WORD)0x1800 | (BYTE)psp_i, (BYTE)2, (void XHUGE* XDATA*)&pbTransmissionType, pSize ) == SUCCESSFUL ) // gets the tranmission type
TxPDOTransferTable[psp_i].transmissionType = *pbTransmissionType;
TxPDOTransferTable[psp_i].sent = TRUE; // normally this command will be executed (except the first time)
if( bFirstTime == FALSE )
{
if( TxPDOTransferTable[psp_i].dataValid == TRUE )
{
for( psp_j=(BYTE)0x00; psp_j<copiedBytes; psp_j++ )
{ // checks wheter the data has changed since last time or not...
if( TxPDOTransferTable[psp_i].canMessage.data[psp_j] != TxPDOTransferTable[psp_i].prevData[psp_j] )
{ // if a databyte has changed since last time, set the sent flag to FALSE, so it will be sent now...
TxPDOTransferTable[psp_i].sent = FALSE;
}
TxPDOTransferTable[psp_i].prevData[psp_j] = TxPDOTransferTable[psp_i].canMessage.data[psp_j];
TxPDOTransferTable[psp_i].dataValid = TRUE;
}
}
else
{
TxPDOTransferTable[psp_i].sent = FALSE;
}
}
else
{
// the first time, we have to send the PDO
bFirstTime = FALSE;
// copy the data to the prevData-field.
for( psp_j=(BYTE)0x00; psp_j<copiedBytes; psp_j++ )
{ // checks wheter the data has changed since last time or not...
TxPDOTransferTable[psp_i].prevData[psp_j] = TxPDOTransferTable[psp_i].canMessage.data[psp_j];
TxPDOTransferTable[psp_i].dataValid = TRUE;
}
TxPDOTransferTable[psp_i].sent = FALSE;
}
TxPDOTransferTable[psp_i].canMessage.len = copiedBytes;
// workaround: SUCCESSFUL was deleted and (DWORD)0x8 written instead...
if( getODEntry( (WORD)0x1800 | (BYTE)psp_i, (BYTE)0x01, (void XHUGE* XDATA*)&pwCobId, pSize ) == SUCCESSFUL ) // gets the cob_id
TxPDOTransferTable[psp_i].canMessage.cob_id.w = *pwCobId;
TxPDOTransferTable[psp_i].canMessage.rtr = 0x00; // sets the can-rtr bit to 0
}
else // if no datas are copied into the transfertable, set sent flag to true, so the old data aren't sent
{
TxPDOTransferTable[psp_i].sent = TRUE;
}
}
} // end test if PDO communication parameter are valid (count at least 2)
}
if( ( TxPDOTransferTable[psp_i].sent == FALSE ) && ( TxPDOTransferTable[psp_i].transmissionType == (BYTE)255 ) )
{ // if message not sent, and transmissiontype == 255, then send the message NOW
canSend( (BYTE)0x00, &TxPDOTransferTable[psp_i].canMessage );
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -