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

📄 qmc__hdl.c

📁 基于vxworks操作系统的电话语音平台系统
💻 C
字号:
/************************************************************************/
/*                                                              		*/
/*                                                              		*/
/* (C) Copyright Bangyan Information Technology Ltd, 2000/9.            */
/*  All right reserved                                          		*/
/*                                                              		*/
/* Author: Zhuguosheng 	                                  				*/
/*                                                              		*/
/* Description:                                                 		*/
/*     Driver Set - QMC hdlc specific routines.            				*/
/*                                                              		*/
/* Routines                                                     		*/
/*     hdlc_qmc_tx                                              		*/
/*     hdlc_rx_internal                                         		*/
/*     hdlc_tx_internal                                         		*/
/*     qmc_hdlc_interrupt                                           	*/
/*                                                              		*/
/************************************************************************/

#include "PUB\PUB_INCL.H"
#include "DRVS\DRV860\PUB\NETCOMM.H"
#include "DRVS\DRV860\PUB\D860_PUB.H"
#include "DRVS\DRV860\PUB\MPC860.H"
#include "DRVS\DRV860\PUB\MASKS860.h"
#include "DRVS\DRV860\QMC\QMC.H"



extern QMC_TABLE        qmc_table;
extern QUICC_32_MANAGER mgr;
extern EPPC             *quicc;
extern VOID RestartQmcChannelRecv( UC scc_num, UC channel_num );
extern VOID RestartQmcChannelSend(UC channel_num );
extern VOID DrvRecvMsu( SI channel_num, VOID *buf, SI length );
extern VOID qmc_glob_underrun(SI scc_num);
extern VOID qmc_glob_overrun(SI scc_num);
extern VOID qmc_chan_underrun(SI chan_num);
extern VOID qmc_chan_overrun(SI chan_num);
extern VOID qmc_chan_CRC_error(SI chan_num);
extern CommReportToNetMan( UC,UC,UI,UC*);



extern SEM_ID SemQMCHdlcSend_ID[64];

UL TestQmcRecvMsgTimes=0;
UL TestQmcRecvMsgFailTimes=0;
UL TestQmcSendMsgTimes=0;
UL TestQmcChansSendMsgTimes[64]={0};
UL TestQmcChansRecvMsgTimes[64]={0};
UL TestQmcChansRecvBsyTimes[64]={0};
UL TestQmcChansSendMissTimes[64]={0};
UL TestQmcChansCrcErrorTimes[64]={0};


int_routine     qmc_hdlc_interrupt;
SI hdlc_qmc_tx(SI channel_num, VOID *buf, SI length, SI int_ena);
STATIC VOID hdlc_rx_internal(SI channel_num);
STATIC VOID hdlc_tx_internal(SI channel_num);
VOID qmc_hdlc_interrupt(UI interrupt_event);
VOID qmc_mgr_interrupt(SI scc_num);



BOOL hdlc_qmc_tx_buf_is_full(UI channel_num)
{
	register QUICC_BD *tbd;

	tbd = qmc_table[channel_num].NextFreeTbd;

	if( (tbd->status&T_R)==T_R )
	{
		return TRUE;
	}

	return FALSE;
}

VOID QmcPrintTxBdStatus(QUICC_BD *tbd, SI channel_num)
{
	QUICC_BD *print_db;

	UI i;

	print_db=tbd;

	for( i=0; i<32; i++ )
	{
		INCREASE_TBD_32(print_db, quicc, qmc_table[channel_num].scc_number, channel_num);
	}
}

SI hdlc_qmc_tx(SI channel_num, VOID *buf, SI length, SI int_ena)
{
	SI i, old_sr, rc = TRUE;
	register QUICC_BD *tbd;
	struct qmc_hdlc_pram  *pram;

	pram = CHANNEL_PRAM_BASE(quicc,channel_num);

	/* Is there free TDB ?*/
	/* Point to next free TBD*/
	tbd = qmc_table[channel_num].NextFreeTbd;

	/* This TBD must be free, if we not in continuous mode.*/
	if( (tbd->status&T_R)==T_R )
	{
		/*It is added by zhuguosheng in 2002/07/28 for Debug, when the queue is full.*/
		QmcPrintTxBdStatus(tbd, channel_num);

		/*BYPrintf("@@@@@@@@@@@@@@@@@@@@@@CHAN %d IN T_R MODE@@@@@@@@@@@@@@@@@@@@@@", channel_num);*/

		rc = FALSE;
	}
	else
	{
		tbd->length  = (UI)length;
		memcpy( tbd->buf, buf, length );
		tbd->status &= T_W;              /* Clear all except Wrap bit*/
		tbd->status |= T_R | T_L | T_TC; /* Ready to transmittion*/

		if (qmc_table[channel_num].continuous_tx)
			tbd->status |= T_CM;         /* Continuous mode*/
		if (int_ena)
			tbd->status |= T_I;          /* Enable interrupt if required*/
	
		pram->chamr |= HDLC_CHAMR_POL;   /* Enable polling*/

		qmc_table[channel_num].tbd_len++;

		INCREASE_TBD_32(qmc_table[channel_num].NextFreeTbd, quicc, qmc_table[channel_num].scc_number, channel_num);

		TestQmcSendMsgTimes++;
		TestQmcChansSendMsgTimes[channel_num]++;
	}

	return rc;
}

