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

📄 pmdpci.c

📁 一个机器人的源代码.软件设计得超级好!是商业级代码.
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
    	rc = PlxIoPortWrite(PIOtransport_data->hDrv, 
						PIOtransport_data->nBasePortAddress + 0x18,
						BitSize16,
						&temp); 
    }
    else //if (PIOtransport_data->nDeviceID == CARD_MB_NAVIGATOR)
    {
    	rc = PlxIoPortWrite(PIOtransport_data->hDrv, 
						PIOtransport_data->nBasePortAddress + 0x0E,
						BitSize16,
						&temp); 
    }

    if (rc != ApiSuccess)
		return PMD_ERR_Driver;

    return PMD_NOERROR;
}

//*****************************************************************************
PMDuint16 PMDPCI_WaitUntilReady(void* transport_data)
{
#ifdef _LINUX	S32 stopTime, currentTime;	struct timeval now;#else    	DWORD stopTime, currentTime;#endif
	PMDuint16 status=0;

#ifdef _LINUX     gettimeofday(&now,NULL);     stopTime = now.tv_sec * 1000l + now.tv_usec/1000l+1000;#else    // GetTickCount returns time in ms
    stopTime = GetTickCount() + 1000; // timeout is 1 sec
#endif
    for(;;)
    {
        // poll ready port, if not ready, loop
		PMDPCI_ReadStatus(transport_data, &status);

		if (status&RDY_MASK)
			return PMD_NOERROR;
#ifdef _LINUX	gettimeofday(&now,NULL);        currentTime = now.tv_sec * 1000l + now.tv_usec/1000l;#else
        currentTime = GetTickCount();
#endif
        if (currentTime > stopTime)
        {
			// check the ready again, even after a timeout
			PMDPCI_ReadStatus(transport_data, &status);

			if (status&RDY_MASK)
				return PMD_NOERROR;
        	return PMD_ERR_CommTimeoutError;
        }
    }

} /* end WaitUntilReady */

//*****************************************************************************
PMDuint16 PMDPCI_Send(void* transport_data, PMDuint8 xCt, PMDuint16* xDat, PMDuint8 rCt, PMDuint16* rDat)
{
	int index,i;
	PMDuint16 cksum, status;
	PMDuint16 calcSum;
	PMDuint16 result = PMD_NOERROR;
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
	HANDLE hDrv = PIOtransport_data->hDrv;

	if (hDrv == INVALID_HANDLE_VALUE)
	    return PMD_ERR_DK2000NotInitialized;

	if ( PMDPCI_WriteCMD(transport_data, xDat[0]) )
		return PMD_ERR_Driver;

	// check for success/failure of this command
	if ( PMDPCI_WaitUntilReady(transport_data) )
		return PMD_ERR_CommTimeoutError;

    // put the data into the DK2000
    // one word at a time
    for(index=1; index<xCt; index++)
    {
		if ( PMDPCI_WriteData(transport_data, xDat[index]) )
			return PMD_ERR_Driver;
    }

    // get the data from the DK2000
    for(index=0; index<rCt; index++)
    {
		if ( PMDPCI_ReadData(transport_data, &rDat[index]) )
			return PMD_ERR_Driver;
    }

	if (PIOtransport_data->bVerifyChecksum)
	{
		if ( PMDPCI_ReadData(transport_data, &cksum) )
			return PMD_ERR_Driver;

		calcSum = 0;

		for( i=0; i<xCt; i++ ) calcSum += xDat[i];
		for( i=0; i<rCt; i++ ) calcSum += rDat[i];

		if( calcSum != cksum )
		{
			PMDprintf( "Checksum error, sent: ");
			for( i=0; i<xCt; i++ ) PMDprintf( " 0x%04hx", xDat[i] );
			PMDprintf( "\n" );

			if( rCt ) PMDprintf( "            received:" );
			for( i=0; i<rCt; i++ ) PMDprintf( " 0x%04hx", rDat[i] );

			PMDprintf( "\nExpected: 0x%04hx, got: 0x%04hx\n", calcSum, cksum );

			return PMD_ERR_ChecksumError;
		}
	}

	if ( PMDPCI_ReadStatus(transport_data, &status) )
		return PMD_ERR_Driver;

    if (status & ERR_MASK)
	{
		if (PIOtransport_data->bDiagnostics)
		{
            result = PMDPCI_HandleError(transport_data);
			PMDprintf("Command Error: %s\n", PMDGetErrorMessage(result));
		}

		return PMD_ERR_CommandError;
	}

	return result;
}

