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

📄 syshdlc.c

📁 基于如何开发MPC860处理器系统的核心业务模块QMC的开发程序
💻 C
字号:
#include "vxworks.h"
#include "taskLib.h"
#include "mpc860p.h"
#include "msgQLib.h"
#include "arch/ppc/ivPpc.h"


QMCCHAN  	*chan;
MHEXTRAM 	*mhextRam;
char *pData2,*pData3;
UINT32 xi;
unsigned short QMCIntTbl[QMCINTMAX];
int  currentInt;
int  currentRXBD[HDLCCHANNELMAX];
int  currentTXBD[HDLCCHANNELMAX];

void QMC_BdInit();
void QMC_IntTblInit();
void QMC_ChannelInit();
void SiRamInit();

void mhRXF_int(int);
void mhTXB_int(int);
void mhMRF_int(int);
void mhIDL_int(int);
void mhNID_int(int);
void mhGlobalInt();
void mhQueueOverRun();
void mhTxUnderRun();
void mhRxOverRun();

void ppc860HdlcInt();

void sysHdlcHwInit(){	
QMCPARAM 	*param;  
 	int i,j;
	int immrVal = vxImmrGet();
	xi = 0;
	pData2 = (char *)0x3100000;
	pData3 = (char *)0x3180000;
  mhextRam = (MHEXTRAM *)QMC_BD_BASE;
  	chan = (QMCCHAN *)QMC_CHAN_BASE;

	*SDCR(immrVal) = 0x00000001;

   *SIMODE(immrVal) |= 0x00000010;/*0x00180018;*/ 

    /* Connect SCC2 to TMD mode */
   *SICR(immrVal) |= 0x00004000;  

    /* Configure PortA for TDMa & TDMb functionality */
    /* Enable the L1RCLKx and L1TCLKx                */
    
    /*********************** TDMA ************************/
    /* PA5 -> L1TCLKA : PA7 -> L1RCLK : PA8 -> L1RXDA :  */
    /* PA9 -> L1TXDA : PC4 -> L1RSYNCA : PC5 -> L1TSYNCA */
    /*********************** TDMB ************************/
    /* PA0 -> L1TCLKB : PA2 -> L1RCLKB : PA10 -> L1RXDB  */
    /* PA11 -> L1TXDB : PC6 -> L1RSYNCB : PC7 -> L1TSYNCB*/
    /*****************************************************/ 
    
    *PAPAR(immrVal) |= (PA5|PA7|PA8|PA9);
    *PADIR(immrVal) &= ~(PA5|PA7);
    *PADIR(immrVal) |= (PA8|PA9);

    *PCPAR(immrVal) |= (PC4|PC5);
    *PCDIR(immrVal) &= ~(PC4|PC5);

	*PBPAR(immrVal) |= PB20;
	*PBDIR(immrVal) |= PB20;
  
    SiRamInit();

  /* Enable TDMA & TDMB */
    *SIGMR(immrVal) = 0x04;
    
    *GSMR_H2(immrVal) = 0x00000780;
    *GSMR_L2(immrVal) = 0x0000000a;/* QMC mode */

	param = (QMCPARAM *)PARAM(2);
	param->mcbase   = (UINT32) QMC_BD_BASE;
	param->intbase  = (unsigned long ) &QMCIntTbl;
	param->mrblr    = MSGLEN;
  
  	param->grfthr   = 1;
  	param->grfcnt   = 1;

	param->c_mask32 = 0xDEBB20E3;
	param->c_mask16 = 0xF0B8;

	param->intptr   = (unsigned long ) &QMCIntTbl;
   		
  	for(j=0 ; j<32 ; j++)
  	{	
		if(j<HDLCCHANNELMAX)
		{
			param->tsatrx[j]=0xb03f + (unsigned short)(j<<6);
  			param->tsattx[j]=0xb03f + (unsigned short)(j<<6);
		}
		else
		{
			param->tsatrx[j]=0x303f + (unsigned short)(j<<6);
  			param->tsattx[j]=0x303f + (unsigned short)(j<<6);
		}
 	}
  	param->tsatrx[HDLCCHANNELMAX-1] |= 0x4000;
	param->tsattx[HDLCCHANNELMAX-1] |= 0x4000; 

	param->tx_s_ptr =0x3d60;	/* (short)(&param->tsattx);*/
	param->txptr = 0x3d60;		/*(short)(&param->tsattx);*/
	param->rx_s_ptr = 0x3d20;	/*(short)(&param->tsatrx);*/
	param->rxptr = 0x3d20;		/*(short)(&param->tsatrx);*/

	param->qmcstate = 0x8000;	


    QMC_ChannelInit();

    QMC_BdInit();

    for(i=0;i<HDLCCHANNELMAX;i++) 
    {
        currentRXBD[i] = 0;
        currentTXBD[i] = 0;
    }

    QMC_IntTblInit();
	 currentInt = 0;	

  	for(i = 0 ; i < HDLCCHANNELMAX ; i++)
  	{
      chan[i].chamr |= 0x1000;/*; 0x8000 */
   }

    *SCCE2(immrVal) = 0xffff;
    *SCCM2(immrVal) = 0x0004;


   /* Write CIMR, allow SCC2 &SCC4 to generate a system interrupt.*/
/*	 *CICR(immrVal) |= 0x00d00000;*/
 
    
    *GSMR_L2(immrVal) |= 0x00000030;     /* Enable Transmit and receive */

   intConnect(IV_SCC2, (VOIDFUNCPTR)ppc860HdlcInt,0);
   *CIMR(vxImmrGet()) |= 0x20000000;  
  }