UL channel36error=0,channel36right=0;
UL channel33right=0,channel33error=0;
UL error_len_msg=0;
UL channelrightmsunum=0;
STATIC VOID hdlc_rx_internal(SI channel_num)
{
	QUICC_BD *rbd;
	SI      once = 1;

	rbd = qmc_table[channel_num].rbd;

	while(qmc_table[channel_num].continuous_rx ? once : (!(rbd->status & R_E)))
	{
		once = 0;
		if (rbd->status & HDLC_QMC_R_ERROR)
		{
			rbd->status &= ~HDLC_QMC_R_ERROR;
			qmc_chan_CRC_error(channel_num);
			TestQmcChansCrcErrorTimes[channel_num]++;

			QmcCrcErrorNum[channel_num]++;
		}
		else
		{
			if( rbd->length == 2 )
				QmcShortPacketNum[channel_num]++;

			if( rbd->length>=3 && rbd->length<MRBLR_T )
				channelrightmsunum++;

			TestQmcChansRecvMsgTimes[channel_num]++;
			DrvRecvMsu( channel_num, rbd->buf,rbd->length-2);
		}

		/* Reset this buffer status to be ready to next reception.*/
		if (!qmc_table[channel_num].continuous_rx)
		{
			rbd->status &= R_W;
			rbd->status |= R_E | R_I;
		}

		INCREASE_RBD_32(rbd, quicc, qmc_table[channel_num].scc_number, channel_num);
	}

	qmc_table[channel_num].rbd = rbd;
}


STATIC VOID hdlc_tx_internal(SI channel_num)
{
/*	QUICC_BD             *tbd;

	tbd = qmc_table[channel_num].tbd;

	while(qmc_table[channel_num].tbd_len && (!(tbd->status & T_R)))
	{
		tbd->status &= T_W;
		tbd->status |= T_I;

		INCREASE_TBD_32(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
		
		if( qmc_table[channel_num].tbd_len>0 )
			qmc_table[channel_num].tbd_len--;
	}

	qmc_table[channel_num].tbd = tbd;
*/
/*	UI sended_bds,i;

	tbd = qmc_table[channel_num].tbd;
	
	sended_bds = qmc_table[channel_num].tbd_len;
	for( i=0; i<qmc_table[channel_num].no_of_trn_bd; i++ )
	{
		if( (tbd->status&T_R)!=T_R )
		{
			tbd->status &= T_W;
			tbd->status |= T_I;
	
			INCREASE_TBD_32(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
			
			if( qmc_table[channel_num].tbd_len>0 )
				qmc_table[channel_num].tbd_len--;
		}
		else
		{
			qmc_table[channel_num].tbd = tbd;

			break;
		}
	}
*/
}

VOID qmc_hdlc_interrupt(UI interrupt_event)
{
	UI event;
	UI channel_num;

	channel_num = (interrupt_event & INTR_CH_NU) >> 6;
	event = interrupt_event & INTR_MASK_BITS;

	if (event &  HDLC_UN)       /* transmit underrun*/
	{
		QUICC_BD       *tbd;


		tbd = TBD_32_CUR_ADDR(quicc, qmc_table[channel_num].scc_number, channel_num);
		DECREASE_TBD_32(tbd,quicc, qmc_table[channel_num].scc_number, channel_num);

/*		if( ((*qmc_table[channel_num].handle_tx_error_ptr)
			 (qmc_table[channel_num].scc_number, channel_num, tbd)))
		{
			TBD_32_SET_CUR_ADDR(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
			tbd->status |= T_R | T_L | T_TC;
		}
*/
		tbd->status &= ~HDLC_UN;

		hdlc_tx_internal(channel_num);
	}
	if( event & HDLC_BSY )
	{
/*		RestartQmcRecvChannel( channel_num );*/

		RestartQmcChannelRecv( qmc_table[channel_num].scc_number, channel_num );
	}
	if (event & HDLC_TXB)
	{
		hdlc_tx_internal(channel_num);
	}
	if (event & HDLC_RXF)
	{
		hdlc_rx_internal(channel_num);
	}
	if (event & HDLC_RXB)
	{
		hdlc_rx_internal(channel_num);
	}
}


