hal_mac.c

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

C
422
字号
//-----------------------------------------------------------------------------
// HAL_MAC
//-----------------------------------------------------------------------------

#include "hal_mac.h"
#include "arp.h"
#include "ip.h"
#include "hal_gpio.h"
#include "tcpip_stack.h"

#include "stdlib.h"
#include "string.h"


//-----------------------------------------------------------------------------
// Ethernet MAC address + static IP address + Ethernet types
//-----------------------------------------------------------------------------

  u8 srcMAC[6] = {0x00,0x08,0x07,0x06,0x05,0x04};
  u8 destMAC[6] = {0x00,0x01,0x02,0x1C,0xAD,0x64};

  u8 srcIP[4] = {192,168,1,15};
  u8 destIP[4] = {192,168,1,2};

  u8 brcastADD[4] = {255,255,255,255};
  u8 etherIP[2]={0x08,0x00};
  u8 etherARP[2]={0x08,0x06};
  u8 httpPORT[2]={0x00,0x50};

//-----------------------------------------------------------------------------
// MAC-DMA
// Declarations of Frame Descriptor tables for RX and TX + declaration of pointers
//-----------------------------------------------------------------------------

static DmaMacDescr  *RX_MAC_DescrTable;       // Ptr to RX Descriptor Table
static u16          RX_MAC_currDescNum = 0;   // RX DescrTable current element

static DmaMacDescr  *TX_MAC_DescrTable;       // Ptr to TX Descriptor Table
static u16          TX_MAC_currDescNum = 0;   // TX DescrTable current element

//-----------------------------------------------------------------------------
//name:MAC_GetPhyLayer()
//funcionality: Communication with Ethernet phy, ready to be used with
//STE100P and STE101P
//-----------------------------------------------------------------------------
void MAC_GetPhyLayer(
                u16 PHYnum,  // PHY num
                u16 PHYreg,  // PHY register num
                u16 *CtrlBit // PHY Operation Mode
                )

{
        *CtrlBit = 0x0;
        while (MAC->MII_ADDR & Mii_Busy);        // wait

        // Program PHY address
        MAC->MII_ADDR    = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk);

        while (MAC->MII_ADDR & Mii_Busy);        // wait

        *CtrlBit = MAC->MII_DATA;

        while (MAC->MII_ADDR & Mii_Busy);        // wait

}

//-----------------------------------------------------------------------------
//name:MAC_SetPhyLayer()
//funcionality: Communication with Ethernet phy, ready to be used with
//STE100P and STE101P
//-----------------------------------------------------------------------------
void MAC_SetPhyLayer
                (
                u16 PHYnum,  // PHY num
                u16 PHYreg,  // PHY register num
                u16 CtrlBit, // Bit to be set/reset
                u16 Set      // Turn Off (0) or On (1) the mode
                )
{
	volatile unsigned int tmpval = 0;
	
        while (MAC->MII_ADDR & Mii_Busy);        // wait

        // Program PHY address
        MAC->MII_ADDR    = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk);

        while (MAC->MII_ADDR & Mii_Busy);        // wait
        tmpval = MAC->MII_DATA;
        while (MAC->MII_ADDR & Mii_Busy);        // wait
	
        // Set/Clear Control Bit.
        if (Set)
                MAC->MII_DATA    = tmpval | CtrlBit;
        else
                MAC->MII_DATA    = tmpval & ~CtrlBit;

        //Program PHY address + write bit set
        MAC->MII_ADDR    = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk) | Mii_Write;

        while (MAC->MII_ADDR & Mii_Busy);        // wait

        // DUMMY READ; phy bug? = additional code
        MAC->MII_ADDR    = ((PHYnum * Phy_AddrU) & Phy_AddrMsk) | ((PHYreg * Mii_RegisterU) & Mii_RegisterMsk);

        while (MAC->MII_ADDR & Mii_Busy);        // wait
	tmpval = MAC->MII_DATA;
        while (MAC->MII_ADDR & Mii_Busy);        // wait

}


