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

📄 860qmc1h.c

📁 MPC860初始化QMC在HDLC模式示例
💻 C
📖 第 1 页 / 共 3 页
字号:
UHWORD BDRxError(UHWORD bd_cstatus)
{
      if (bd_cstatus & BD_RX_ERROR)
      {      return TRUE;
      }
         else
      {      return FALSE;
      }
      
} /* end BDRxError */



/*--------------------------------------------------------------------------
*
* FUNCTION NAME: LastBD
*
* DESCRIPTION:   Return TRUE if Buffer Descriptor with status and 
*                control register bd_cstatus is last in frame; Return 
*                FALSE otherwise.
*
* EXTERNAL EFFECTS: None
** PARAMETERS:  
*
*     bd_cstatus -
*
* RETURNS:
*
*-------------------------------------------------------------------------*/

UHWORD LastBD(UHWORD bd_cstatus)
{
      if (bd_cstatus & 0x0800)
      {      return TRUE;
      }
         else
      {      return FALSE;
      }
      } /* end LastBD */


/*--------------------------------------------------------------------------
*
* FUNCTION NAME: BDEmpty
*
* DESCRIPTION:
*
*     Return TRUE if Buffer Descriptor Status bd_cstatus is empty. Return 
*     FALSE otherwise.
** EXTERNAL EFFECTS: None
*
* PARAMETERS:  
*
*     bd_cstatus 
*
* RETURNS: TRUE if empty and FALSE if it isn't
*
*-------------------------------------------------------------------------*/

UHWORD BDEmpty(UHWORD bd_cstatus)
{
   if (bd_cstatus & 0x8000)
      {      return TRUE;
      }
         else
      {      return FALSE;
      }
      } /* end BDEmpty */




/*--------------------------------------------------------------------------
*
* FUNCTION NAME: GetIMMR
*
* DESCRIPTION:
*
*     returns in R3, the current value in IMMR register. The IMMR register 
*     must be accessed in this manner because it is a special purpose 
*     register.
*
* EXTERNAL EFFECTS: None
*
* PARAMETERS: none
*
* RETURNS: IMMR value in R3.
*-------------------------------------------------------------------------*/
GetIMMR()
{
   /*--------------------------------------------------------------------*/
   /* r3 is the register that the compiler is using for the return value */
   /* In other words, r3 is the implicit return value.                   */
   /*--------------------------------------------------------------------*/

   #ifdef MetaWare
      _ASM(" mfspr  %r3,638 ");    /* IMMR is spr #638 */
   #else
      #ifdef Diab
         asm(" mfspr  r3,638 ");        /* IMMR is spr #638 */
      #endif
   #endif

} /* end GetIMMR */

/*-------------------------------------------------------------------------
*
* FUNCTION NAME: Ethled
*
* DESCRIPTION:
*
*     Turn On/Off Ethernet LED on 821/860 ADS board.
*
* EXTERNAL EFFECTS:
*
* PARAMETERS: 
*     
*     setting - 0 turns off LED; otherwise turn on LED.
*
* RETURNS: NONE
*
*-------------------------------------------------------------------------*/
void Ethled(UHWORD setting)
{

BCSR *csr;
      csr = (BCSR *)(IMMR->memc_br1 & 0xFFFF8000);
   if (setting)
      {      csr->bcsr1 &= ~ETHEN;	/* turn on LED, active low */
      }
         else
      {      csr->bcsr1 |= ETHEN;	/* turn off LED, active high */
      }
} /* end Ethled */

/*-------------------------------------------------------------------------
*
* FUNCTION NAME:  FlashEthled
*
* DESCRIPTION:  This function flashes the Ethernet LED
*
* EXTERNAL EFFECTS: None
*
* PARAMETERS: none
*
* RETURNS: None
*
*-------------------------------------------------------------------------*/

