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

📄 qmc_init.c

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

#ifdef _NUCLEUS_RTOS
#include "RTOS\NUCLEUS\TASK\TASK_NUC.H"
#endif

#include "PUB\PUB_INCL.H"
#include "DRVS\DRV860\PUB\NETCOMM.H"       /* global defines */
#include "DRVS\DRV860\PUB\D860_PUB.H"
#include "DRVS\DRV860\PUB\MPC860.H"       /* IMMR definitions and declarations */
#include "DRVS\DRV860\PUB\MASKS860.h"      /* Global masks header file */
#include "DRVS\DRV860\QMC\QMC.H"


extern EPPC      *quicc;
QMC_TABLE        qmc_table;
QUICC_32_MANAGER mgr;
STATIC UC ReinitQmcFlag=0;
UC QmcIsReinitiating=0;

extern VOID qmc_hdlc_interrupt(UI interrupt_event);
extern VOID glob_overrun(SI scc_number);
extern VOID glob_underrun(SI scc_number);
extern VOID intr_q_overflow(SI scc_number);
extern VOID scc_loopback(SI scc_num);

extern VOID scc_start(SI scc_num);

extern SCC_TABLE scc_table; 



/* allocate memory for interrupt table */
SC 	intr_tbl_scc1[INTR_MEM_SPACE];
SC 	intr_tbl_scc2[INTR_MEM_SPACE];

VOID InitQmcScc(VOID);
VOID ReInitQmcScc(VOID);

STATIC VOID InitQmcRegisters( VOID )
{
	quicc->si_simode = 0x00d800d8L;

/*	quicc->si_sicr   |= 0x40400000L;*/ /*Map SCC4 and SCC1*/
	quicc->si_sicr   |= 0x40000040L;  /*Map SCC4 and SCC3*/

	quicc->si_sigmr  = 0x0E;

	quicc->pio_papar  = 0xFFFF;
	quicc->pio_padir |= 0x00F0;
	quicc->pio_paodr &= 0xFF0F;

	quicc->pio_pcpar |= 0X0E00;
	quicc->pio_pcdir |= 0X0E00;
	quicc->pio_pcso  |= 0X0001;

	quicc->dma_sdcr= 0x00000001;

	quicc->si_sicmr = 0;

	quicc->cpmi_cicr = 0x00189F80;

#ifdef _NUCLEUS_RTOS
	quicc->siu_simask = 0X00000000;
#endif
}

STATIC VOID QmcSIRamInit( VOID )
{
	UI i;

	/*------------------------------------------config SCC1---------------------------------*/
	/*Set L1RCLKa and L1RSYNCa Related to SIRAM and config to SCC1*/
	for( i=0; i<32; i++ )
	{
		quicc->si_siram[i] = 0x00420000; /*0,0,0000,0,001,0000,1,0*/
	}
	quicc->si_siram[31]    = 0x00430000;

	/*Set L1TCLKa and L1TSYNCa Related to SIRAM and config to SCC1*/
	for( i=0; i<32; i++ )
	{
		quicc->si_siram[64+i] = 0x00420000; /*0,0,0000,0,001,0000,1,0*/
	}
	quicc->si_siram[64+31]    = 0x00430000;

	/*------------------------------------------config SCC4---------------------------------*/
	/*Set L1RCLKb and L1RSYNCb Related to SIRAM and config to SCC4*/
	for( i=0; i<(16+NUM_OF_HTB_CHAN); i++ )
	{
		quicc->si_siram[32+i] = 0x01020000; /*0,0,0000,0,100,0000,1,0*/
	}
	quicc->si_siram[32+15+NUM_OF_HTB_CHAN]    = 0x01030000;

	/*Set L1TCLKb and L1TSYNCb Related to SIRAM and config to SCC4*/
	for( i=0; i<(16+NUM_OF_HTB_CHAN); i++ )
	{
		quicc->si_siram[96+i] = 0x01020000; /*0,0,0000,0,100,0000,1,0*/
	}
	quicc->si_siram[96+15+NUM_OF_HTB_CHAN]    = 0x01030000;
}