void sysHdlcHwInit2(void)
{
   
}

void SiRamInit()
{
   unsigned long *SiEntry;
   int i;
   int immrVal = vxImmrGet();
  
   SiEntry = (unsigned long *) SIRAM(immrVal);

	for(i=0 ; i< 64 ; i++)
	{
		if(i < (HDLCCHANNELMAX - 1))
		{
			*(SiEntry + i) = 0x00820000;
			*(SiEntry + i + 64) = 0x00820000;
		}
		else
		{
			if(i == (HDLCCHANNELMAX - 1))/* the last */
			{
				*(SiEntry + i) = 0x00830000;
				*(SiEntry + i + 64) = 0x00830000;
			}
			else /* no used */
			{
			    *(SiEntry + i) = 0x00000000;
			    *(SiEntry + i) = 0x00000000;
			}
		}
	}
}

void QMC_BdInit(void)
{
   int i,j;
   char *RxBuf, *TxBuf; 
 	char * bufAddr; 

    RxBuf = (char *) QMC_RXBUF_BASE;/*(QMC_BUF_BASE + (MSGLEN + 4) 
							* MHTXBDNUM * MHCHANMAX);*/
    for(i = 0; i < HDLCCHANNELMAX; i++)
    {
        for(j = 0; j < MHRXBDNUM; j++)
        {
			bufAddr = (char *)&RxBuf[i * MHTXBDNUM * (MSGLEN + 4) + j * (MSGLEN + 4)];
        	(mhextRam->qmcRxBD[i][j]).sc = (RXBD_E|RXBD_I);/*0x9000;*/
        	(mhextRam->qmcRxBD[i][j]).len = 0;
        	(mhextRam->qmcRxBD[i][j]).addr = bufAddr;/*(UINT8 *)(&RxBuf[i * MHRXBDNUM 
							* (MSGLEN+4) + j * (MSGLEN+4)]);	*/
			*((mhextRam->qmcRxBD[i][j]).addr) = EOS;
    	}
        (mhextRam->qmcRxBD[i][MHRXBDNUM - 1]).sc |= 0x2000;
  	}
 
  	TxBuf = (char *)QMC_TXBUF_BASE;/*0x380000;*/
   for(i=0 ; i<HDLCCHANNELMAX ; i++)
   {
       for(j=0 ; j<MHTXBDNUM ; j++)
        {
				bufAddr = (char *)&TxBuf[i * MHTXBDNUM * (MSGLEN + 4) + j * (MSGLEN + 4)];
            (mhextRam->qmcTxBD[i][j]).addr = bufAddr;/*(char *)(&TxBuf[i * MHTXBDNUM 
							* (MSGLEN+4) +	j * (MSGLEN+4)]);*/
				 *((mhextRam->qmcTxBD[i][j]).addr) = EOS;  
				(mhextRam->qmcTxBD[i][j]).len = 0;
   			(mhextRam->qmcTxBD[i][j]).sc = (TXBD_I|TXBD_L|TXBD_TC); 
     	}
        (mhextRam->qmcTxBD[i][MHTXBDNUM - 1]).sc |= 0x3000;
    }
}

void QMC_IntTblInit(void)
{
   int i;

  	for(i=0; i<QMCINTMAX; i++)  QMCIntTbl[i] = 0;

  	QMCIntTbl[QMCINTMAX-1] = 0x4000;

}

