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

📄 sndshdlcend.c

📁 4510b的vxworks的BSP
💻 C
📖 第 1 页 / 共 3 页
字号:

LOCAL STATUS sndsHdlcEndMCastDel
    (
    HDLC_END_DEVICE* pDrvCtrl,	/* device pointer */
    char* pAddress		/* address to be deleted */
    )
    {
    int error;

    if ((error = etherMultiDel (&pDrvCtrl->end.multiList,
	     (char *)pAddress)) == ENETRESET)
	sndsHdlcEndConfig (pDrvCtrl);

    return (OK);
    }

/*****************************************************************************
*
* sndsHdlcEndMCastGet - get the multicast address list for the device
*
* This routine gets the multicast list of whatever the driver
* is already listening for.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sndsHdlcEndMCastGet
    (
    HDLC_END_DEVICE* pDrvCtrl,	/* device pointer */
    MULTI_TABLE* pTable		/* address table to be filled in */
    )
    {
    return (etherMultiGet (&pDrvCtrl->end.multiList, pTable));
    }

/*******************************************************************************
*
* sndsHdlcEndStop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sndsHdlcEndStop
    (
    HDLC_END_DEVICE *pDrvCtrl	/* device to be stopped */
    )
    {
    STATUS result = OK;
	HDLC_HCON	hdlchcon;


    /* TODO - stop/disable the device. */

	*(UINT32*)(&hdlchcon) = 0;
	SNDS_HDLC_REG_READ (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);
	hdlchcon.hcon_reg.txen = 0;
	hdlchcon.hcon_reg.rxen = 0;
	hdlchcon.hcon_reg.dtxen = 0;
	hdlchcon.hcon_reg.drxen = 0;
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);

	intDisable(pDrvCtrl->hdlcVecTx);
	intDisable(pDrvCtrl->hdlcVecRx);

	END_FLAGS_CLR(&pDrvCtrl->end,IFF_UP | IFF_RUNNING);

    return (result);
    }

/******************************************************************************
*
* sndsHdlcEndUnload - unload a driver from the system
*
* This function first brings down the device, and then frees any
* stuff that was allocated by the driver in the load function.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sndsHdlcEndUnload
    (
    HDLC_END_DEVICE* pDrvCtrl	/* device to be unloaded */
    )
    {
    END_OBJECT_UNLOAD (&pDrvCtrl->end);


	sndsHdlcEndStop (pDrvCtrl);
	sndsHdlcEndReset (pDrvCtrl);
	sndsHdlcEndFree (pDrvCtrl);

    /*  Free any shared DMA memory */

	if (pDrvCtrl->end.pNetPool)
		{
		netPoolDelete (pDrvCtrl->end.pNetPool);
		free (pDrvCtrl->end.pNetPool);
		}

	if (pDrvCtrl->hdlcEndClDescTbl[0].memArea)
		free (pDrvCtrl->hdlcEndClDescTbl[0].memArea);

	if (pDrvCtrl->hdlcEndMclConfig.memArea)
		free (pDrvCtrl->hdlcEndMclConfig.memArea);

	if (pDrvCtrl)
		free (pDrvCtrl);
	
    return (OK);
    }
/*******************************************************************************
*
* sndsHdlcEndPollStart - start polled mode operations
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sndsHdlcEndPollStart
    (
    HDLC_END_DEVICE* pDrvCtrl	/* device to be polled */
    )
    {
    return (OK);
    }

/*******************************************************************************
*
* sndsHdlcEndPollStop - stop polled mode operations
*
* This function terminates polled mode operation.  The device returns to
* interrupt mode.
*
* The device interrupts are enabled, the current mode flag is switched
* to indicate interrupt mode and the device is then reconfigured for
* interrupt operation.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS sndsHdlcEndPollStop
    (
    HDLC_END_DEVICE* pDrvCtrl	/* device to be changed */
    )
    {
    return (OK);
    }

/*******************************************************************************
*
* sndsHdlcEndReset- Reset the HDLC 
*
*/
LOCAL void	sndsHdlcEndReset
	(
	HDLC_END_DEVICE *pDrvCtrl	/* Pointer to the device */
	)
	{
		
	HDLC_HCON	hdlchcon;
		
	*(UINT32 *)(&hdlchcon) = 0;

	/*reset the frame length and receive buffer registers*/
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HMFLR, 0);
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HRBSR, 0);

	/*reset the tx,rx,dmatx,dmarx registers */
	hdlchcon.hcon_reg.txrs = 1;
	hdlchcon.hcon_reg.rxrs = 1;
	hdlchcon.hcon_reg.dtxrs = 1;
	hdlchcon.hcon_reg.drxrs = 1;
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HCON, hdlchcon.hcon_resetval);
	}		

