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

📄 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 UC TheBrdNum;

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;
	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;

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

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

	/*Set Communication timeslot*/
	quicc->si_siram[TheBrdNum] = 0x00C20000;
	quicc->si_siram[64+TheBrdNum] = 0x00C20000;


	/*Set L1RCLKb and L1RSYNCb Related to SIRAM and config to SCC1*/
	for( i=0; i<32; i++ )
	{
		quicc->si_siram[32+i] = 0x00020000; 
	}
	quicc->si_siram[32+31]    = 0x00030000;

	/*Set L1TCLKb and L1TSYNCb Related to SIRAM and config to SCC1*/
	for( i=0; i<32; i++ )
	{
		quicc->si_siram[96+i] = 0x00020000; 
	}
	quicc->si_siram[96+31]    = 0x00030000;


	/*Set 8 D channel in SCC4*/	/*Set in 2002/08/10*/
	for( i=16; i<(16+8); i++ )
	{
		quicc->si_siram[32+i] = 0x01020000;		
		quicc->si_siram[96+i] = 0x01020000;		
	}
}



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=malloc(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 = malloc(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)malloc(MAX_NUM_OF_BDS*sizeof(QUICC_BD));
		scc_table[GLB_SCC_2].mcbase = set.mcbase;
	}
	else
		set.mcbase = scc_table[GLB_SCC_2].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_2,0,&set);

	if( ReinitQmcFlag==0 )
	{
		set.mcbase = (UL)malloc(MAX_NUM_OF_BDS*sizeof(QUICC_BD));
		scc_table[GLB_SCC_3].mcbase = set.mcbase;
	}
	else
		set.mcbase = scc_table[GLB_SCC_3].mcbase;	/*GLB_SCC_2?3?*//*www*/
	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++ )
	{
		if( i==0 )
		{
			if( hdlc_qmc_init(GLB_SCC_2,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_2);
	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);
	base->tsatrx[0] = 0x303f;  
	base->tsatrx[0] |= 0 << 6;
	base->tsatrx[0] |= VALID_SLOT;
	base->tsatrx[0] |= WRAP_SLOT;


	/*Set SCC2 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<8; i++ )
	{
		base->tsatrx[i] = 0x0003;  /* 0x303f Set Mask bit*/
		base->tsatrx[i] |= (i+1) << 6;
		base->tsatrx[i] |= VALID_SLOT;
	}
	base->tsatrx[7] |= WRAP_SLOT; /* Modified by weng on 2005-9-22 17:27 */
}


/*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_2);
		scc_start(GLB_SCC_3);

		ReinitQmcFlag=0;
		QmcIsReinitiating=0;

		QmcSccIsInitiating=FALSE;
	}
}

VOID InitQmcScc(VOID) /*Used SCC2 and SCC3*/
{
	InitQmcRegisters();

	QmcSIRamInit();

	QmcLogicChannnelInit();

	QmcTsaTableInit();

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

⌨️ 快捷键说明

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