UL HDLC_UN_Times=0;
UL HDLC_BSY_Times=0;
VOID QmcEventHdl(UI interrupt_event,UI scc_num)
{
	UI event;
	UI channel_num;

	channel_num = (interrupt_event & INTR_CH_NU) >> 6;

	event = interrupt_event & INTR_MASK_BITS;

	if (event &  HDLC_UN)       /* transmit underrun*/
	{
		QUICC_BD       *tbd;

		tbd = TBD_32_CUR_ADDR(quicc, qmc_table[channel_num].scc_number, channel_num);
		DECREASE_TBD_32(tbd,quicc, qmc_table[channel_num].scc_number, channel_num);
/*		if (qmc_table[channel_num].handle_tx_error_ptr  &&
			((*qmc_table[channel_num].handle_tx_error_ptr)
			 (qmc_table[channel_num].scc_number, channel_num, tbd)))
		{
			TBD_32_SET_CUR_ADDR(tbd, quicc, qmc_table[channel_num].scc_number, channel_num);
			tbd->status |= T_R | T_L | T_TC;
		}
*/
		tbd->status &= ~HDLC_UN;

		hdlc_tx_internal(channel_num);

		HDLC_UN_Times++;

		qmc_chan_underrun(channel_num);
	}
	if( event & HDLC_BSY )
	{
		HDLC_BSY_Times++;

		TestQmcChansRecvBsyTimes[channel_num]++;

		qmc_chan_overrun(channel_num);
	}
	if (event & HDLC_TXB)
	{
		hdlc_tx_internal(channel_num);
	}
	if (event & HDLC_RXF)
	{
		hdlc_rx_internal(channel_num);
	}
	if (event & HDLC_RXB)
	{
		hdlc_rx_internal(channel_num);
	}/*Temp disable it.*/
}


UL QMC_SCCM_GOV_Times=0;
UL QMC_SCCM_GUN_Times=0;
UL QMC_SCCM_IQOV_Times=0;

VOID qmc_mgr_interrupt(SI scc_num)
{
	struct scc_regs          *regs;
	UI           old_sr;
	UI           event;
	UI           cur_intr;
	struct global_qmc_pram *base;

	base = QMC_BASE(quicc, scc_num);

	regs = &quicc->scc_regs[scc_num];
	event = regs->scc_scce;

/*	 clear the event register*/
	CLEAR_BIT(regs->scc_scce, event);

	/* clear the interrupt in service register*/
	switch(scc_num)
	{
		case GLB_SCC_0:
			CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC1);
			break;
		case GLB_SCC_1:
			CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC2);
			break;
		case GLB_SCC_2:
			CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC3);
			break;
		case GLB_SCC_3:
			CLEAR_BIT(quicc->cpmi_cisr,INTR_SCC4);
			break;
	}

	if(event & QMC_SCCM_GOV)
	{
		qmc_glob_overrun(scc_num);

		QMC_SCCM_GOV_Times++;
	}
	if(event & QMC_SCCM_GUN)
	{
		qmc_glob_underrun(scc_num);

		QMC_SCCM_GUN_Times++;
	}
	if(event & QMC_SCCM_IQOV)
	{
		QMC_SCCM_IQOV_Times++;
	}

	if(event & QMC_SCCM_GINT)
	{
		/* go over the interrupt queue and handle it*/
		while( (cur_intr = (*(mgr.CurrIntr[scc_num]))) & INTR_VALID)
		{
			/* call the appropiate interrupt handler*/
/*			qmc_hdlc_interrupt (cur_intr);*/
			QmcEventHdl(cur_intr,scc_num);

			/* valid the entry , clear events*/
			*(mgr.CurrIntr[scc_num]) &= INTR_WRAP;
			if( cur_intr & INTR_WRAP)
				mgr.CurrIntr[scc_num] = (UI *)base->intbase;
			else
				(mgr.CurrIntr[scc_num])++;
		}
	}
}

⌨️ 快捷键说明

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