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

📄 sccahdlcdrv.c

📁 支持VXWORKES操作系统下MPC860系列处理器地异步HDLC驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (NULL == (pSccDev->writeSem  =  semBCreate (SEM_Q_PRIORITY, SEM_FULL)  )  )			goto errExit;		if (NULL == (pSccDev->readSem =  semBCreate (SEM_Q_PRIORITY, SEM_FULL)  )  )			goto errExit; /******************************initian end*******************************************/       	  if (  (ahdlcDrvNum = iosDevAdd ( & pSccDev->devHdr, devName, ahdlcDrvNum ) ) ==    ERROR)	  	goto errExit;	  return (OK);   errExit:   		#ifdef USE_DMA		if(NULL  !=  pSccDev->precv_buf_malloc_address)			cacheDmaFree ( pSccDev->usr_recv_buf);		if(NULL  !=  pSccDev->ptran_buf_malloc_address )			cacheDmaFree ( pSccDev->ptran_buf_malloc_address);		#endif	     return  (ERROR);	         }/******************************************************/static	int	ahdlcOpen		(DEV_HDR *pDev, char *name, int mode){	SCC_AHDLC_DEV *  pSccDev = 	 (SCC_AHDLC_DEV * ) pDev ;		#ifdef  M_DEBUG	int i;	#endif		debug((" \n open  dev %s \n" , name));	if ( pDev == NULL )		{			errnoSet (2);			return (ERROR);		}	if( pSccDev->opened)		{                return (ERROR);	       }       pSccDev->opened = TRUE;	semGive (pSccDev->writeSem);		semGive (pSccDev->readSem);		 	#if 0	if( NULL == ( pSccDev->rsyncSem =semBCreate (SEM_Q_PRIORITY, SEM_FULL) ) )		return (ERROR);	if( NULL == ( pSccDev->tsyncSem = semBCreate (SEM_Q_PRIORITY, SEM_FULL) ) )		return (ERROR);	#endif     /*初始化用户缓冲和读写指针*/	 memset( ( char * ) pSccDev->usr_recv_buf , 0,  sizeof(BUFM_BUF)*SCC_AHDLC_RECV_BUF_NUM);	 pSccDev->rbuf_rptr =0;	 pSccDev->rbuf_wptr =0;	 	init_tranBD(pSccDev);	init_recvBD(pSccDev);    	 pSccDev->statistics.pnumCrcec =0;	AHDLC_RX_CS();      sccHdlcEnable(pSccDev);	/* enable the scc */	        #ifdef M_DEBUG  	 debug(("look up rx bd mod ???????? \n"));	 for(i = 0;i< SCC_NUM_RBD ;  i++)	 	{		debug((" %x ," ,  pSccDev->precv_BD[ i ].statusMode  & BD_RX_EMPTY_BIT   ));		 if( ( i%8) == 7)			debug((" \n"));	        }	  debug(("\n"));	#endif  	return ( (int )pDev );	   	}static	int	ahdlcRead		(int deviceid, char *pBuf, int buflen){	/* 对一些变量进行初始化操作*/	int read_length = ERROR;	BUFM_BUF * bufptr ;	/* 获得设备描述符并判断*/	SCC_AHDLC_DEV *  pSccDev =( SCC_AHDLC_DEV *)  deviceid ;	assert( (buflen-2) >0);	if( pSccDev  == (SCC_AHDLC_DEV * )NULL )	{		return (ERROR);	}		bufptr = & pSccDev->usr_recv_buf[pSccDev->rbuf_rptr];			while(0 == bufptr->status)			{			    return 0;			/*semTake(pSccDev->readSem, WAIT_FOREVER);*/			}	  bufptr->len-=2;       read_length =  bufptr->len < buflen ? bufptr->len : buflen ;	bcopy( (const char *)bufptr->body, (char *)pBuf, read_length);	/*	logMsg(" recv %x,%x \n" , bufptr->body[0],bufptr->body[96] );	printf( "addt rx %x, %x ,%x\n",   bufptr->body,txpbbuf, usrbuf);	*/	bufptr->status = 0;		  	pSccDev->rbuf_rptr++;	if( SCC_AHDLC_RECV_BUF_NUM <= pSccDev->rbuf_rptr)		pSccDev->rbuf_rptr = 0;	      pSccDev->ready_to_read =FALSE;	return ( read_length );	}static	int	ahdlcWrite	(int deviceid, char *pBuf, int buflen){	/* 对一些变量进行初始化操作*/	int write_length = ERROR;	/*BOOL found_error;*/	BUFM_BUF * bufptr ;	SCC_AHDLC_BD * pBD;		/* 获得设备描述符并判断*/	SCC_AHDLC_DEV *  pSccDev =( SCC_AHDLC_DEV *)  deviceid ;	if( pSccDev  == (SCC_AHDLC_DEV * )NULL )	{		return (ERROR);	}	if((0 >=buflen) || ( buflen > (AHDLC_MAX_PKT_LEN)))		return(-1);		semTake (pSccDev->writeSem , WAIT_FOREVER); 	pBD = &(pSccDev->ptran_BD[pSccDev->current_tBD]);		if( AHDLC_BD_TX_READY_BIT & (pBD->statusMode) ) /* current BD is busy, return without send.*/	{               return -1;	}	/* BD is empty */	 AHDLC_TX_CS();	/* set BD length */	pBD->dataLength = buflen;	/* copy data to BD's buffer */	bcopy( (const char *)pBuf, (char *)pBD->dataPointer, pBD->dataLength);	    	/* change the current transmite BD */	if( AHDLC_BD_TX_WRAP_BIT & pBD->statusMode )		pSccDev->current_tBD = 0;	else		pSccDev->current_tBD++;		/* set the ready bit .*/	pBD->statusMode |= AHDLC_BD_TX_READY_BIT | AHDLC_BD_TX_INTERRUPT_BIT | AHDLC_BD_TX_LAST_FRAME_BIT ;     	pSccDev->ready_to_write = FALSE;	return (buflen);}static	int   ahdlcIoctl	(int deviceid, int cmd, int arg){	int status = ERROR;	SCC_AHDLC_DEV *  pSccDev =( SCC_AHDLC_DEV *)  deviceid ;	 EPCFG  *cfg;	 int baudRate;				switch(cmd)		{			case FIOSELECT:			/*	add node to wakeup list	*/			status =selNodeAdd (&pSccDev->selWakeupkist, (SEL_WAKEUP_NODE *) arg);	         		if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELREAD )&&(pSccDev->ready_to_read))            			selWakeup ((SEL_WAKEUP_NODE *) arg);			if ((selWakeupType ((SEL_WAKEUP_NODE *) arg) == SELWRITE )&&(pSccDev->ready_to_write))            			selWakeup ((SEL_WAKEUP_NODE *) arg);			break;		case FIOUNSELECT:	       	 /* delete node from wakeup list */	       	 status =selNodeDelete (&pSccDev->selWakeupkist, (SEL_WAKEUP_NODE *) arg);	      		  break;				case SIO_BAUD_SET:	                debug(("set bauderate  = %d \n", arg));            		if (arg >=  1600 && arg <= 38400)	/* could go higher... */				{					/* calculate proper counter value, then enable BRG */                                     cfg = getEpCfg();					baudRate = (cfg->sysBrgClkFreq /16     - arg /2)  /  arg;							    				*pSccDev->pBaud = (   BRGC_CD_MSK &(baudRate  << BRGC_CD_SHIFT)   ) | BRGC_EN |BRGC_DIV16;					status = OK;					}		       else if(arg>38400  && arg <= 115200 )		       	{					       cfg = getEpCfg();						baudRate = (cfg->sysBrgClkFreq    - arg /2)  /  arg;						*pSccDev->pBaud = (   BRGC_CD_MSK &(baudRate  << BRGC_CD_SHIFT)   ) | BRGC_EN  ;						status = OK;			   	}			       else	      			  status = EIO;	  	  break;    					case SIO_BAUD_GET:			  cfg = getEpCfg();			 baudRate = *pSccDev->pBaud;			 baudRate =    ( (1+  ((baudRate  & BRGC_CD_MSK)>>BRGC_CD_SHIFT)  ) ) * ( 1 + (baudRate & BRGC_DIV16)*15  );						* (int *)arg  = cfg->sysBrgClkFreq /baudRate ;				status = OK;	 	  	 break;		case FIOOPTIONS:				if(1 == arg)					{						AHDLC_TX_CS();					}				else					{						AHDLC_RX_CS();					}					status = OK;			break;			case FIOREADYCHANGE:				/* errot get */			memcpy((char *)arg, (char *)&pSccDev->statistics , sizeof(SCC_AHDLC_STATISTIC) );			status = OK;			 break;		case FIONWRITE:			/*reset error count*/			bzero((char *)&pSccDev->statistics ,sizeof(SCC_AHDLC_STATISTIC)  );			status = OK;			break;		default :			status = ERROR;			break;		}	return 	status ;	}static	int	ahdlcClose(int deviceid){	/* 获得设备描述符并判断*/	SCC_AHDLC_DEV *  pSccDev =( SCC_AHDLC_DEV *)  deviceid ;	if( pSccDev  == (SCC_AHDLC_DEV * )NULL )	{		return (ERROR);	}	/* 关闭中断*/		AHDLC_RX_CS();		sccHdlcDisable(pSccDev);		 pSccDev->opened = FALSE ;	  	 debug((" \n close  AHDLC !\n" ));	/*释放缓冲区*/}int	ahdlcAttach(void){	ahdlcDrv();	ahdlcDevCreate("/ahdlc");	return OK;}/************use for test *************************/void dtt (int data){int i;int j;int k;#define  AHDLC_TXD     0x0080#define  AHDLC_RXD     0x0040	int immrval;      EPCFG  *cfg = getEpCfg();	immrval = vxImmrGet();	if(0 == data)		{	  	 AHDLC_TX_CS();	   			/* General-purpose I/O.*/		*PAPAR(immrval) &= (~AHDLC_TXD );			/*Select the signal for general-purpose output*/		*PADIR(immrval)|=AHDLC_TXD ;		*PADAT(immrval) &= (~AHDLC_TXD );				printf(" CS : 1 ,TXD : 0 \n ");		}	else if( 1 ==data )		{		 AHDLC_TX_CS();	   			/* General-purpose I/O.*/		*PAPAR(immrval) &= (~AHDLC_TXD );			/*Select the signal for general-purpose output*/		*PADIR(immrval)|=AHDLC_TXD ;		*PADAT(immrval) |= AHDLC_TXD ;				printf(" CS: 1 ,TXD : 1 \n ");			}	else if( 3 ==data )		{		 AHDLC_RX_CS();	   			/* General-purpose I/O.*/		*PAPAR(immrval) &= (~AHDLC_TXD );		*PAPAR(immrval) |= AHDLC_RXD ;			/*Select the signal for general-purpose output*/		*PADIR(immrval)|=AHDLC_TXD ;		/*Select the signal for general-purpose intput*/		*PADIR(immrval)&=(~AHDLC_RXD) ;				*PADAT(immrval) |= AHDLC_TXD ;				printf(" CS: 0 ,TXD : 1,read Rx \n ");		k=0;		for(j=0;j<100;j++)			{			taskDelay(sysClkRateGet( )/50);			i = (*PADAT(immrval) & AHDLC_RXD);		       if(i)k++;			printf("RXD  %x \n" , i );						}		printf("1 num %d \n" ,k);		}	else		{					init_ports();			printf(" CS: 0 ,TXD : 1 , default set !\n");		}}/****************************************************************************** Function: ahdlcTxdModeSet* Author: JinGu	* Description: TXD模式设置,用于控制FPGA TXD脚输出方式* Parameters:  mode: 0: FPGA TXD常0; 1: FPGA TXD常1; 2:FPGA 直接输出PPC TXD* Returns: OK or ERROR     *****************************************************************************/INT32 ahdlcTxdModeSet(INT8 mode){	switch(mode)	{		case 0:			*REG_LX30T_AHDLC_DATA = 0;			*REG_LX30T_AHDLC_CTRL = 1;			AHDLC_TX_CS();			printf(" CS: 1 ,TXD : 0 \n ");				break;					case 1:			*REG_LX30T_AHDLC_DATA = 1;			*REG_LX30T_AHDLC_CTRL = 1;			AHDLC_TX_CS();			printf(" CS: 1 ,TXD : 1 \n ");				break;					case 2:			*REG_LX30T_AHDLC_CTRL = 0;			AHDLC_RX_CS();			printf(" CS: 0 ,TXD : 1 , default set !\n");			break;		default:			return ERROR;				}	return OK;}UINT8	ahdlcRxdModeRet(void){        UINT8  data;	data = 	(*REG_LX30T_AHDLC_DATA&0x2)>>1;	printf("RXD  %x \n" , data );	return data;}#endif /* defined(INCLUDE_AHDLC) */

⌨️ 快捷键说明

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