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

📄 hdlcint.c

📁 ads mpc860上hdlc的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
* DESCRIPTION:
*
*     Return TRUE if Buffer Descriptor Status bd_cstatus indicates Receive 
*     Error; Return FALSE otherwise note Receive Errors are as follows:
*
*     0x80: DPLL Error (DE)
*     0x20: Length Violation (LG)
*     0x10: Non-Octet Aligned (NO)
*     0x8: Rx Abort Sequence (AB)
*     0x4: Rx CRC Error (CR)
*     0x2: Overrun (OV)
*     0x1: Carrier Detect Lost (CD)
*
* EXTERNAL EFFECTS: None
*
* PARAMETERS:  
*
*     bd_cstatus
*
* RETURNS: TRUE if there was an error and FALSE if there wasn't
*
*-----------------------------------------------------------------------------*/

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: ExtIntHandler
*
* DESCRIPTION:
*
*     Process External Interrupt (assumes only interrupts from SCC2)
*
*     Main Processing Steps:
*
*        (1) Save off SCCE for SCC2 (SCC 1 Event Register)
*
*        (2) Test input vector against External Interrupt Vector.
*
*        (3) Test Interrupt Code in SIU Interrupt Vector Reg (SIVEC) against 
*            LEVEL 4.
*
*        (4) Clear LEVEL 4 Interrupt Level bit in SIPEND.
*
*        (5) Request Interrupt Vector Number from CPM Interrupt Vector Reg
*            (CIVR).
*
*        (6) Test CIVR Interrupt Vector against Vector for SCC2. 
*
*        (7) Clear SCC2 Event Register
*
*        (8) Test SCC2 Event
*
*        (9) 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   index;


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

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

   /*-----------------------------*/
   /* Grab the SCC event register */
   /*-----------------------------*/

   scce = IMMR->scc_regs[SCC2_REG].scc_scce; /* Save off scce */

   /*---------------------------------------------------------------------*/
   /* Match input vector against Exteral Interrupt Vector -- 0x500 on PPC */
   /*---------------------------------------------------------------------*/

   if (vector != EXT_INT_VECTOR) 
   
      return;

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

   /*-------------------------------------------*/
   /* Clear SCC2 Event Register (by writing 1s) */
   /*-------------------------------------------*/

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

   /*---------------------------------------------------------*/
   /* Process SCC HDLC Event if the event flag for RXF is set */
   /*---------------------------------------------------------*/

   if (scce & HDLC_SCCE_RXF) 
   
   {
      /*-------------------------------------------------------------------*/
	   /* Traverse through available Receive Buffers to locate first filled */
	   /* buffer.                                                           */
	   /*-------------------------------------------------------------------*/

	   for(index = RxProcIndex; index < NUM_RXBDS; index++) 
            
      {
         if (!BDEmpty(RxTxBD->RxBD[index].bd_cstatus)) 

         {
            /*-------------------------------------------------------------*/
            /* Compare the receive buffer with it's corresponding transmit */
            /* buffer.                                                     */
            /*-------------------------------------------------------------*/

            if (memcmp(&BufferPool[index],
                       &BufferPool[index+FIRST_TX_BUF],
                       (BUFFER_SIZE-2)))
            {
               RxGood=FALSE; /* they didn't compare */
            }

            /******************************************************************/
            /* I've designed the architecture so that every frame of data     */
            /* encompasses a buffer descriptor's worth of data. This a very   */
            /* simple example. Normally there could be several BD's in a      */
            /* HDLC frame and once a buffer data was processed, the BD could  */
            /* be released for use. Also, the BDs in this case are linear/in  */
            /* order in terms of their processing. Normally BD's would not be */
            /* guaranteed to be linear so this interrupt code would have to   */
            /* look for the next BD that wasn't empty and process accordingly.*/
            /******************************************************************/

            /*----------------------------------------------------------------*/
            /* In my example, every BD is the last BD because every frame     */
            /* holds one buffer per BD. I only 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 )) 
            
            {
				   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;  	

         }	
      }
   }

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

   /*---------------------------------------------------------------------*/
   /* Here's our error loop. Spin here indefinitly if there was an error. */
   /*---------------------------------------------------------------------*/

   if (RxGood == FALSE) 
   
   {
      while (1) 
      
         FlashEthled();	 /* spin here if error is flagged */
   } 

   /*-----------------------------------------------------------------*/
   /* Clear CPM Interrupt In-Service Register SCC2 bit (by writing 1) */
   /*-----------------------------------------------------------------*/

   IMMR->cpmi_cisr |= CISR_SCC2;

} /* end ExtIntHandler */


/*-----------------------------------------------------------------------------
*
* 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 */


⌨️ 快捷键说明

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