hal_mac.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 380 行
C
380 行
//-----------------------------------------------------------------------------
// HAL_MAC
//-----------------------------------------------------------------------------
#include "hal_mac.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,16};
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' ??) */
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){
}
//-----------------------------------------------------------------------------
void MAC_IrqHandler_RxCurrDone(void){
}
//-----------------------------------------------------------------------------
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 + -
显示快捷键?