STATIC VOID qmc_scc_init(SI scc_num, SI first_log_chan,MULTI_CHAN_SETUP *setup)
{

	struct global_qmc_pram *base;
	SI i, *j;
	struct scc_regs *regs;

	/* initialize the multi channel parameter ram*/
	base = (struct global_qmc_pram *)QMC_BASE(quicc, scc_num);

	base->mcbase = setup->mcbase;
	base->qmcstate = QMC_STATE;

	base->mrblr = setup->mrblr;

	base->grfthr = base->grfcnt = setup->grfthr;

	base->intbase = base->intptr = (UL)setup->intbase;

	base->c_mask16 = C_MASK_CCITT16;
/*	base->c_mask32 = C_MASK_CCITT32;*/

	for(i=0; i<setup->tx_max_time_slot; i++)
		base->tsattx[i]=0;
	base->tsattx[--i] |= WRAP_SLOT;

	/* prepare the interrupt table, set the wrap bit on the last entry*/
	j=(SI *)base->intbase;
	for(i=0; i<(setup->inter_tbl_size/sizeof(SI)); i++)
		(*(j++))=0;
	(*(--j)) = INTR_WRAP;

	mgr.CurrIntr[scc_num] = (UI *)base->intbase;
	mgr.num_of_bds[scc_num] = 0;
	mgr.allocated_bds[scc_num] = MAX_NUM_OF_BDS;

	/* set up the mask register*/
	regs = &quicc->scc_regs[scc_num];


	/* set multi channel mode*/
	regs->scc_gsmr_l = MODE_MULTI_CHANNEL;
	regs->scc_gsmr_h = 0x780L;

	/* mask all interrupts*/
	regs->scc_scce = 0xffff;
	regs->scc_sccm = QMC_SCCM_IQOV|QMC_SCCM_GINT|QMC_SCCM_GUN|QMC_SCCM_GOV;
}

STATIC SI hdlc_qmc_init( SI                        scc_number,
				  SI                        channel_num,
				  SI                       	number_of_rx_buf,
				  SI                       	number_of_tx_buf,
				  HDLC_QMC_SPECIFIC         *hdlc_spec)
{
	QUICC_BD                 *rbd;
	QUICC_BD                 *tbd;
	struct qmc_hdlc_pram	 *pram;
	struct scc_regs          *regs;
	SI                      i,num_of_bds;
	struct global_qmc_pram *base;

	/* channel_num must be valid and initialized.*/
	if (channel_num < 0 || channel_num >= NUM_OF_CHANNELS )
		return -1;

	qmc_table[channel_num].scc_number = scc_number;
	qmc_table[channel_num].continuous_rx = hdlc_spec->continuous_rx;
	qmc_table[channel_num].continuous_tx = hdlc_spec->continuous_tx;
	qmc_table[channel_num].max_frame_length = hdlc_spec->max_frame_length;
	qmc_table[channel_num].no_of_rcv_bd = number_of_rx_buf;
	qmc_table[channel_num].no_of_trn_bd = number_of_tx_buf;
	qmc_table[channel_num].init_flag    = 1;

	base = QMC_BASE(quicc, scc_number);
	pram = CHANNEL_PRAM_BASE(quicc, channel_num);

	num_of_bds = mgr.num_of_bds[scc_number];
	mgr.num_of_bds[scc_number] =  mgr.num_of_bds[scc_number] \
							   + (qmc_table[channel_num].no_of_rcv_bd\
							   + qmc_table[channel_num].no_of_trn_bd);

	if( mgr.num_of_bds[scc_number] > mgr.allocated_bds[scc_number] )
	{
		mgr.num_of_bds[scc_number] = num_of_bds;
		return( -1);
	}

	pram->rbase = num_of_bds*sizeof(QUICC_BD);
	pram->rbptr = num_of_bds*sizeof(QUICC_BD);
	rbd = RBD_32_ADDR(quicc, scc_number, channel_num);
	qmc_table[channel_num].rbd = rbd;
	qmc_table[channel_num].FirstRxBd = rbd;
	for(i = 0; i <qmc_table[channel_num].no_of_rcv_bd; i++)
	{
		rbd->length = 0;
		rbd->status = R_E | R_I | (hdlc_spec->continuous_rx ? R_CM : 0);
		if( ReinitQmcFlag==0 )
		{
			rbd->buf=BYMalloc(hdlc_spec->max_frame_length);
		}
		rbd++;
	}
	--rbd;
	rbd->status |= R_W;
	pram->tbase = (qmc_table[channel_num].no_of_rcv_bd+num_of_bds)*(sizeof(QUICC_BD));
	pram->tbptr = (qmc_table[channel_num].no_of_rcv_bd+num_of_bds)*(sizeof(QUICC_BD));
	tbd = TBD_32_ADDR(quicc, scc_number, channel_num);
	qmc_table[channel_num].tbd = tbd;
	qmc_table[channel_num].NextFreeTbd = tbd;
	qmc_table[channel_num].tbd_len = 0;
	qmc_table[channel_num].FirstTxBd = tbd;
	for (i = 0; i <qmc_table[channel_num].no_of_trn_bd ; i++)
	{
		tbd->status = T_I;  
		tbd->length = 0;
		if( ReinitQmcFlag==0 )
		{
			tbd->buf = BYMalloc(hdlc_spec->max_frame_length);
		}
		tbd++;
	}
	--tbd;
	tbd->status |= T_W;

	if( hdlc_spec->mode == HDLC_32)
	{
		pram->zdstate = HDLC_ZD_STATE;
		pram->zistate = HDLC_ZI_STATE;
		hdlc_spec->reverse_mode = 0;
	}
	else
	{
		hdlc_spec->crc = 0;
		hdlc_spec->idle_mode = 1;
		hdlc_spec->number_of_flags = 0;
		pram->zdstate = TRANS_ZD_STATE;
		pram->zistate = TRANS_ZI_STATE;
	}

	pram->chamr = 	(hdlc_spec->number_of_flags&HDLC_CHAMR_NOF) |	\
					((hdlc_spec->crc  & 0x01) << 7)          	|	\
					((hdlc_spec->idle_mode & 0x01) <<13)     	|	\
					((hdlc_spec->reverse_mode & 0x01) << 14) 	|	\
					((hdlc_spec->mode & 0x01) << 15);

	pram->tstate = 0x30000000;
	pram->rstate = 0x31000000;

	pram->intmsk = hdlc_spec->intmask;
	pram->mflr   = hdlc_spec->max_frame_length;
	pram->chamr |= HDLC_CHAMR_ENT;

	return 0;
}

