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

📄 functions.c

📁 SERCOSII卡在 linux下的驱动。数控系统开发人员可以在此基础上
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "Functions.h"

pthread_t root_thread;
pthread_t acph_thread;
pthread_t syst_thread;
pthread_t diag_thread;//not used yet

BOOL bhard_enable_irq;
T_IPC_HANDLES ipc_handles;
SCS_TASK_t SCS_Task[MAX_NUM_TASKS];
unsigned char  hInt; 
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 )
{

	unsigned char bus,fun;
	//Scan SERCANSII PCI card
	if( pcibios_find_device(0x16f2,0x104a,0,&bus,&fun)!=PCIBIOS_SUCCESSFUL)//check 0x16f2? 0x104a=inventor id
	{
		rtl_printf("Not found SERCANSII card!\n");
		return 1;
	}
	//Map the Memory BAR0 
	if( pcibios_read_config_dword(bus,fun,PCI_BASE_ADDRESS_0, &base0))
	{
		rtl_printf("Not found SERCANSII base0!\n");
		return 1;
	}
	pbBaseAdress=(unsigned short *) ioremap(base0,4*1024);
	if (pbBaseAdress==0)
	{
		rtl_printf("error map SERCANSII base0!\n");
		return 1;
	}
	//Attach Interrupt 
	if(	pcibios_read_config_byte(bus,fun,PCI_INTERRUPT_LINE, &ipc_handles.hInterrupt))
	{
		rtl_printf("error Attach SERCANSII Interrupt!\n");
		return 1;
	}
	if (rtl_request_irq(ipc_handles.hInterrupt,SERCANS_ISR))
	{
		rtl_printf("error rtl_request_irq!\n");
		rtl_free_irq(ipc_handles.hInterrupt);
		return 1;
	}else{
		rtl_hard_enable_irq(ipc_handles.hInterrupt);
		bhard_enable_irq = 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)
	{
		rtl_printf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
//	rtl_printf("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;
/*	rtl_printf("sControlWord=0x%08x\n",sControlWord);
	rtl_printf("rRequestData.ulIdent_Nbr=0x%08x\n",rRequestData.ulIdent_Nbr);
	rtl_printf("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)
	{
		rtl_printf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
//	rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	sControlWord = 0x1;
	sControlWord |= ((sDataBlockElement & 0x7)<<8);
	if(!bSinglePara){
		sControlWord |= 0x8;
	}
//	rtl_printf("Request_HMIReadDriveParameter ulIDN=0x%08x\n",ulIDN);
	rRequestData.ulIdent_Nbr = ulIDN;
	rRequestData.uControlWord = sControlWord;
/*	rtl_printf("sControlWord=0x%08x\n",sControlWord);
	rtl_printf("rRequestData.ulIdent_Nbr=0x%08x\n",rRequestData.ulIdent_Nbr);
	rtl_printf("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)
//USHORT uDriveNbr 驱动器地址
//ULONG* pulData  操作数或列表型操作数的在list contain中的索引(只能是NC通道有对列表型操作数的访问)
//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));

//	rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	if(!(rResponseData.uStatusWord & 0x1))
	{
		return (SVCH_NO_READ);
	}
	else if (rResponseData.uStatusWord & 0x8000)
	{
//		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
//		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
//		rtl_printf("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)
	{
/*		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
		rtl_printf("rResponseData.usACT_LEN=0x%08x\n",rResponseData.usACT_LEN);
*/		
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
		*pusLength=rResponseData.usACT_LEN;
//		rtl_printf("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));

//	rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
	if(!(rResponseData.uStatusWord & 0x1))
	{
		return (SVCH_NO_READ);
	}
	else if (rResponseData.uStatusWord & 0x8000)
	{
//		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
//		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
//		rtl_printf("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)
	{
/*		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
		rtl_printf("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)
	{
		rtl_printf("SVCH_IN_USE\n");
		return (SVCH_IN_USE);
	}
//	rtl_printf("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)
	{
		rtl_printf("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{

		pListParameterDataWr = pbBaseAdress+0x28018;
		//pchData=(char *)pulData;
		memcpy(pListParameterDataWr,(void*)ph_ptr->vdata,sLength);
	//	memcpy((void*)rRequestData.Data_Cont,(void*)pulData,sLength);
	}
	rRequestData.uControlWord = sControlWord;

/*	rtl_printf("sControlWord=0x%08x\n",sControlWord);
	rtl_printf("Request_HMIWriteDriveParameter rRequestData.ulIdent_Nbr=0x%08x\n",rRequestData.ulIdent_Nbr);
	rtl_printf("Request_HMIWriteDriveParameter rRequestData.uControlWord=0x%08x\n",rRequestData.uControlWord);
*/
	memcpy( (NC_SERVICE_CHN*)pbDriveParameterDataWr, &rRequestData,sizeof(rRequestData));
	return(SVCH_OK);
}


USHORT Response_WriteDriveParameter (USHORT uDriveNbr, ULONG* pulData)
{
#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));

	if(!(rResponseData.uStatusWord & 0x2))
	{
		return (SVCH_NO_WRITE);
	}
	else if (rResponseData.uStatusWord & 0x8000)
	{
//		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
//		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
//		rtl_printf("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)
	{
/*		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
		rtl_printf("rResponseData.usACT_LEN=0x%08x\n",rResponseData.usACT_LEN);
*/		
		*pulData = 0;
		return (SVCH_FINISHED);
	}
	else
	{
		return (SVCH_NO_STATE);
	}
}
USHORT Response_HMIWriteDriveParameter (ULONG* pulData)
{
	char* pbDriveParameterDataRd;
	NC_SERVICE_CHN	 rResponseData;

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

	if(!(rResponseData.uStatusWord & 0x2))
	{
		return (SVCH_NO_WRITE);
	}
	else if (rResponseData.uStatusWord & 0x8000)
	{
//		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		memcpy((LARGE_INTEGER*)pulData, &(rResponseData.Data_Cont),4);
//		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
//		rtl_printf("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)
	{
/*		rtl_printf("rResponseData.uStatusWord=0x%08x\n",rResponseData.uStatusWord);
		rtl_printf("rResponseData.Data_Cont=0x%08x\n",rResponseData.Data_Cont);
		rtl_printf("rResponseData.usACT_LEN=0x%08x\n",rResponseData.usACT_LEN);
*/		
		*pulData = 0;
		return (SVCH_FINISHED);
	}
	else
	{
		return (SVCH_NO_STATE);
	}
}


void ReadCyclicData(USHORT uDriveNbr, T_CYC_DATA* psActualData, short sActualDataLength)
{
#define ACTUAL_DATA(_DrvAddr) (pbBaseAdress + _DrvAddr*0x48 + 0x00010000)
	char * pbDriveCyclicData;
	pbDriveCyclicData = ACTUAL_DATA(uDriveNbr);
//	rtl_printf("ReadCyclicData *pbDriveCyclicData=0X%08X\n",*(ULONG*)pbDriveCyclicData);
	memcpy((char*) psActualData, pbDriveCyclicData, sActualDataLength);
//	rtl_printf("ReadCyclicData *psActualData=0X%08X\n",*(ULONG*)psActualData);
}
void WriteCyclicData(USHORT uDriveNbr, T_CYC_DATA * psCommandData, short sCommandDataLength)
{
#define COMMAND_DATA(_DrvAddr) (pbBaseAdress + _DrvAddr*0x48)

⌨️ 快捷键说明

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