/********************************************************************************
*
* sndsHdlcEndInitialize	- Initialize the HDLC driver.
*
*/

LOCAL void sndsHdlcEndInitialize
	(
	HDLC_END_DEVICE* pDevice
	)
	{
				
	HDLC_HMODE 	hdlchmode;
	HDLC_HCON  	hdlchcon;
	HDLC_HINTEN hdlchinten;				
    HDLC_HBRGTC hdlchbrgtc;


	/*Hmode Initialization*/
	*(UINT32*)(&hdlchmode) = 0;
	hdlchmode.hmode_reg.dformat = pDevice->dataFormat;		/*Data format */
	hdlchmode.hmode_reg.brgclock = 1;		/*BRG clock-MCLK2*/
	hdlchmode.hmode_reg.txclock = 4;		/*TX clock-BRGOUT2*/
	hdlchmode.hmode_reg.rxclock = 4;		/*Rx clock-BRGOUT2*/
	hdlchmode.hmode_reg.txoutput = 0;		/* Tx Output-Tx clocl*/
	hdlchmode.hmode_reg.rxlittle = 1;		/* Rx data in bus is little mode*/
	hdlchmode.hmode_reg.txlittle = 1;		/* Tx data in bus is little mode*/
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HMODE, hdlchmode.hmode_resetval);
	
	/*Hcon Initialization*/
	*(UINT32*)(&hdlchcon) = 0;
	hdlchcon.hcon_reg.brgen = 1;			/* BRG Counter Enabled*/
	hdlchcon.hcon_reg.txwd = 0;			/* TXWD-1 word mode selected*/
	hdlchcon.hcon_reg.rxwd = 0;			/* TXWD-1 word mode selected*/
	hdlchcon.hcon_reg.rxwa = 0;			/* No Invaled Bytes*/
	hdlchcon.hcon_reg.dtxstsk = 1;		/* DMA Tx Stops when not owner*/
	hdlchcon.hcon_reg.drxstsk = 1;		/* DMA Rx Stops when not owner*/
	hdlchcon.hcon_reg.txdtr = 1;			/* Tx Data Terminal Ready -Low*/
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HCON, hdlchcon.hcon_resetval);

	/*Hinten Initialization*/
	
	*(UINT32*)(&hdlchinten) = 0;
	hdlchinten.hinten_reg.rxmovie = 1;	/* Rx Memory Overflow Interrupt Enb*/
	hdlchinten.hinten_reg.drxfdie = 1;	/* DMA Rx Frame Done Interrupt Enb*/
	hdlchinten.hinten_reg.dtxfdie = 1;	/* DMA Tx Frame Done Interrupt Enb*/
	hdlchinten.hinten_reg.drxnlie = 1;	/* DMA Rx Null List Interrupt Enable*/
	hdlchinten.hinten_reg.drxnoie = 1;	/* DMA Rx Not owner Interrupt Enable*/
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HINTEN, hdlchinten.hinten_resetval);
	
	/*Baud Rate Set*/
		
	*(UINT32 *)(&hdlchbrgtc)=0;
	hdlchbrgtc.hbrgtc_reg.cnt_2 = 1;		/* CNT2 value =1*/
	hdlchbrgtc.hbrgtc_reg.cnt_1 = 0;		/* CNT1 value =0*/
	switch (pDevice->baudRate)
		{
		case 1200:
			hdlchbrgtc.hbrgtc_reg.cnt_0 = 1301;		/* CNT0 value =1301*/
			break;

		case 2400:
			hdlchbrgtc.hbrgtc_reg.cnt_0 = 650;		/* CNT0 value =650*/
			break;

		case 4800:
			hdlchbrgtc.hbrgtc_reg.cnt_0 = 324;		/* CNT0 value =324*/
			break;

		case 9600:
			hdlchbrgtc.hbrgtc_reg.cnt_0 = 162;		/* CNT0 value =162*/
			break;

		case 19200:
			hdlchbrgtc.hbrgtc_reg.cnt_0 = 80;		/* CNT0 value =80*/
			break;

		case 38400:
			hdlchbrgtc.hbrgtc_reg.cnt_0 = 40;		/* CNT0 value =40*/
			break;

		}
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HBRGTC, hdlchbrgtc.hbrgtc_resetval);

		/*Station Address Register */
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HSAR0, pDevice->hdlcAddr);
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HMASK, pDevice->hdlcHmask);

	/*Maximum Frame Length Register */
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HMFLR, MAXFRAMELENGTH);
		
	/* Receive Buffer Size Register */
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HRBSR, MAXFRAMEDATA);

	/* Preamble register */
	SNDS_HDLC_REG_WRITE (pDevice, SNDS_HPRMB, PREAMBLE_NRZ);

	/* Initialize Buffer Descriptor*/
	sndsHdlcTxBuffInitialize(pDevice);
	sndsHdlcRxBuffInitialize(pDevice);
	}			


