⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdo.c

📁 This library is Copyright (c) Raphael Zulliger <zulli@gmx.net>. It is licensed under the GNU L
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
                         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 + -