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

📄 ethernet.c

📁 MPC860的SCC1配置以太网示例代码
💻 C
📖 第 1 页 / 共 3 页
字号:
*
*     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 SCC1)
*
*     Main Processing Steps:
**        (1) Save off SCCE for SCC1 (SCC1 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 SCC1. 
**        (7) Clear SCC1 Event Register
**        (8) Test SCC1 Event
**        (9) Clear SCC1 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[SCC1_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 SCC1 Vector */
   /*-----------------------------------------------*/   if ((IMMR->cpmi_civr >> 11) !=  SCC1_VECTOR) 
   
      return;

   /*-------------------------------------------*/   /* Clear SCC1 Event Register (by writing 1s) */
   /*-------------------------------------------*/   IMMR->scc_regs[SCC1_REG].scc_scce = ALL_ONES;

   /*-------------------------------------------------------------*/
   /* Process SCC Ethernet Event if the event flag for RXF is set */
   /*-------------------------------------------------------------*/
   if (scce & 0x0008) 
   
   {
      /*--------------------------------------------*/
	   /* Traverse through available Receive Buffers */
	 	/* to locate first filled buffer.             */
	   /*--------------------------------------------*/
     
       while ((!BDEmpty(RxTxBD->RxBD[index].bd_cstatus) &&
              (index < NUM_RXBDS))) 
             
       {

            /*---------------------------------------*/
            /* Compare the receive buffer with its   */			 
            /* corresponding transmit buffer.        */                                               
            /*---------------------------------------*/

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

            /*************************************************************/
            /* In this architecture, 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 )) 
            
            {
				   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++;

       } 				

   }	

   else 
   
      RxGood = FALSE; /* Expected to see RXF event in SCCE */
   /*-------------------------------------*/
   /* Here's our error loop. Spin here 	*/
   /* indefinitely if there was an error. */
   /*-------------------------------------*/

   if (RxGood == FALSE) 
   
   {
      while (1) 
      
         FlashEthled();	 /* spin here if error is flagged */
   } 
   /*-----------------------------------------------------------------*/
   /* Clear CPM Interrupt In-Service Register SCC1 bit (by writing 1) */
   /*-----------------------------------------------------------------*/
   IMMR->cpmi_cisr |= CISR_SCC1;
} /* 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 + -