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

📄 mac.c

📁 嵌入式开发的实例
💻 C
📖 第 1 页 / 共 3 页
字号:


// Initialize MAC Controller
void MacInitialize(int num)
{
 //UART_printf("MacInitialize()\n");
 if (num==0)
   {
    // MAC interrupt vector setup.
    SetIntISR(EMCTXINT0, MAC0_Tx_isr) ;
    SetIntISR(EMCRXINT0, MAC0_Rx_isr) ;

    // Set the Tx and Rx Frame Descriptor
    TxFDInitialize(num) ;
    RxFDInitialize(num) ;

    // Set the CAM Control register and the MAC address value
    FillCamEntry(0, 0, gCam0M_0, gCam0L_0);
    CAMCMR_0 = gCAMCMR ;

    // Enable MAC Tx and Rx interrupt.
    Enable_Int(EMCTXINT0);
    Enable_Int(EMCRXINT0);

    // Configure the MAC control registers.
    ReadyMac(num) ;
   }
 else if (num==1)
   {
    // MAC interrupt vector setup.
    SetIntISR(EMCTXINT1, MAC1_Tx_isr) ;
    SetIntISR(EMCRXINT1, MAC1_Rx_isr) ;

    // Set the Tx and Rx Frame Descriptor
    TxFDInitialize(num) ;
    RxFDInitialize(num) ;

    // Set the CAM Control register and the MAC address value
    FillCamEntry(1, 0, gCam0M_1, gCam0L_1);
    CAMCMR_1 = gCAMCMR ;

    // Enable MAC Tx and Rx interrupt.
    Enable_Int(EMCTXINT1);
    Enable_Int(EMCRXINT1);
    
    // Configure the MAC control registers.
    ReadyMac(num) ;
   }
}


// Initialize Tx frame descriptor area-buffers.
void TxFDInitialize(int num)
{
 sFrameDescriptor *pFrameDescriptor;
 sFrameDescriptor *pStartFrameDescriptor;
 sFrameDescriptor *pLastFrameDescriptor = NULL;
 U32 FrameDataAddr;
 U32 i;

 if (num==0)
   {
    // Get Frame descriptor's base address.
    TXDLSA_0 = (U32)TxFDBaseAddr0;
    gWTxFDPtr[0] = gCTxFDPtr[0] = TXDLSA_0;

    // Get Transmit buffer base address.
    FrameDataAddr = (U32)TxFBABaseAddr0;

    // Generate linked list.
    pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[0];
    pStartFrameDescriptor = pFrameDescriptor;

    for(i=0; i < MaxTxFrameDescriptors; i++)
    {
     if (pLastFrameDescriptor == NULL)
       pLastFrameDescriptor = pFrameDescriptor;
     else
       pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;

     pFrameDescriptor->Status1 = 0;
     pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
     pFrameDescriptor->Status2 = (U32)0x0;
     pFrameDescriptor->NextFrameDescriptor = NULL;

     pLastFrameDescriptor = pFrameDescriptor;
     pFrameDescriptor++;
     FrameDataAddr += sizeof(sMACFrame);
    }

    // Make Frame descriptor to ring buffer type.
    pFrameDescriptor--;
    pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
   }
 else if (num==1)
   {
    // Get Frame descriptor's base address.
    TXDLSA_1 = (U32)TxFDBaseAddr1;
    gWTxFDPtr[1] = gCTxFDPtr[1] = TXDLSA_1;

    // Get Transmit buffer base address.
    FrameDataAddr = (U32)TxFBABaseAddr1;

    // Generate linked list.
    pFrameDescriptor = (sFrameDescriptor *) gCTxFDPtr[1];
    pStartFrameDescriptor = pFrameDescriptor;

    for(i=0; i < MaxTxFrameDescriptors; i++)
    {
     if (pLastFrameDescriptor == NULL)
       pLastFrameDescriptor = pFrameDescriptor;
     else
       pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;

     pFrameDescriptor->Status1 = 0;
     pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
     pFrameDescriptor->Status2 = (U32)0x0;
     pFrameDescriptor->NextFrameDescriptor = NULL;

     pLastFrameDescriptor = pFrameDescriptor;
     pFrameDescriptor++;
     FrameDataAddr += sizeof(sMACFrame);
    }

    // Make Frame descriptor to ring buffer type.
    pFrameDescriptor--;
    pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
   }
}


