📄 qmc_init.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 + -