//-----------------------------------------------------------------------------
// name: MAC_Init()
// functionality: Initialization of the Ethernet phy + allocation of DMA descritpor chain
// (Frame Descriptor Tables)
//-----------------------------------------------------------------------------
int MAC_Init()
{
        int i;
        u16 LanStatus;

	/*****************************************
	 * INIT DMA MAC controller
	 *****************************************/
	// Turn the reset off
	DMA_MAC->DMA_STS_CNTL  &= ~DmaMac_SRst;
	
	// Program the DMA Burst Length for TX/RX
	DMA_MAC->DMA_STS_CNTL    |= DmaMac_RXBurst_08 | DmaMac_TXBurst_04;

	// Program the DMA_MAC interrupts
        DMA_MAC->DMA_INT_EN =  DmaMac_RxCurrDone | DmaMac_TxCurrDone;

        //Clear all the interrupt pending bits
        DMA_MAC->DMA_INT_STS = 0xFFFFFFFF;

	/*****************************************
	 * INIT MAC110 controller
	 *****************************************/
	// Program the local MAC Address, should be loaded from EEPROM
	MAC->MAC_ADDL     =  srcMAC[0] +
			  (srcMAC[1] <<  8)+
			  (srcMAC[2] << 16)+
			  (srcMAC[3] << 24);
	
	MAC->MAC_ADDH    =  srcMAC[4] +
			  (srcMAC[5] << 8);
	
	MAC->MAC_CNTL   =  Mac_RxEn |
			   Mac_TxEn |
			   Mac_DfrChk |
			   Mac_NoHeartBeat |
			   Mac_AutoPadStrip |   //strips the PAD frame data
			   Mac_BckOff_04;

	MAC->MMC_CTRL_REG    =  Mmc_Reset |
			   Mmc_RollOver |
			   ((MAC_MAX_FRAME_SZ * Mmc_MaxFrmSzU) & Mmc_MaxFrmSzMsk);
	
	MAC -> MMC_INT_MSK_LO_REG = 0xffffffff;    // ALL Disabled!!!
	MAC -> MMC_INT_MSK_HI_REG = 0xffffffff;    // ALL Disabled!!!


	/*****************************************
	 * INIT the PHY by using MII
	 *****************************************/
	MAC_SetPhyLayer(PHY_NUM, Phy_CtrlReg, Phy_Reset, 1);
	MAC_GetPhyLayer(PHY_NUM, Phy_CtrlReg, &LanStatus);
	MAC_GetPhyLayer(PHY_NUM, Phy_QPDSReg, &LanStatus);

	
	/******************************************
	 * Build the Frame Descriptor table for RX.
	 ******************************************/
	RX_MAC_currDescNum = 0;
        RX_MAC_DescrTable = (DmaMacDescr *)calloc((RX_MAC_DESCR_NUM+1), sizeof(DmaMacDescr));

	if ( RX_MAC_DescrTable == NULL)
	{
		return 0;
	}
	
	/* Init the RX buffer descriptor table for this device, chain construction */
	for (i = 0; i < RX_MAC_DESCR_NUM; i++)
	{
		if (i < RX_MAC_DESCR_NUM - 1)
			RX_MAC_DescrTable[i].DmaMac_Next = ((int) &RX_MAC_DescrTable[i+1] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn;
		else
			RX_MAC_DescrTable[i].DmaMac_Next = ((int) &RX_MAC_DescrTable[0] & DmaMac_DescrAddrMsk) | DmaMac_NpolEn;

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

	/* Start the DMA for receiving. DMA must use word-aligned not-aliased descriptor pointer */
	DMA_MAC->RX_DMA_NXT   = ((int) RX_MAC_DescrTable & DmaMac_DescrAddrMsk) | DmaMac_NpolEn;
	DMA_MAC->RX_DMA_START =	DmaMac_StartFetch |
				((1000 * DmaMac_DFetchDlyU) & DmaMac_DFetchDlyMsk);

	
	/******************************************
	 * Build the Frame Descriptor table for TX.
	 ******************************************/
	TX_MAC_currDescNum = 0;
        TX_MAC_DescrTable = (DmaMacDescr *)calloc((TX_MAC_DESCR_NUM+1), sizeof(DmaMacDescr));

	/* Alloc the TX buffer descriptor table for this device. (TBD: '+ 1' ??) */

⌨️ 快捷键说明

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