// Initialize Rx frame descriptor area-buffers.
void RxFDInitialize(int num)
{
 sFrameDescriptor *pFrameDescriptor;
 sFrameDescriptor *pStartFrameDescriptor;
 sFrameDescriptor *pLastFrameDescriptor = NULL;
 U32 FrameDataAddr;
 U32 i;

 if (num==0)
   {
    // Get Frame descriptor's base address.
    RXDLSA_0 = (U32)RxFDBaseAddr0;
    gCRxFDPtr[0] = RXDLSA_0;

    // Get Transmit buffer base address.
    FrameDataAddr = (U32)RxFBABaseAddr0;

    // Generate linked list.
    pFrameDescriptor = (sFrameDescriptor *) gCRxFDPtr[0];
    pStartFrameDescriptor = pFrameDescriptor;

    for(i=0; i < MaxRxFrameDescriptors; i++)
    {
     if (pLastFrameDescriptor == NULL)
       pLastFrameDescriptor = pFrameDescriptor;
     else
       pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;

     pFrameDescriptor->Status1 = RXfOwnership_DMA;
     pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
     pFrameDescriptor->Status2 = (U32)0x0;
     pFrameDescriptor->NextFrameDescriptor = NULL;

     pLastFrameDescriptor = pFrameDescriptor;
     pFrameDescriptor++;
     FrameDataAddr += sizeof(sMACFrame);
    }

    // Make Frame descriptor to ring buffer type.
    pFrameDescriptor--;
    pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
   }
 else if (num==1)
   {
    // Get Frame descriptor's base address.
    RXDLSA_1 = (U32)RxFDBaseAddr1;
    gCRxFDPtr[1] = RXDLSA_1;

    // Get Transmit buffer base address.
    FrameDataAddr = (U32)RxFBABaseAddr1;

    // Generate linked list.
    pFrameDescriptor = (sFrameDescriptor *) gCRxFDPtr[1];
    pStartFrameDescriptor = pFrameDescriptor;

    for(i=0; i < MaxRxFrameDescriptors; i++)
    {
     if (pLastFrameDescriptor == NULL)
       pLastFrameDescriptor = pFrameDescriptor;
     else
       pLastFrameDescriptor->NextFrameDescriptor = (U32)pFrameDescriptor;

     pFrameDescriptor->Status1 = RXfOwnership_DMA;
     pFrameDescriptor->FrameDataPtr = (U32)FrameDataAddr;
     pFrameDescriptor->Status2 = (U32)0x0;
     pFrameDescriptor->NextFrameDescriptor = NULL;

     pLastFrameDescriptor = pFrameDescriptor;
     pFrameDescriptor++;
     FrameDataAddr += sizeof(sMACFrame);
    }

    // Make Frame descriptor to ring buffer type.
    pFrameDescriptor--;
    pFrameDescriptor->NextFrameDescriptor = (U32)pStartFrameDescriptor;
   }
}



// set Registers related with MAC.
void ReadyMac(int num)
{
 if (num==0)
   {
     if (EXTERNAL_LOOPBACK_PORT == 0)
     {
         MIEN_0 = gMIEN | EnTDU | EnTXEMP | EnRXOV | EnCRCE | EnRDU;
         MCMDR_0 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_ALP | MCMDR_ARP;
     }
     else
     {
         MIEN_0 = gMIEN ;
        //MCMDR_0 = gMCMDR ;
    
        //CMN
        MCMDR_0 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_SPCRC; 
     }
   }
 else if (num==1)
   {
    
     if (EXTERNAL_LOOPBACK_PORT == 1)
     {
         MIEN_1 = gMIEN | EnTDU | EnTXEMP | EnRXOV | EnCRCE | EnRDU;
         //MCMDR_0 = gMCMDR ;
    
         //CMN
         //Collect ANY packet (Runt, Long and CRC error) !!!
         MCMDR_1 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_ALP | MCMDR_ARP;
      }
      else
      {
         MIEN_1 = gMIEN ;        
         MCMDR_1 = MCMDR_RXON | MCMDR_EnMDC | MCMDR_FDUP | MCMDR_SPCRC; 
      }
      
   }
}


// MAC Transfer Start for interactive mode
void MacTxGo(int num)
{
 if (num==0)
   {
    if (!(MCMDR_0&MCMDR_TXON))
      MCMDR_0 |= MCMDR_TXON ;
       
    TSDR_0 = 0;  
   } 
 else if (num==1)
   {
    if (!(MCMDR_1&MCMDR_TXON))
      MCMDR_1 |= MCMDR_TXON ;

    TSDR_1 = 0;  
   } 
}


// Mac Rx Off and disable all interrupts
void MacRxOff(int num)
{
 if (num==0)
   MCMDR_0 &= ~MCMDR_RXON ;
 else
   MCMDR_1 &= ~MCMDR_RXON ;
}


//CMN
void CheckTxFDStatus(int port, sFrameDescriptor *pTxFDptr)
{
   U32 Status;
   
   Status = (pTxFDptr->Status2 >> 16) & 0xffff;

   if (Status & TXFD_TXCP)
   {
       gsMacTxStatus[port].TXCP++ ;  
       gsMacTxStatus[port].TxBytes += pTxFDptr->Status2 & 0xFFFF;
       
       TxPktSeq = *((volatile U32 *) (pTxFDptr->FrameDataPtr + 16));
       if (TxPktSeq != TxPktSeqWanted)
       {
           *((volatile unsigned int *) 0xFFF03210) = 0x43;
           TxPktSeqErr++;
           TxPktSeqWanted = TxPktSeq+1;
       }
       else
           TxPktSeqWanted++;
       
   }
   else 
        gTxErrPacketCnt[port]++;
       
   // Save Error status
   if (Status & TXFD_TXABT) gsMacTxStatus[port].TXABT++ ;
   if (Status & TXFD_DEF)   gsMacTxStatus[port].DEF++ ;
   if (Status & TXFD_PAU)   gsMacTxStatus[port].PAU++ ;
   if (Status & TXFD_EXDEF) gsMacTxStatus[port].EXDEF++ ;
   if (Status & TXFD_NCS)   gsMacTxStatus[port].NCS++ ;
   if (Status & TXFD_SQE)   gsMacTxStatus[port].SQE++ ;
   if (Status & TXFD_LC)    gsMacTxStatus[port].LC++ ;
   if (Status & TXFD_TXHA)  gsMacTxStatus[port].TXHA++ ;
 
   pTxFDptr->Status2 &= (U32) 0x0000FFFF;
   gCTxFDPtr[port] = (U32)pTxFDptr->NextFrameDescriptor ;

}


// Interrupt Service Routine for MAC0 Tx
void MAC0_Tx_isr(void)
{   
 sFrameDescriptor *pTxFDptr;
 U32 *pFrameDataPtr ;
 U32 Status, RdValue;
 U32 CTxPtr ;
   
 RdValue=MISTA_0;
 
 
 if (RdValue & 0x00800000)
     gsMacTxStatus[0].TDU++;
     
 if (RdValue & 0x00020000)
     gsMacTxStatus[0].EMP++;
  
 MISTA_0=RdValue&0xffff0000;
 
#ifdef TxInt_Msg
 UART_printf("MAC0_Tx_isr(%x)\n",RdValue) ;
#endif 

 if (RdValue & MISTA_TxBErr)
   {
    FIFOTHD_0|=SWR;
    LanInitialize(0);
    MacRxDoneFlagForLoopBackCheck[0] = 1 ;
    gsMacTxStatus[0].TxBErr++ ; //CMN
   }
 else
   {  
    CTxPtr = CTXDSA_0 ;

    while ( gCTxFDPtr[0] != CTxPtr )
    {
     pTxFDptr = (sFrameDescriptor *) gCTxFDPtr[0];

     // Check CPU ownership, if Owner is DMA then break
     pFrameDataPtr = (U32 *)&pTxFDptr->Status1;
     if ( (*pFrameDataPtr & TXfOwnership_DMA) )
       break ;

     Status = (pTxFDptr->Status2 >> 16) & 0xffff;

     if (Status & TXFD_TXCP)
     {
       gsMacTxStatus[0].TXCP++ ;  
       gsMacTxStatus[0].TxBytes += pTxFDptr->Status2 & 0xFFFF; //CMN
       
#if 1
       if (EXTERNAL_LOOPBACK_PORT == 0)
       {
           TxPktSeq = *((volatile U32 *) (pTxFDptr->FrameDataPtr + 16));
           if (TxPktSeq != TxPktSeqWanted)
           {           
               TxPktSeqErr++;
               TxPktSeqWanted = TxPktSeq+1;
           }
           else
               TxPktSeqWanted++;
       }
#endif       
     }
     else
        gTxErrPacketCnt[0]++;
       
      // Save Error status
      if (Status & TXFD_TXABT) gsMacTxStatus[0].TXABT++ ;
      if (Status & TXFD_DEF)   gsMacTxStatus[0].DEF++ ;
      if (Status & TXFD_PAU)   gsMacTxStatus[0].PAU++ ;
      if (Status & TXFD_EXDEF) gsMacTxStatus[0].EXDEF++ ;
      if (Status & TXFD_NCS)   gsMacTxStatus[0].NCS++ ;
      if (Status & TXFD_SQE)   gsMacTxStatus[0].SQE++ ;
      if (Status & TXFD_LC)    gsMacTxStatus[0].LC++ ;
      if (Status & TXFD_TXHA)  gsMacTxStatus[0].TXHA++ ;
       
     // Clear Framedata pointer already used.
     pTxFDptr->Status2 &= (U32) 0x0000FFFF;

     gCTxFDPtr[0] = (U32)pTxFDptr->NextFrameDescriptor ;
    }
  
    MacTxDoneFlagForLoopBackCheck[0] = 1 ;
   }
}


// Interrupt Service Routine for MAC1 Tx
void MAC1_Tx_isr(void)
{   
 sFrameDescriptor *pTxFDptr;
 U32 *pFrameDataPtr ;
 U32 Status, RdValue;
 U32 CTxPtr ;
 
 RdValue=MISTA_1;
  
 if (RdValue & 0x00800000)
     gsMacTxStatus[1].TDU++;
     
 if (RdValue & 0x00020000)
     gsMacTxStatus[1].EMP++;
 
 MISTA_1=RdValue&0xffff0000;
 
#ifdef TxInt_Msg
 UART_printf("MAC1_Tx_isr(%x)\n",RdValue) ;
#endif 
 
 if (RdValue & MISTA_TxBErr)
   {
    FIFOTHD_1|=SWR;
    LanInitialize(1);
    MacTxDoneFlagForLoopBackCheck[1] = 1 ;
    gsMacTxStatus[1].TxBErr++;  
   } 
 else
   {
    CTxPtr = CTXDSA_1 ;

⌨️ 快捷键说明

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