/********************************************************************************
*
* sndsHdlcTxBuffInitialize - Initialize the Transmit Buffer Descriptor
*
*/

LOCAL void	sndsHdlcTxBuffInitialize
	(
	HDLC_END_DEVICE *pDrvCtrl	/* Pointer to the device being initialized */
	)
	{
	SNDSHDLCBD *CurrentTxBD;		
	SNDSHDLCBD *PrevTxBD=NULL;
	int 	count;

	for(count = 0; count < MAXTXBDCOUNT; count++)
		{
		if ((CurrentTxBD = (SNDSHDLCBD *)calloc(sizeof(SNDSHDLCBD), 1)) == NULL)
			return;
		(UINT32)CurrentTxBD += NON_CACHE_REGION;
		(UINT32)(CurrentTxBD->BufferDataPtr) = (SNDSHDLCFRAME *)calloc(sizeof(SNDSHDLCFRAME), 1);
		CurrentTxBD->BufferDataPtr += NON_CACHE_REGION;
		CurrentTxBD->BufferDataPtr &= BOWNERSHIP_CPU;
	 	CurrentTxBD->StatusLength = 0;
		CurrentTxBD->NextBD = NULL;

		if (count == 0)
			{
			pDrvCtrl->gpTxBDStart = CurrentTxBD;
			SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HDMATXPTR, *(UINT32*)(&CurrentTxBD));
			}
		else
			{
			PrevTxBD->NextBD = CurrentTxBD;
			}
		if (count == (MAXTXBDCOUNT - 1))
			{
			CurrentTxBD->NextBD = pDrvCtrl->gpTxBDStart;
			}
		PrevTxBD = CurrentTxBD;
		}
	}

	

/********************************************************************************
*
*sndsHdlcRxBuffInitialize - Initialize the Receive Buffer Descriptor
*
*/
LOCAL void	sndsHdlcRxBuffInitialize
	(
	HDLC_END_DEVICE *pDrvCtrl	/* Pointer to the device being initialized */
	)
	{
	SNDSHDLCBD *CurrentRxBD;		
	SNDSHDLCBD *PrevRxBD=NULL;
	int 	count;

	for(count = 0; count < MAXRXBDCOUNT; count++)
		{
		if ((CurrentRxBD = (SNDSHDLCBD *)calloc(sizeof(SNDSHDLCBD), 1)) == NULL)
				return;
		(UINT32)CurrentRxBD += NON_CACHE_REGION;
		(UINT32)CurrentRxBD->BufferDataPtr = (SNDSHDLCFRAME *)calloc(sizeof(SNDSHDLCFRAME), 1);
		CurrentRxBD->BufferDataPtr += NON_CACHE_REGION;
		CurrentRxBD->BufferDataPtr |= BOWNERSHIP_DMA;
		CurrentRxBD->StatusLength = 0;
		CurrentRxBD->NextBD = NULL;

		if (count == 0)
			{
			pDrvCtrl->gpRxBDStart = CurrentRxBD;
			SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HDMARXPTR, *(UINT32 *)(&CurrentRxBD));
			}
		else
			{
			PrevRxBD->NextBD = CurrentRxBD;
			}
		if (count == (MAXRXBDCOUNT - 1))
			{
			CurrentRxBD->NextBD = pDrvCtrl->gpRxBDStart;
			}
		PrevRxBD = CurrentRxBD;
		}
	}
/************************************************************************************
*
* sndsHdlcTxInt- Transmitter Handle Interrupt Controller 
*
*/