STATIC VOID QmcLogicChannnelInit( VOID )
{
	MULTI_CHAN_SETUP 	 set;
	HDLC_QMC_SPECIFIC    h;
	UC i;

	struct global_qmc_pram *base;

	if( ReinitQmcFlag==0 )
	{
		set.mcbase = (UL)BYMalloc(MAX_NUM_OF_BDS*sizeof(QUICC_BD));
		scc_table[GLB_SCC_0].mcbase = set.mcbase;
	}
	else
		set.mcbase = scc_table[GLB_SCC_0].mcbase;
	set.bds_tbl_size = MAX_NUM_OF_BDS*sizeof(QUICC_BD);
	set.mrblr = MRBLR_T + CRC_LEN;
	set.grfthr = RECEIVE_INTR;
	set.intbase = (UI *)&intr_tbl_scc1[0];
	set.inter_tbl_size = INTR_MEM_SPACE;
	set.rx_max_time_slot = set.tx_max_time_slot = MAX_SLOT_NUM/2;
	qmc_scc_init(GLB_SCC_0,0,&set);

	if( ReinitQmcFlag==0 )
	{
		set.mcbase = (UL)BYMalloc(MAX_NUM_OF_BDS*sizeof(QUICC_BD));
		scc_table[GLB_SCC_3].mcbase = set.mcbase;
	}
	else
		set.mcbase = scc_table[GLB_SCC_3].mcbase;
	set.bds_tbl_size = MAX_NUM_OF_BDS*sizeof(QUICC_BD);
	set.mrblr = MRBLR_T + CRC_LEN;
	set.grfthr = RECEIVE_INTR;
	set.intbase = (UI *)&intr_tbl_scc2[0];
	set.inter_tbl_size = INTR_MEM_SPACE;
	set.rx_max_time_slot = set.tx_max_time_slot = MAX_SLOT_NUM/2;
	qmc_scc_init(GLB_SCC_3, MAX_SLOT_NUM/2, &set);

	h.crc = CCITT_CRC16;
	h.number_of_flags = 1;	/* send one flag at the worst case*/
	h.idle_mode = FALSE;
	h.reverse_mode = FALSE;	/* reverse mode =1 Valid only for trasparent*/
	h.intmask = HDLC_SCCM_RXF|HDLC_SCCM_BSY|HDLC_SCCM_TXB;
	h.max_frame_length= MRBLR_T + CRC_LEN;
	h.mode = 1;		/* 1 for hdlc, 0- transparent*/
	h.continuous_tx = 0;
	h.continuous_rx = 0;

	for( i=0; i< NUM_OF_CHANNELS; i++ )
	{
		ClearWatchDog();
		if( i<32 )
		{
			if( hdlc_qmc_init(GLB_SCC_0,i,NUMBER_OF_RX_BUF,NUMBER_OF_TX_BUF,&h)==(-1))
				return;
		}
		else
		{
			if( hdlc_qmc_init(GLB_SCC_3,i,NUMBER_OF_RX_BUF,NUMBER_OF_TX_BUF,&h)==(-1))
				return;
		}
	}
}