void QMC_ChannelInit()
{
  	int i;

  	for(i = 0; i < HDLCCHANNELMAX ; i++)
   	{
  		chan[i].tbase = (UINT16)((UINT32)mhextRam->qmcTxBD[i]-(UINT32)mhextRam);
  		chan[i].rbase = (UINT16)((UINT32)mhextRam->qmcRxBD[i]-(UINT32)mhextRam);

  		chan[i].tbptr = (UINT16)((UINT32)mhextRam->qmcTxBD[i]-(UINT32)mhextRam);
		/*sizeof(BD) * MHTXBDNUM * i;*/
  		chan[i].rbptr = (UINT16)((UINT32)mhextRam->qmcRxBD[i]-(UINT32)mhextRam);
   		/*sizeof(BD) * MHRXBDNUM * i
   							+ sizeof(BD) * MHRXBDNUM * MHCHANMAX;*/

  		chan[i].tstate = 0x30000000;
  		chan[i].rstate = 0x31000000;

  		chan[i].zistate = 0x00000100;
  		chan[i].zdstate = 0x00000080;

	    chan[i].intmsk = 0x0008;
  		chan[i].mflr = MSGLEN;
 		chan[i].chamr = 0x8000;
    }
}


void ppc860HdlcInt()
{
    unsigned short intVal;
    int immrVal = vxImmrGet();

    intVal = *SCCE2(immrVal);
	
    if(intVal & SCCE_GINT)mhGlobalInt();
    if(intVal & SCCE_GOV)mhRxOverRun();
    if(intVal & SCCE_GUN)mhTxUnderRun();
    if(intVal & SCCE_IQOV)mhQueueOverRun();

    *SCCE2(immrVal) = 0xffff;
    *CISR(immrVal) |= 0x20000000;
 	return;
}

void mhRxOverRun()
{
	int immrVal = vxImmrGet();
	
	*SCCE2(immrVal) |= SCCE_GOV;
}

void mhTxUnderRun()
{          
	int immrVal = vxImmrGet();

   *SCCE2(immrVal) |= SCCE_GUN;
}

void mhQueueOverRun()
{
	int immrVal = vxImmrGet();

   *SCCE2(immrVal) |= SCCE_IQOV;
}

void mhGlobalInt()
{
  	UINT16 intValue;
	int immrVal = vxImmrGet();

  	int mhch;

	*SCCE2(immrVal) |= SCCE_GINT;
    
	while( (intValue = QMCIntTbl[currentInt]) & INTTBL_V )
	{
		QMCIntTbl[currentInt] &= ~(INTTBL_V);
		mhch = (UINT8)((intValue&INTTBL_CH_NUM)>>6);
  			
		if(intValue & INTTBL_TXB) mhTXB_int(mhch);
 		if(intValue & INTTBL_RXF) mhRXF_int(mhch);
 		if(intValue & INTTBL_MRF) mhMRF_int(mhch);
      if(intValue & INTTBL_IDL) mhIDL_int(mhch);
      if(intValue & INTTBL_NID) mhNID_int(mhch);

		/* clear int flag and channel number */
		QMCIntTbl[currentInt] &= ~(0x37f2);
		if( (intValue & INTTBL_W) || (currentInt >= (QMCINTMAX - 1)) )
		{
			currentInt = 0;
			continue;
		}
		currentInt++;
	}
}

void mhTXB_int(int mhch)
{
    QMCIntTbl[currentInt] &= ~INTTBL_TXB;
}

void mhRXF_int(int mhch)
{
   int n;
   UINT16 length;
	int msgType, link;
   BD *bd;

	QMCIntTbl[currentInt] &= ~(INTTBL_RXF);
     
   bd = &(mhextRam->qmcRxBD[mhch][currentRXBD[mhch]]);
    
   n=0;

   while( bd->sc & RXBD_E )
   {
      if( (bd->sc & RXBD_W) || (currentRXBD[mhch] >= (MHRXBDNUM - 1)) )
      {
         bd = &(mhextRam->qmcRxBD[mhch][0]);
         currentRXBD[mhch] = 0;
      }
      else
      {
         bd++; 
         currentRXBD[mhch]++;
      }
      n++;
      if(n>= MHRXBDNUM)return; 
   } 

   while( !(bd->sc & RXBD_E) )
   {
    	if( !(bd->sc & RXBD_F) || (bd->sc & RXBD_BAD_FACT) || (bd->len <= 2) )
    	{
			bd->sc &= ~(RXBD_L | RXBD_F | RXBD_BAD_FACT);
         bd->sc |= RXBD_E;
   		if( (bd->sc & RXBD_W) || currentRXBD[mhch] >= (MHRXBDNUM - 1) )
         {
        		bd = &(mhextRam->qmcRxBD[mhch][0]);
        		currentRXBD[mhch] = 0;
        		continue;
         }
         bd++;
         currentRXBD[mhch]++;
         continue;
      }
   	length = (bd->len - 2);     /* remove CRC bit */
	
		if(( bd->sc & RXBD_L )&&(length <= 512))
		{
if(mhch == 3){
	     		memcpy(pData3, (char *)bd->addr, length);
				pData3 = (char *)(pData3 + 0x40);
				if((UINT32)pData3 > 0x31ff000)pData3 = (char *)0x3100030;
				}
else if(mhch == 2)
{
		 		memcpy(pData2, (char *)bd->addr, length);
				pData2 = (char *)(pData2 + 0x40);
				if((UINT32)pData2 > 0x31ff000)pData2 = (char *)0x3100030;
}
		}
     		
    	bd->sc |= RXBD_E;
    	bd->sc &= ~(RXBD_L | RXBD_F | RXBD_BAD_FACT);

    	if( (bd->sc & RXBD_W) || currentRXBD[mhch] == (MHRXBDNUM - 1) )
    	{
    		bd = &(mhextRam->qmcRxBD[mhch][0]);
        	currentRXBD[mhch] = 0;
        	continue;
      }
    	bd++;
		currentRXBD[mhch]++;
   }
}