/******************************************************************************
 *
 * Function Name: ReadPCI_DPRAM()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_ReadDPRAM(void* transport_data, PMDuint32* data, PMDuint32 offset_in_dwords, PMDuint32 dwords_to_read)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc;
	PMDuint32 i,swap;

	if (g_bHasDPRAM == FALSE)
		return PMD_ERR_Driver; // no DPRAM

	rc = PlxBusIopRead(PIOtransport_data->hDrv, 
						g_IopSpace, 
						g_IopSpaceBase+(offset_in_dwords*4),
						FALSE,
						(PMDuint32*)data, 
						dwords_to_read*4, 
						BitSize32);

	if (rc != ApiSuccess)
		return PMD_ERR_Driver;

	// the chip stores the double word in big endian word order
	// so we need to word swap the results
	for (i=0;i<dwords_to_read;i++)
	{
		swap = (data[i] & 0xffff) << 16;
		data[i] = (data[i] >> 16) | swap;
	}

    return PMD_NOERROR;
} /* end ReadData */

/******************************************************************************
 *
 * Function Name: WritePCI_DPRAM()
 *
 ******************************************************************************/
PMDuint16 PMDPCI_WriteDPRAM(void* transport_data, PMDuint32* data, PMDuint32 offset_in_dwords, PMDuint32 dwords_to_write)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
    RETURN_CODE rc;
	PMDuint32 i,swap;

	if (g_bHasDPRAM == FALSE)
		return PMD_ERR_Driver; // no DPRAM

	// the chip stores the double word in big endian word order
	// so we need to word swap the data before writing
	for (i=0;i<dwords_to_write;i++)
	{
		swap = (data[i] & 0xffff) << 16;
		data[i] = (data[i] >> 16) | swap ;
	}

	rc = PlxBusIopWrite(PIOtransport_data->hDrv, 
						g_IopSpace, 
						g_IopSpaceBase+(offset_in_dwords*4),
						FALSE,
						(PMDuint32*)data, 
						dwords_to_write*4, 
						BitSize32);

	if (rc != ApiSuccess)
		return PMD_ERR_Driver;

    return PMD_NOERROR;
} /* end ReadData */

//*****************************************************************************
PMDuint16 PMDPCI_HandleError(void* transport_data)
{
	PMDuint16 result;
    PMDuint8 xCt;
    PMDuint16 xDat[2];
    PMDuint8 rCt;
    PMDuint16 rDat[2];
    static int GettingError = 0;

	if (GettingError) 
        return PMD_ERR_CommunicationsError;

	GettingError = 1;

    xCt = 1;
    xDat[0] = PMDOPGetHostIOError;
    rCt = 1;
    rDat[0] = PMD_NOERROR;

    result = PMDPCI_Send(transport_data, xCt, xDat, rCt, rDat);

    if (result == PMD_NOERROR)
    {
        result = rDat[0];
	}
	GettingError = 0;

	return result;
}

//*****************************************************************************
PMDuint16 PMDPCI_GetStatus(void* transport_data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
	PMDuint16 status = 0;

	PMDPCI_ReadStatus(PIOtransport_data, &status);

	return status;
}

//*****************************************************************************
PMDuint16 PMDPCI_IsReady(void* transport_data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
	PMDuint16 status = 0;

	PMDPCI_ReadStatus(PIOtransport_data, &status);

	return (PMDuint16)(status&RDY_MASK?1:0);
}

