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

📄 aal5_sar.c

📁 MPC860SAR源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
* 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 SCCx)
*
*     Main Processing Steps:
*
*        (1) Save off SCCE for SCCx
*
*        (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 SCCx. 
*
*        (7) Clear SCCx Event Register
*
*        (8) Test SCCx Event
*
*        (9) Clear the SAR interrupt queue. 
*
*        (10) Clear SCCx bit CPM Interrupt In-Service Register
*
*
*     NOTE: This ISR will handle Synchronization and Global Interrupt 
*	    events in the SCC event registers.  The type of global 
*	    interrupt is further defined in the interrupt queue.  Global
*	    interrupts handled:  Received Frame & Transmit Buffer. 
*
* EXTERNAL EFFECTS:  interrupt related registers
*
* PARAMETERS:
*
*     vector - interrupt vector (address)
*
* RETURNS: NONE
*
*-----------------------------------------------------------------------------*/

void ExtIntHandler(UWORD vector)

{

   UWORD    sivec_ic;

   UWORD    mask = CISR_SCC1;

   BD_860SAR *ptr_xmit_bd; 
   BD_860SAR *ptr_rcv_bd; 
 
   UWORD bd_num;

   /* Get the starting address of the txmit buffer descriptor */
   ptr_xmit_bd = (BD_860SAR *)(IMMR->PRAM[SCC_num].sar.tbdbase); 


   /* Get the starting address of the receive buffer descriptor */
   ptr_rcv_bd = (BD_860SAR *)(IMMR->PRAM[SCC_num].sar.rbdbase); 

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

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

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

   if ((IMMR->cpmi_civr >> 11) !=  (0x1E - SCC_num)) 
   
      return;

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

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

   /*-------------------------------------------*/
   /* If it's the synchronization event, just   */
   /* return. main() will enable the xmiter.    */
   /*-------------------------------------------*/

   if(Event_register & SAR_SERIAL_SCCE_SYNC) 
     {
  
       /* Clear the event and service registers */
       /* before returning                      */

       IMMR->scc_regs[SCC_num].scc_scce = ALL_ONES;
       IMMR->cpmi_cisr |= (mask >> (1*SCC_num));

       /* Return control, the receiver achieved */
       /* synchronization                       */ 
       return;
     } 

   /*----------------------------------------------------------------*/
   /* Process Global Interrupt.  The only events (as defined in      */
   /* imask) generating an interrupt queue entry are the Transmit    */
   /* buffer and Receive Frame events.  The valid bit is cleared     */
   /* in the interrupt queue.                                        */
   /*----------------------------------------------------------------*/

   if(Event_register & SAR_SERIAL_SCCE_GINT)
   
   {
      /*-------------------------------------------------------------------*/
      /* The software expects to receive Frames in order of transmission   */
      /* and as such expects the received buffers to be filled sequentially*/
      /* as programmed by InitBDs().  Any errors detected in the status of */
      /* Rx or Tx BD status word will result in an error condition.        */
      /*-------------------------------------------------------------------*/

      /*-----------------------------------------*/
      /* Get Interrupt queue entry, we process   */ 
      /* all entries in the queue. i.e. while    */ 
      /* the valid bit in the queue entry is set */
      /*-----------------------------------------*/

      while(*Ptr_int_queue & Q_ENTRY_VALID)
        {

          /*****************************************/
          /* Check the Transmitt Buffer event.     */
          /*****************************************/
   
          if(*Ptr_int_queue & TXB)
            {
              /* Check That all frames where transmitted */
              /* (Ready bit is 0)                       */

              for(bd_num=0;bd_num < NUM_FRAMES;bd_num++,ptr_xmit_bd++)
                {
                  /* If the Ready bit is set, then flag an error */
                  /* This interrupt is generated ONLY when the   */
                  /* last Frame has been transmitted.            */

                  if(BDEmpty(ptr_xmit_bd->status))
                      RxGood=FALSE; 
                }

            } /* End of if(...TXB) */ 

            /*****************************************/
            /* Check the Receive Frame event.        */
            /*****************************************/

            /*---------------------------------------------------------*/
            /* Compare the Rx buffer with it's corresponding Tx buffer */
            /* buffer.  All Frames are received in order in which they */
            /* were transmitted.                                       */
            /*---------------------------------------------------------*/
   
            if(*Ptr_int_queue & RXF)
              {
                if (memcmp((Received_frames + (RxProcIndex * FRAME_LENGTH)),
                         (Frames_to_xmit + (RxProcIndex * FRAME_LENGTH)),
                         (FRAME_LENGTH)))
                   {
                     RxGood=FALSE; /* they didn't compare */
                   }
                
                /* The receive BD status should indicate that the buffer */
                /* is full                                               */

                if(BDEmpty(ptr_rcv_bd->status))
                   RxGood=FALSE; 

                /* Check if there were any errors */
                if(BDRxError(ptr_rcv_bd->status)) 
                   RxGood=FALSE; 

                ++ptr_rcv_bd;	/* Move on to next Buffer Descriptor */

                ++RxCount;	/* Increment Received Frame Count */

                RxProcIndex++; 

              } /* End of if(...RXF) */ 

            /* Clear the valid bit in the interrupt queue */ 
            *Ptr_int_queue &= 0x4FFFFFFF; 

            /***********************************************************/
            /* Reset the pointer if we've reached the last queue entry */
            /***********************************************************/

            if(*Ptr_int_queue & 0x40000000)
              {
               Ptr_int_queue =  (UWORD *)IMMR->PRAM[SCC_num].sar.intbase;
              }
		
            /* Increment the Queue Pointer */
            else
              {
               ++Ptr_int_queue; 
              }

          } /* End of while(...Q_ENTRY_VALID) */
            
        IMMR->scc_regs[SCC_num].scc_scce = ALL_ONES;
        IMMR->cpmi_cisr |= (mask >> (1*SCC_num));

   } /* End of if(..GINT) */ 
 
   else 
                      
      RxGood = FALSE; /* Error, expected a Global Interrupt in SCCE */

   /*---------------------------------------------------------------------*/
   /* Here's our error loop. Spin here indefinitly if there was an error. */
   /* NOTE: if you are debugging with SDS Monitor, set a breakpoint in    */
   /*       the FlashEthled() line below to prevent the debbuger from     */
   /*       hanging. This way, you can determine what caused the error.   */
   /*---------------------------------------------------------------------*/

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

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

   IMMR->cpmi_cisr |= (mask >> (1*SCC_num));

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