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

📄 hdlcint.c

📁 MPC860的SCC2配置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 + -