//*****************************************************************************
PMDuint16 PMDPCI_HasInterrupt(void* transport_data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
	PMDuint16 status = 0;

	PMDPCI_ReadStatus(PIOtransport_data, &status);

	return (PMDuint16)(status&INT_MASK?1:0);
}

//*****************************************************************************
PMDuint16 PMDPCI_HasError(void* transport_data)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)transport_data;
	PMDuint16 status = 0;

	PMDPCI_ReadStatus(PIOtransport_data, &status);

	return (PMDuint16)(status&ERR_MASK?1:0);
}

//*****************************************************************************
PMDuint16 PMDPCI_SetInterruptEvent(PMDAxisHandle* axis_handle,  HANDLE *pEventHdl)
{
	PMDPCIIOTransportData* PIOtransport_data = (PMDPCIIOTransportData*)axis_handle->transport_data;
	PMDuint16 status = 0;
	RETURN_CODE rc;
    HANDLE    hDevice = PIOtransport_data->hDrv; 
    PLX_INTR  intrTypes;

	memset(&intrTypes, 0, sizeof(PLX_INTR));
//	intrTypes.PciINTApin = 1; this has no effect
	intrTypes.IopToPciInt = 1;
#ifndef _LINUX	rc = PlxIntrAttach(hDevice, intrTypes, pEventHdl);
#endif
	// enable the "Local Interrupt 1 Enable" and "PCI Interrupt Enable" bits in the runtime register
	// note: after the interrupt occurs the "Local Interrupt 1 Enable" bit is cleared
	// see the PLX example code IntEvt.c for more info
	intrTypes.PciMainInt = 1;
	rc = PlxIntrEnable(hDevice, &intrTypes);

	//rc = PlxIntrStatusGet(hDevice, &intrTypes); // for debugging

	return (PMDuint16)(rc);
}

//*****************************************************************************
void PMDPCI_InitData(PMDPCIIOTransportData* transport_data)
{
	// assign default values
	memset(transport_data, 0, sizeof(PMDPCIIOTransportData));
	transport_data->hDrv = INVALID_HANDLE_VALUE;

	// by default always verify the checksum
	transport_data->bVerifyChecksum = 1;
	// by default enable diagnostics
	transport_data->bDiagnostics = 0;
	// by default set to first card found (numbering starts at 0)
	transport_data->nBoardNo = 0;

    transport_data->nBasePortAddress = 0;
    transport_data->nDeviceID = 0;
}

//*****************************************************************************
PMDuint16 PMDPCI_Init(void* handle)
{
	PMDAxisHandle* axis_handle = (PMDAxisHandle*) handle;

	// setup function pointers
	axis_handle->transport.SendCommand = PMDPCI_Send;
	axis_handle->transport.GetStatus = PMDPCI_GetStatus;
	axis_handle->transport.IsReady = PMDPCI_IsReady;
	axis_handle->transport.HasInterrupt = PMDPCI_HasInterrupt;
	axis_handle->transport.HasError = PMDPCI_HasError;
	axis_handle->transport.HardReset = PMDPCI_HardReset;
	axis_handle->transport.Close = PMDPCI_Close;

	return PMDPCI_InitPort((PMDPCIIOTransportData*)axis_handle->transport_data);
}

//*****************************************************************************
PMDuint16 PMDSetupAxisInterface_PCI(PMDAxisHandle* axis_handle, PMDAxis axis_number, int board_number)
{
	PMDPCIIOTransportData* transport_data;

	transport_data = (PMDPCIIOTransportData*) malloc( sizeof( PMDPCIIOTransportData ) );

	// set the axis we are talking to with this handle
	axis_handle->axis = axis_number;

	// set the interface type 
	axis_handle->InterfaceType = InterfacePCI;

	// the transport data is initialized first to setup the defaults
	// make sure the IO mode is set correctly
	PMDPCI_InitData(transport_data);

	// set the board we are talking to with this handle
	transport_data->nBoardNo = board_number;

	axis_handle->transport_data = (void*) transport_data;

	// initialize the transport (inits function pointers)
	return PMDPCI_Init(axis_handle);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -