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

📄 functions.c

📁 SERCOSII卡驱动,通过该驱动程序可以在windowXp与RTX环境下运行自己编写的数控软件实现对数控设备的驱动。
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "Functions.h"


T_IPC_HANDLES ipc_handles;
SCS_TASK_t SCS_Task[MAX_NUM_TASKS];
char * pbBaseAdress;
USHORT usCount_NC_SERCOS_TAKT_SYNC_USER=1;
USHORT usCount_NC_SERCOS_TAKT_USER_ACC=1;
USHORT usNC_SERCOS_TAKT;
BOOL DriveExist[256];

ULONG SercansInit( void )
{
	PCI_SLOT_NUMBER     SlotNumber;
	PPCI_COMMON_CONFIG  PciData; 
	UCHAR               buffer[PCI_COMMON_HDR_LENGTH]; 
	LARGE_INTEGER       PCI_Adr,SCS_Adr;

	HANDLE  hInterrupt; 
	BOOL		bfound=0,bret;				//found the SERCANSII Card
    ULONG       i;                    // logical slot number for the PCI adapter
    ULONG       f;                    // function number on the specified adapter
    ULONG       bytesWritten;         // return value from RtGetBusDataByOffset
    ULONG       bus;                  // bus number
    BOOLEAN     flag;                  
	ULONG		Offset= 0;
	ULONG		nothingWritten = 0;
	ULONG       ulAdrSpace=0;
	//Scan SERCANSII PCI card
    PciData = (PPCI_COMMON_CONFIG) buffer; 
    SlotNumber.u.bits.Reserved = 0; 
    flag = TRUE; 
    for (bus=0; flag; bus++) { 
		if (bfound) break;
        for (i=0; i<PCI_MAX_DEVICES && flag; i++) { 
			if (bfound) break;
            SlotNumber.u.bits.DeviceNumber = i; 
 
            for (f=0; f<PCI_MAX_FUNCTION; f++) { 
				if (bfound) break;
                SlotNumber.u.bits.FunctionNumber = f; 
 
                bytesWritten = RtGetBusDataByOffset (
                    PCIConfiguration, 
                    bus, 
                    SlotNumber.u.AsULONG, 
                    PciData, 
                    Offset,
                    PCI_COMMON_HDR_LENGTH 
                    ); 
 
                if (bytesWritten == nothingWritten) { 
                    // out of PCI buses 
                    flag = FALSE; 
                    break; 
                } 
 
                if (PciData->VendorID == PCI_INVALID_VENDORID) { 
                    // no device at this slot number, skip to next slot 
                    break; 
                }

				if (PciData->u.type0.InterruptPin == 0) { 
                    // no pin number for this device - it was simply
					// illusion that it exists 
                    break; 
                }
                // A device is found, print out the PCI configuration information
				if (PciData->VendorID == 0x104a)
				{
		//			RtPrintf("SERCANSII_InterruptLine = %d\n",PciData->u.type0.InterruptLine);
		//			RtPrintf("bus:%d,device:%d,function:%d\n",bus,i,f);
					bfound=TRUE;
				}

          } 

        } 
    } 
	//Map the Memory BAR0 
	      PCI_Adr.QuadPart=PciData->u.type0.BaseAddresses[0];
		PCI_Adr.QuadPart=PCI_Adr.QuadPart-0x8;//0xda000000;
          bret=RtTranslateBusAddress( PCIBus,
                                      0,
                                      PCI_Adr,
                                      &ulAdrSpace,
                                      &SCS_Adr);
          /* Das Uebersetzen der PCI-Adresse ging schief */ 
          if( !bret )
          {
			RtPrintf("RtTranslateBusAddress error!\n");
			ExitProcess(1);
           }
      	  /* Bildet den Speicher der PCI-Karte in den virtuellen Speicher vom PC ab.                   */
          pbBaseAdress = (char *) RtMapMemory( SCS_Adr, 4000000,  TRUE);
          if( pbBaseAdress == NULL )
          {
			RtPrintf("RtMapMemory error!\n");
			ExitProcess(1);
          }

    // RTX interrupt handler code
    // RtAttachInterruptVector associates a handler routine with
    // a hardware interrupt.
    // Note: level triggered interrupts are not supported in the 
    //       Win32 environment
//	RtPrintf("PciData->u.type0.InterruptLine = %d\n",PciData->u.type0.InterruptLine);
  hInterrupt = RtAttachInterruptVector(
                                         NULL,              // thread attributes
                                         0,                 // stack size - 0 uses default
                                         SERCANS_ISR,  // handler routine
                                         NULL,// context
                                         RT_PRIORITY_MAX,                 // priority
                                         PCIBus,               // interface type
                                         0,                 // bus number
                                         PciData->u.type0.InterruptLine,    // bus interrupt level
                                         PciData->u.type0.InterruptLine );  // bus interrupt vector

    if (! hInterrupt)
    {
        //
        // TO DO: exception code here 
        RtWprintf(L"RtAttachInterruptVector error = %d\n",GetLastError());
		return 1;
//		ExitProcess(1);
    }
	return 0;
}

USHORT Request_ReadDriveParameter(USHORT uDriveNbr, ULONG ulIDN, short sDataBlockElement,BOOL bSinglePara)
{
#define NC_SERVICE_CHANNEL_WRITE(_DrvAddr) (pbBaseAdress+_DrvAddr*0x20+0x00040000)
#define NC_SERVICE_CHANNEL_Read(_DrvAddr)  (pbBaseAdress+_DrvAddr*0x20+0x00044000)

	char *	pbDriveParameterDataWr;
	char*	pbDriveParameterDataRd;
	short	sControlWord;
	NC_SERVICE_CHN	rRequestData = {0};
	NC_SERVICE_CHN	rResponseData = {0};
	
	pbDriveParameterDataWr = NC_SERVICE_CHANNEL_WRITE(uDriveNbr);
	pbDriveParameterDataRd = NC_SERVICE_CHANNEL_Read(uDriveNbr);

	memcpy( &rResponseData, (NC_SERVICE_CHN*) pbDriveParameterDataRd, sizeof(rResponseData));

	if (rResponseData.uStatusWord & 0x40)
	{
		RtPrintf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
//	RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	sControlWord = 0x1;
	sControlWord |= ((sDataBlockElement & 0x7)<<8);
	if(!bSinglePara){
		//Name,Unit等非List Parameter 只使用 List container #0
		//为方便起见,写List Parameter 虽然可以使用其它1-31个List container,但是仍然使用List container #0
		rRequestData.Data_Cont.QuadPart = 0;
		sControlWord |= 0x8;
	}
	rRequestData.ulIdent_Nbr = ulIDN;
	rRequestData.uControlWord = sControlWord;
/*	RtPrintf("sControlWord=0x%08x\n",sControlWord);
	RtPrintf("rRequestData.ulIdent_Nbr=0x%08x\n",rRequestData.ulIdent_Nbr);
	RtPrintf("rRequestData.uControlWord=0x%08x\n",rRequestData.uControlWord);*/
	memcpy( (NC_SERVICE_CHN*)pbDriveParameterDataWr, &rRequestData,sizeof(rRequestData));
	return(SVCH_OK);
}
USHORT Request_HMIReadDriveParameter(ULONG ulIDN, short sDataBlockElement,BOOL bSinglePara)
{

	char *	pbDriveParameterDataWr;
	char*	pbDriveParameterDataRd;
	short	sControlWord;
	NC_SERVICE_CHN	rRequestData = {0};
	NC_SERVICE_CHN	rResponseData = {0};
	
	pbDriveParameterDataWr = pbBaseAdress+0x28000;
	pbDriveParameterDataRd = pbBaseAdress+0x28000;

	memcpy( &rResponseData, (NC_SERVICE_CHN*) pbDriveParameterDataRd, sizeof(rResponseData));

	if (rResponseData.uStatusWord & 0x40)
	{
		RtPrintf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
//	RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	sControlWord = 0x1;
	sControlWord |= ((sDataBlockElement & 0x7)<<8);
	if(!bSinglePara){
		sControlWord |= 0x8;
	}
//	RtPrintf("Request_HMIReadDriveParameter ulIDN=0x%08x\n",ulIDN);
	rRequestData.ulIdent_Nbr = ulIDN;
	rRequestData.uControlWord = sControlWord;
/*	RtPrintf("sControlWord=0x%08x\n",sControlWord);
	RtPrintf("rRequestData.ulIdent_Nbr=0x%08x\n",rRequestData.ulIdent_Nbr);
	RtPrintf("rRequestData.uControlWord=0x%08x\n",rRequestData.uControlWord);*/
	memcpy( (NC_SERVICE_CHN*)pbDriveParameterDataWr, &rRequestData,sizeof(rRequestData));
	return(SVCH_OK);
}

USHORT Response_ReadDriveParameter(USHORT uDriveNbr, ULONG* pulData,USHORT *pusLength)
{
#define NC_SERVICE_CHANNEL_READ(_DrvAddr) (pbBaseAdress+_DrvAddr*0x20+0x00044000)

	char* pbDriveParameterDataRd;
	NC_SERVICE_CHN  	 rResponseData;

	pbDriveParameterDataRd = NC_SERVICE_CHANNEL_READ(uDriveNbr);
	memcpy ( &rResponseData, (NC_SERVICE_CHN*)pbDriveParameterDataRd, sizeof(rResponseData));

//	RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	if(!(rResponseData.uStatusWord & 0x1))
	{
		return (SVCH_NO_READ);
	}
	else if (rResponseData.uStatusWord & 0x8000)
	{
//		RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
//		RtPrintf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
//		RtPrintf("in function *pulData=0x%08x\n",*pulData);
		//*((LARGE_INTEGER*)psData) = rResponseData.Data_Cont;
		return (SVCH_ERROR);
	}
	else if (rResponseData.uStatusWord & 0x40)
	{
		return (SVCH_IN_PROGRESS);
	}
	else if (rResponseData.uStatusWord & 0x80)
	{
/*		RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		RtPrintf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
		RtPrintf("rResponseData.usACT_LEN=0x%08x\n",rResponseData.usACT_LEN);
*/		
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
		*pusLength=rResponseData.usACT_LEN;
//		RtPrintf("rResponseData.usACT_LEN=0x%08x,*pusLength =%d\n",rResponseData.usACT_LEN,*pusLength);
		return (SVCH_FINISHED);
	}
	else
	{
		return (SVCH_NO_STATE);
	}

}

USHORT Response_HMIReaDriveParameter(ULONG* pulData,USHORT *pusLength)
{

	char* pbDriveParameterDataRd;
	NC_SERVICE_CHN  	 rResponseData;

	pbDriveParameterDataRd = pbBaseAdress+0x28000;
	memcpy ( &rResponseData, (NC_SERVICE_CHN*)pbDriveParameterDataRd, sizeof(rResponseData));

//	RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	if(!(rResponseData.uStatusWord & 0x1))
	{
		return (SVCH_NO_READ);
	}
	else if (rResponseData.uStatusWord & 0x8000)
	{
//		RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
//		RtPrintf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
//		RtPrintf("in function *pulData=0x%08x\n",*pulData);
		//*((LARGE_INTEGER*)psData) = rResponseData.Data_Cont;
		return (SVCH_ERROR);
	}
	else if (rResponseData.uStatusWord & 0x40)
	{
		return (SVCH_IN_PROGRESS);
	}
	else if (rResponseData.uStatusWord & 0x80)
	{
/*		RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		RtPrintf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
		RtPrintf("rResponseData.usACT_LEN=0x%08x\n",rResponseData.usACT_LEN);
*/		
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
		*pusLength=rResponseData.usACT_LEN;
		return (SVCH_FINISHED);
	}
	else
	{
		return (SVCH_NO_STATE);
	}

}

USHORT Request_WriteDriveParameter(USHORT uDriveNbr,ULONG ulIDN, short sDataBlockElement, SERC_ARGS_t* ph_ptr, short sLength,BOOL bSinglePara)
{
#define NC_SERVICE_CHANNEL_WRITE(_DrvAddr) (pbBaseAdress+_DrvAddr*0x20+0x00040000)
#define NC_SERVICE_CHANNEL_Read(_DrvAddr)  (pbBaseAdress+_DrvAddr*0x20+0x00044000)
#define LIST_CONTAINER(_Index)  (pbBaseAdress+_Index*0x10000+0x00200000)

	char *	pbDriveParameterDataWr;
	char*	pbDriveParameterDataRd;
	char * pListParameterDataWr;

	short	sControlWord;
	NC_SERVICE_CHN	rRequestData = {0};
	NC_SERVICE_CHN	rResponseData = {0};
	
	pbDriveParameterDataWr = NC_SERVICE_CHANNEL_WRITE(uDriveNbr);
	pbDriveParameterDataRd = NC_SERVICE_CHANNEL_Read(uDriveNbr);

	memcpy( &rResponseData, (NC_SERVICE_CHN*) pbDriveParameterDataRd, sizeof(rResponseData));

	if (rResponseData.uStatusWord & 0x40)
	{
		RtPrintf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
//	RtPrintf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	sControlWord = 0x2;
	sControlWord |= ((sDataBlockElement & 0x7)<<8);
	if(!bSinglePara)
		sControlWord |= 0x8;
	rRequestData.ulIdent_Nbr = ulIDN;
	if(bSinglePara)
		//memcpy(&rRequestData.Data_Cont,&pulData,sLength);
		memcpy(&rRequestData.Data_Cont,&ph_ptr->ldata,sLength);
	else{
		//Name,Unit等非List Parameter 只使用 List container #0
		//为方便起见,写List Parameter 虽然可以使用其它1-31个List container,但是仍然使用List container #0
		rRequestData.Data_Cont.QuadPart = 0;
		
		pListParameterDataWr = LIST_CONTAINER(rRequestData.Data_Cont.QuadPart);
		//pchData=(char *)pulData;
		memcpy(pListParameterDataWr,(void*)ph_ptr->vdata,sLength);	
	//	memcpy((void*)rRequestData.Data_Cont,(void*)pulData,sLength);
	}
	rRequestData.uControlWord = sControlWord;

	memcpy( (NC_SERVICE_CHN*)pbDriveParameterDataWr, &rRequestData,sizeof(rRequestData));
	return(SVCH_OK);
}
USHORT Request_HMIWriteDriveParameter(ULONG ulIDN, short sDataBlockElement, SERC_ARGS_t* ph_ptr, short sLength,BOOL bSinglePara)
{

	char *	pbDriveParameterDataWr;
	char*	pbDriveParameterDataRd;
	char * pListParameterDataWr;

	short	sControlWord;
	NC_SERVICE_CHN	rRequestData = {0};
	NC_SERVICE_CHN	rResponseData = {0};
	
	pbDriveParameterDataWr = pbBaseAdress+0x28000;
	pbDriveParameterDataRd = pbBaseAdress+0x28000;

	memcpy( &rResponseData, (NC_SERVICE_CHN*) pbDriveParameterDataRd, sizeof(rResponseData));

	if (rResponseData.uStatusWord & 0x40)
	{
		RtPrintf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
	sControlWord = 0x2;
	sControlWord |= ((sDataBlockElement & 0x7)<<8);
	if(!bSinglePara)
		sControlWord |= 0x8;
	rRequestData.ulIdent_Nbr = ulIDN;
	if(bSinglePara)
		//memcpy(&rRequestData.Data_Cont,&pulData,sLength);
		memcpy(&rRequestData.Data_Cont,&ph_ptr->ldata,sLength);	
	else{

⌨️ 快捷键说明

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