hal_mac.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 422 行 · 第 1/2 页

C
422
字号
	if (TX_MAC_DescrTable == NULL)
	{
		return 0;
	}
	
	/* Init the TX buffer descriptor table for this device, chain construction */
	for (i = 0; i < TX_MAC_DESCR_NUM; i++)
	{
		if (i < TX_MAC_DESCR_NUM - 1)
			TX_MAC_DescrTable[i].DmaMac_Next = ((int) &TX_MAC_DescrTable[i+1] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn;
		else
			TX_MAC_DescrTable[i].DmaMac_Next = ((int) &TX_MAC_DescrTable[0] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn;

	
		TX_MAC_DescrTable[i].TxRx_Status = 0x0;
		TX_MAC_DescrTable[i].DmaMac_Addr = (int)(TX_MAC_DescrTable[i].FrameBuf);	
		TX_MAC_DescrTable[i].DmaMac_Cntl = DmaMac_NxtEn |
	            				    (MAC_MAX_FRAME_SZ & DmaMac_XferCntMsk) |
	                                            ((3 * DmaMac_EntryTrigU) & DmaMac_EntryTrigMsk);
	}

	/* Start the DMA for sending */
	DMA_MAC->TX_DMA_NXT   = ((int) TX_MAC_DescrTable & DmaMac_DescrAddrMsk) | DmaMac_NpolEn;

        return 1; //MAC initialized
}

//-----------------------------------------------------------------------------
// name: MAC_Send()
// functionality: Builds and Sends an Ethernet frame
//-----------------------------------------------------------------------------
int MAC_Send(EthernetFrame *frame, u16 len)
{
	u8	*dest; //pointer to the data to be sent
        u32	DmaStat;
        u8 *Buffer;


        if (!len) {
          len = ETHER_HEADER_LENGTH; //
                  //Check whether the length of the frame is not too long
          if (len >= MAC_MAX_FRAME_SZ)
	        {
		  return 0;  //frame too long
	        }
        }

        Buffer = frame->EthernetFrameByByte;

        //Check whether the current DMA descriptor VALID bit is 0 -> CPU is the owner -> continue
 	DmaStat = TX_MAC_DescrTable[TX_MAC_currDescNum].TxRx_Status;
 	if (DmaStat & DmaMac_Valid)
		return 0;

	dest = TX_MAC_DescrTable[TX_MAC_currDescNum].FrameBuf; //pointer to the data to be sent

        //Data is copied
	memcpy(dest, Buffer, len);

        //Prepares settings of the TX_DMA_CNTL register
        TX_MAC_DescrTable[TX_MAC_currDescNum].DmaMac_Cntl  = DmaMac_NxtEn |
	            				    		(len & DmaMac_XferCntMsk) |
	                                            		((3 * DmaMac_EntryTrigU) & DmaMac_EntryTrigMsk);

        //Set the VALID bit to 1, enables DMA to access the Current Descriptor
        TX_MAC_DescrTable[TX_MAC_currDescNum].TxRx_Status   = DmaMac_Valid;

	DMA_MAC->TX_DMA_START   |= DmaMac_StartFetch | ((1000 * DmaMac_DFetchDlyU) & DmaMac_DFetchDlyMsk);


        /* Test the wrap-around condition. */
        if (++TX_MAC_currDescNum >= TX_MAC_DESCR_NUM)
                TX_MAC_currDescNum = 0;

        return 1;
}

//-----------------------------------------------------------------------------
// name: MAC_Recv()
// functionality: Receives an Ethernet frame
//-----------------------------------------------------------------------------
u16 MAC_Recv(EthernetFrame *frame)
{
        u16     type = 0;
        u32     DmaStat;

        while(1)
        {
 		DmaStat = RX_MAC_DescrTable[RX_MAC_currDescNum].TxRx_Status;
 		if (DmaStat & DmaMac_Valid)
			break;
                type = *(u16 *)&RX_MAC_DescrTable[RX_MAC_currDescNum].FrameBuf[2*MAC_ADDR_LEN];

                //Data is copied
                memcpy(frame->EthernetFrameByByte, RX_MAC_DescrTable[RX_MAC_currDescNum].FrameBuf, MAC_MAX_FRAME_SZ);
		
		/* Make the current descriptor valid again and go to the next one */
		RX_MAC_DescrTable[RX_MAC_currDescNum].TxRx_Status = DmaMac_Valid;

		/* Test the wrap-around condition. */
		if (++RX_MAC_currDescNum >= RX_MAC_DESCR_NUM)
			RX_MAC_currDescNum = 0;
        }

	return type;
}


//-----------------------------------------------------------------------------
//*                                                                         *//
//*                                                                         *//
//*                                                                         *//
//*                         DMA MAC irq handler routines                    *//
//*                                                                         *//
//*                                                                         *//
//*                                                                         *//
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxEmpty(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxFull(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxEntry(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxTo(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_PckLost(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxNext(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxDone(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxMErr(void){
}
//-----------------------------------------------------------------------------
// Analyses of the received frame for its content
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxCurrDone(void){

    EthernetFrame frame;
    u16 frametype;

    if (!(frametype = MAC_Recv(&frame))) return;

    ChangeEndianess_16(frametype); //macro

    switch (frametype){
        case ETHER_IP:{

                      switch (Rx_Ip_Frame(&frame)){  //check whether the packet is OK
                      case IP_ICMP:{
                                   Receive_ICMP(&frame);
                                   break;
                                   }
                      case IP_UDP: {
                                   Receive_UDP(&frame);
                                   break;
                                   }
                      case IP_TCP: {
                                   Receive_TCP(&frame);
                                   break;
                                   }
                      default:     break;
                      }
                      break;
        }

        case ETHER_ARP:{
                      Receive_ARP(&frame);
                      break;
        }

        default :     break; //for not supported frame types
    }
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxEmpty(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxFull(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxEntry(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxTo(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxNext(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxDone(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxMErr(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_MACInt(void){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_TxCurrDone(void){

}
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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