LOCAL void  sndsHdlcTxInt
	(
	HDLC_END_DEVICE *pDrvCtrl	/* Pointer to the device causing interrupt */
	)

	{
		
	HDLC_HSTAT	hdlchstat;

	SNDS_HDLC_REG_READ (pDrvCtrl, SNDS_HSTAT, hdlchstat.hstat_resetval);
		
	if(hdlchstat.hstat_reg.dtxfd == 1)
		pDrvCtrl->gHTxStatus.DMATxFD++;

	if(hdlchstat.hstat_reg.dtxabt == 1)
		pDrvCtrl->gHTxStatus.DMATxABT++;

	if(hdlchstat.hstat_reg.dtxnl == 1)
		pDrvCtrl->gHTxStatus.DMATxNL++;
	
	if(hdlchstat.hstat_reg.dtxno == 1)
		pDrvCtrl->gHTxStatus.DMATxNO++;

	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HSTAT, hdlchstat.hstat_resetval);
	}

/*******************************************************************************
*
* sndsHdlcRxInt- Receive Interrupt Controller
*
*/
LOCAL void  sndsHdlcRxInt
	(
	HDLC_END_DEVICE *pDrvCtrl	/* Pointer to the device causing interrupt */
	)

	{

	HDLC_HSTAT	hdlchstat;
	BOOL rxErr = FALSE;

	SNDS_HDLC_REG_READ (pDrvCtrl, SNDS_HSTAT, hdlchstat.hstat_resetval);
			
	if(hdlchstat.hstat_reg.drxfd == 1)
		{
		pDrvCtrl->gHRxStatus.DMARxFD++;
		if(hdlchstat.hstat_reg.rxcrce == 1) 
			{
			pDrvCtrl->gHRxStatus.RxCRCErr++;
			rxErr = TRUE;
			}
		}

	if(hdlchstat.hstat_reg.rxmov == 1) 
		{
		pDrvCtrl->gHRxStatus.DMARxMOV++;
		rxErr = TRUE;
		
		}
	if(hdlchstat.hstat_reg.drxnl == 1) 
		{
		pDrvCtrl->gHRxStatus.DMARxNL++;
		rxErr = TRUE;
		}
	if(hdlchstat.hstat_reg.drxno == 1) 
		{
		pDrvCtrl->gHRxStatus.DMARxNO++;
		rxErr = TRUE;
		}
	SNDS_HDLC_REG_WRITE (pDrvCtrl, SNDS_HSTAT, hdlchstat.hstat_resetval);
	
	if (rxErr == FALSE)
		netJobAdd ((FUNCPTR)sndsHdlcEndHandleRcvInt, (int)pDrvCtrl, hdlchstat.hstat_resetval, 0,0,0);
	}


/******************************************************************************
* sndsHdlcEndFree - Free the allocated TX and RX FD lists and buffers
* This function frees all the allocated TX and RX FDs and the associated buffers
*/
LOCAL void sndsHdlcEndFree
	(
	HDLC_END_DEVICE *pDrvCtrl	/* Pointer to the device being freed */
	)
	{
	SNDSHDLCBD	*pRxBD;
	SNDSHDLCBD	*pTxBD;
	UINT32 count;

	for (count = 0; (count < MAXTXBDCOUNT) && pDrvCtrl->gpTxBDStart; count++)
		{
		pTxBD = pDrvCtrl->gpTxBDStart;
		if (pDrvCtrl->gpTxBDStart->BufferDataPtr)
			{
			pDrvCtrl->gpTxBDStart->BufferDataPtr &= ~NON_CACHE_REGION;
			free ((UINT32 *)pDrvCtrl->gpTxBDStart->BufferDataPtr);
			}
		pDrvCtrl->gpTxBDStart = pDrvCtrl->gpTxBDStart->NextBD;
		(UINT32)pTxBD -= NON_CACHE_REGION;
		free (pTxBD);
		}

	for (count = 0; (count < MAXRXBDCOUNT) && pDrvCtrl->gpRxBDStart; count++)
		{
			pRxBD = pDrvCtrl->gpRxBDStart;
			if (pDrvCtrl->gpRxBDStart->BufferDataPtr)
			{
			pDrvCtrl->gpRxBDStart->BufferDataPtr &= ~NON_CACHE_REGION;
			free ((UINT32 *)(pDrvCtrl->gpRxBDStart->BufferDataPtr));
			}
		pDrvCtrl->gpRxBDStart = pDrvCtrl->gpRxBDStart->NextBD;
		(UINT32)pRxBD -= NON_CACHE_REGION;
		free (pRxBD);
		}
	*(UINT32 *)(&(pDrvCtrl->gpRxBDStart)) = *(UINT32 *)(&(pDrvCtrl->gpTxBDStart)) = 0;
	}

#endif	 /* INCLUDE_SNDS_HDLC_END */

⌨️ 快捷键说明

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