void FlashEthled()
{
UBYTE  ii;
UWORD jj;
   for (ii = 0; ii<20; ii++)
         {
      Ethled(ii%2);  /* Turn on every other time through the loop */
            for (jj=0; jj < 100000; jj++);	/* Wait */
   }
      Ethled(0);  /* LED off */
} /* end FlashEthled */



/*--------------------------------------------------------------------------
*
* FUNCTION NAME: ExtIntHandler
*
* DESCRIPTION:
*
*     Process External Interrupt (assumes only interrupts from SCC2)
*
*     Main Processing Steps:
*
*
*			(1) Match input vector against External Interrupt Vector
**        (2) Test Interrupt Code in SIU Interrupt Vector Reg (SIVEC) against 
*            LEVEL 4.
* *        (3) Request Interrupt Vector Number from CPM Interrupt Vector Reg
*            (CIVR).
*
*			(4) Test CIVR Interrupt Vector against Vector for SCC2. 
* 
*        (5) Save a copy of SCCE.
*
*        (6) Clear SCCE. 
*
*        (7) Process Global Interrupt Event.
*       *        (8) Clear SCC2 bit CPM Interrupt In-Service Register.
**
*     NOTE: This ISR will only handle ONE RX event. This interrupt happens 
*           when the last frame of eight is received.
*
* EXTERNAL EFFECTS:  interrupt related registers
*
* PARAMETERS:
**     vector - interrupt vector (address)
*
* RETURNS: NONE
*
*-------------------------------------------------------------------------*/
void ExtIntHandler(UWORD vector)
{

UWORD    sivec_ic;
UWORD    scce;
UHWORD   channel_number;
UHWORD entry_count = 0;	          /* counter for entries in ICT */
UHWORD index = 0;						   


	/*-------------------------------------*/
   /* Match input vector against External */
   /* Interrupt Vector -- 0x500 on PPC    */
   /*-------------------------------------*/
   if (vector != EXT_INT_VECTOR) 
   
      return;


   /*------------------------------------*/
   /* Shift the byte wide interrupt code */
   /* down to the least significant byte */
   /*------------------------------------*/

   sivec_ic = IMMR->siu_sivec >> 24;   /* sivec interrupt code */

   /*-----------------------------*/
   /* Process SIU Interrupt Event */
   /*-----------------------------*/
   switch(INTERRUPT_LEVEL) 				 
     
   {
      case 4:
         if(sivec_ic != IC_LEVEL_4) 
         
            return;
         break;
      default: 
      
         return;	/* INTERRUPT NOT Level 4 */
   }

   /*----------------------------------------------------------*/
   /* Set IACK bit in CIVR to request current interrupt vector */
   /*----------------------------------------------------------*/
   IMMR->cpmi_civr |= CIVR_IACK; 	 


   /*-----------------------------------------------*/   /* Test CPM Interrupt Vector against SCC2 Vector */
   /*-----------------------------------------------*/   if ((IMMR->cpmi_civr >> 11) !=  SCC2_VECTOR) 
   
      return;


   /*----------------------------------------*/
   /* Save a copy of the SCC event register, */
   /* then clear the actual SCCE.            */
   /*----------------------------------------*/

   scce = IMMR->scc_regs[SCC2_REG].scc_scce; 
   IMMR->scc_regs[SCC2_REG].scc_scce = ALL_ONES;


   /*-------------------------------------------*/
   /* Process SCC Global Interrupt Event (GINT) */
   /*-------------------------------------------*/

	UHWORD exit_flag = FALSE;

     if (scce & 0x0004) 
   
   {				
      
		/*-----------------------------------*/
		/* Traverse Interrupt Circular Table */
		/* from first entry to last          */
		/*-----------------------------------*/

     	while (!exit_flag)

		{	
		
           /*------------------------------------------*/
           /* Look for a set "Valid" bit in each table */
           /* entry. Then make sure this entry's event */
           /* is RXB. RXB is the only event            */
           /* ExtIntHandler will process.              */
           /*------------------------------------------*/
								
	  	   if ((IntCQ[entry_count] & QMC_ITE_V) && 
	  	       (IntCQ[entry_count] & QMC_ITE_RXB))

		   { 
				                          
		     /*---------------------------------*/ 
		     /* Get Channel Number for this ITE */
		     /*---------------------------------*/

            channel_number = (IntCQ[entry_count] & QMC_ITE_CN);

            channel_number = (channel_number >> 6);


            /*--------------------------------------------*/
            /* Traverse through available Receive Buffers */
            /* to locate first filled buffer.             */
            /*--------------------------------------------*/
     
            while ((!BDEmpty(RxTxBD->RxBD[index].bd_cstatus) &&
                   (index < NUM_RXBDS))) 
             
            {

                /*************************************************************/
                /* In this example, every frame encompasses a buffer         */
                /* descriptor's worth of data. This a very simple 		     */
                /* example. Normally there could be several BD's in a        */               
                /* frame, and once a data buffer was processed, it could     */
                /* be released for use. Note also that the BDs in this       */
                /* example are processed in linear fashion. Typically,       */
                /* BD's would not be guaranteed to be linear, so more        */
                /* "realistic" interrupt code would have to search for       */
                /* the next BD that wasn't empty and process it accordingly. */
                /*************************************************************/

                /*--------------------------------------------------------*/
                /* In this example, EVERY BD is the first and last BD in  */
                /* frame, because every frame holds one buffer per BD. We */
                /* include the function "LastBD()" so that the user can   */
                /* expand/modify the code to consider multiple BDs in one */
                /* frame.                                                 */
                /*--------------------------------------------------------*/

                if(LastBD(RxTxBD->RxBD[index].bd_cstatus))
                /*changed for HDLC version from "!LastBD"*/
            
                {
				       RxTxBD->RxBD[index].bd_cstatus |= 0x8000; /* set empty flag */

                   /*-------------------------------------*/
                   /* checking all status bits for errors */
                   /*-------------------------------------*/

                   if (BDRxError(RxTxBD->RxBD[index].bd_cstatus)) 
                      {
                      RxGood = FALSE;
                      }
			    }

					
                /*------------------------------------------*/
                /* This is the last BD in the chain. Clear  */
                /* all bits but the Ready bit and Wrap bit. */
                /*------------------------------------------*/

                if (index == (NUM_RXBDS-1)) 
                   {
                   RxTxBD->RxBD[index].bd_cstatus = 0xA000;
				   }

                /*------------------------------------*/
                /* Set RX process index to start next */
                /* BD scan from the BD after this one */                                                    
                /*------------------------------------*/

                RxProcIndex = index+ 1;  
            
                index++;

           } // while

  	      } // if 



              /*--------------------------------------------------*/
              /* If "Wrap" bit is set in this ITE:                */
              /*                                                  */
              /* 1) Set flag to exit after we process this entry. */
              /* 2) Clear the entry, preserving the wrap bit.     */
              /*                                                  */
              /* ELSE just clear the entire entry.                */
              /*--------------------------------------------------*/

			   if (IntCQ[entry_count] & QMC_ITE_W)

		     	{
			   	exit_flag = TRUE;
                IntCQ[entry_count] &= (QMC_ITE_CLEAR | QMC_ITE_W);
			    }
   	  
		       else
                {
				IntCQ[entry_count] &= QMC_ITE_CLEAR;
                }

				entry_count++;



     } // while 
		  
 } // if

   else 
   
      RxGood = FALSE; /* Expected to see RXB event in SCCE */

   

   /*-----------------------------------------------------------------*/
   /* Clear CPM Interrupt In-Service Register SCC2 bit (by writing 1) */
   /*-----------------------------------------------------------------*/
   IMMR->cpmi_cisr |= CISR_SCC2;

} /* end ExtIntHandler */    

⌨️ 快捷键说明

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