STATUS sendMsgQMC(int mhch, UINT16 length, char *buf)
{
   BD *bd;
   int i;
	char *tmp;
  
   bd = (BD *)&(mhextRam->qmcTxBD[mhch][currentTXBD[mhch]]);
  
	i=0;

   while( bd->sc & TXBD_R )
   {
      if( (bd->sc & TXBD_W) || (currentTXBD[mhch] >= (MHTXBDNUM - 1)) )
      {
         bd = &(mhextRam->qmcTxBD[mhch][0]);
         currentTXBD[mhch] = 0;
      }
      else
      {
         bd++;
         currentTXBD[mhch]++;
      }
      i++;
      if(i>=MHTXBDNUM) return ERROR;
   }

   if( !(bd->sc & TXBD_R) )
   {
		tmp = (char *)bd->addr;
		for(i=0;i<length;i++)*tmp++ = *buf++;

/*		memcpy((void *)bd->addr,(void *)buf,length);*/
      bd->len = length;
      bd->sc |= TXBD_R | TXBD_L;

      chan[mhch].chamr |= 0x100;  /* enable Polling */

      if( (bd->sc & TXBD_W) || (currentTXBD[mhch] >= (MHTXBDNUM - 1)))
      {
         currentTXBD[mhch] = 0;
         return OK;
     	}

     	currentTXBD[mhch]++;
    	return OK;
 	}
  	return ERROR;
}

void mhMRF_int(int mhch)
{
  	UINT16 length;
  	BD *bd;
  	char *Data;
  	int msgType, link;

  	if(mhch >= 32)return;

	QMCIntTbl[currentInt] &= ~(INTTBL_MRF);

  	bd = &(mhextRam->qmcRxBD[mhch][currentRXBD[mhch]]);

  	length = bd->len - 2;
/*
  	Data = (char *)malloc(length);
   memcpy(Data, (char *)bd->addr, length);
*/
   memcpy(pData2, (char *)bd->addr, length);
	xi++;
	pData2 ++;
	if((UINT32)pData2 >= 0x31fff80) pData2 = (char *)0x3100020;
	
  	bd->sc |= RXBD_E;
  	bd->sc &= ~(RXBD_L | RXBD_F | RXBD_BAD_FACT);

  	if( (bd->sc & RXBD_W) || currentRXBD[mhch] == (MHRXBDNUM - 1) )
  	{
  		bd = &(mhextRam->qmcRxBD[mhch][0]);
     	currentRXBD[mhch] = 0;
     	return;
   }

  	bd++;
	currentRXBD[mhch]++;


}

void mhIDL_int(int mhch)
{
	QMCIntTbl[currentInt] &= ~(INTTBL_IDL);
}

void mhNID_int(int mhch)
{
	QMCIntTbl[currentInt] &= ~(INTTBL_NID);
}

/*
void vSendPkgToHardware(unsigned char MsgDirType, unsigned char PhLinkNo,
							unsigned short PkLen, unsigned char *bpPkg)
{
	
}
void vSetSlotType(UINT8 SlotType, UINT8 PhLinkNo, UINT8 SlotNo)
{
	switch (SlotType)
	{
	case BC_SLOT:
		break;
	case PH_C_CHANNEL_SLOT:
		break;
	default: break;
	}
}
*/

⌨️ 快捷键说明

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