STATIC VOID QmcTsaTableInit( VOID )
{
	UI i;
	struct global_qmc_pram *base;

	/*-------------------------Set SCC1 for 32 time slot-------------------------*-*/
	base = (struct global_qmc_pram *)QMC_BASE(quicc, GLB_SCC_0);
	base->rx_s_ptr  = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	base->rxptr     = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	base->tx_s_ptr  = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	base->txptr     = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	for( i=0; i<32; i++ )
	{
		base->tsatrx[i] = 0x303f;  /*Set Mask bit*/
		base->tsatrx[i] |= i << 6;
		base->tsatrx[i] |= VALID_SLOT;
	}
	base->tsatrx[31] |= WRAP_SLOT;

	/*-------------------------Set SCC4 for 16 time slot-----------------------------*/
	base = (struct global_qmc_pram *)QMC_BASE(quicc, GLB_SCC_3);
	base->rx_s_ptr  = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	base->rxptr     = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	base->tx_s_ptr  = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	base->txptr     = (SI)((SC *)(&base->tsatrx[0]) - (SC *)quicc);
	for( i=0; i<(16+NUM_OF_HTB_CHAN); i++ )
	{
		base->tsatrx[i] = 0x303f;  /*Set Mask bit*/
		base->tsatrx[i] |= (i+32) << 6;
		base->tsatrx[i] |= VALID_SLOT;
	}
	base->tsatrx[15+NUM_OF_HTB_CHAN] |= WRAP_SLOT;
}


UL  QmcShortPacketNum[64]={0};
UL  QmcCrcErrorNum[64]={0};
VOID InitQmcScc(VOID) /*Used SCC2 and SCC3*/
{
	UC  i;

	InitQmcRegisters();

	QmcSIRamInit();

	QmcLogicChannnelInit();

	QmcTsaTableInit();

	quicc->cpmi_cicr = quicc->cpmi_cicr|0X00000080;

	for( i=0; i<NUM_OF_CHANNELS; i++ )
	{
		QmcShortPacketNum[i] = 0;
		QmcCrcErrorNum[i] = 0;
	}
}

/*The flowing is added in 2002/04/07*/
VOID ReInitQmcLogicChannel( VOID )
{
	QUICC_BD                 *rbd;
	QUICC_BD                 *tbd;
	struct qmc_hdlc_pram	 *pram;
	struct scc_regs          *regs;
	SI                      i,num_of_bds;
	struct global_qmc_pram *base;
	UI channel_num;

	for( channel_num=0; channel_num<NUM_OF_CHANNELS; channel_num++ )
	{
		pram = CHANNEL_PRAM_BASE(quicc, channel_num);

		rbd = qmc_table[channel_num].FirstRxBd;
		qmc_table[channel_num].rbd = rbd;
		for(i = 0; i <qmc_table[channel_num].no_of_rcv_bd; i++)
		{
			rbd->length = 0;
			rbd->status = R_E | R_I;
			rbd++;
		}
		--rbd;
		rbd->status |= R_W;

		tbd = qmc_table[channel_num].FirstTxBd;
		qmc_table[channel_num].tbd = tbd;
		qmc_table[channel_num].NextFreeTbd = tbd;
		qmc_table[channel_num].tbd_len = 0;
		for (i = 0; i <qmc_table[channel_num].no_of_trn_bd ; i++)
		{
			tbd->status = T_I;
			tbd->length = 0;
			tbd++;
		}
		--tbd;
		tbd->status |= T_W;

		pram->tstate = 0x30000000;
		pram->rstate = 0x31000000;
		pram->chamr |= HDLC_CHAMR_ENT;
	}
}

STATIC UC QmcSccIsInitiating=FALSE;
VOID ReInitQmcScc(VOID) /*Used SCC2 and SCC3*/
{
	UI i;

	if( QmcSccIsInitiating==FALSE )
	{
		QmcSccIsInitiating=TRUE;

		ReinitQmcFlag=1;
		QmcIsReinitiating=1;

		InitQmcRegisters();

		QmcSIRamInit();

		ReInitQmcLogicChannel();

		QmcTsaTableInit();
		quicc->cpmi_cicr = quicc->cpmi_cicr|0X00000080;

		scc_start(GLB_SCC_0);
		scc_start(GLB_SCC_3);

		ReinitQmcFlag=0;
		QmcIsReinitiating=0;

		QmcSccIsInitiating=FALSE;
	}
}



⌨️ 快捷键说明

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