39#define PHY_CNTL_REG 0x00
40#define PHY_STATUS_REG 0x01
41#define PHY_ID1_REG 0x02
42#define PHY_ID2_REG 0x03
43#define PHY_ANA_REG 0x04
44#define PHY_ANLPA_REG 0x05
45#define PHY_ANE_REG 0x06
48#define PHY_CNTL_RESET_PHY (1 << 15)
49#define PHY_CNTL_DR_100MB (1 << 13)
50#define PHY_CNTL_ENABLE_AN (1 << 12)
51#define PHY_CNTL_POWER_DOWN (1 << 11)
52#define PHY_CNTL_RESTART_AN (1 << 9)
53#define PHY_CNTL_FULLDUPLEX (1 << 8)
56#define PHY_STATUS_AN_COMPLETE (1 << 5)
57#define PHY_STATUS_LINK_VALID (1 << 2)
60#define PHY_ANA_DR100_TX_FULL (1 << 8)
61#define PHY_ANA_DR100_TX_HALF (1 << 7)
62#define PHY_ANA_DR10_TX_FULL (1 << 6)
63#define PHY_ANA_DR10_TX_HALF (1 << 5)
64#define PHY_ANA_IEEE_802_3_CSMA_CD (1 << 0)
67#define PHY_ANLPA_DR100_TX_FULL (1 << 8)
68#define PHY_ANLPA_DR100_TX_HALF (1 << 7)
69#define PHY_ANLPA_DR10_TX_FULL (1 << 6)
70#define PHY_ANLPA_DR10_TX_HALF (1 << 5)
73#define EMAC_DESC_OWN_EMAC 0x80000000
74#define EMAC_DESC_OWN_CPU 0x00000000
77#define EMAC_RXFD_RTSAS 0x0080
78#define EMAC_RXFD_RP 0x0040
79#define EMAC_RXFD_ALIE 0x0020
80#define EMAC_RXFD_RXGD 0x0010
81#define EMAC_RXFD_PTLE 0x0008
82#define EMAC_RXFD_CRCE 0x0002
83#define EMAC_RXFD_RXINTR 0x0001
86#define EMAC_TXFD_TTSEN 0x08
87#define EMAC_TXFD_INTEN 0x04
88#define EMAC_TXFD_CRCAPP 0x02
89#define EMAC_TXFD_PADEN 0x01
92#define EMAC_TXFD_TXINTR 0x0001
93#define EMAC_TXFD_DEF 0x0002
94#define EMAC_TXFD_TXCP 0x0008
95#define EMAC_TXFD_EXDEF 0x0010
96#define EMAC_TXFD_NCS 0x0020
97#define EMAC_TXFD_TXABT 0x0040
98#define EMAC_TXFD_LC 0x0080
99#define EMAC_TXFD_TXHA 0x0100
100#define EMAC_TXFD_PAU 0x0200
101#define EMAC_TXFD_SQE 0x0400
102#define EMAC_TXFD_TTSAS 0x0800
124 uint8_t au8Buf[1520];
136static uint32_t u32CurrentTxDesc, u32NextTxDesc, u32CurrentRxDesc;
137static uint32_t s_u32EnableTs = 0;
148#define EMAC_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
155#define EMAC_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
164static void EMAC_MdioWrite(uint32_t u32Reg, uint32_t u32Addr, uint32_t u32Data)
169 EMAC->MIIMDAT = u32Data ;
187static uint32_t EMAC_MdioRead(uint32_t u32Reg, uint32_t u32Addr)
200 return EMAC->MIIMDAT;
211int32_t EMAC_PhyInit(
void)
217 EMAC_MdioWrite(PHY_CNTL_REG,
EMAC_PHY_ADDR, PHY_CNTL_RESET_PHY);
225 if ((reg & PHY_CNTL_RESET_PHY)==0)
234 while(!(EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID))
242 EMAC_MdioWrite(PHY_ANA_REG,
EMAC_PHY_ADDR, PHY_ANA_DR100_TX_FULL |
243 PHY_ANA_DR100_TX_HALF |
244 PHY_ANA_DR10_TX_FULL |
245 PHY_ANA_DR10_TX_HALF |
246 PHY_ANA_IEEE_802_3_CSMA_CD);
253 while(!(EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_AN_COMPLETE))
264 while(!(EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID))
274 if (reg & PHY_ANLPA_DR100_TX_FULL)
280 else if (reg & PHY_ANLPA_DR100_TX_HALF)
284 EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
286 else if (reg & PHY_ANLPA_DR10_TX_FULL)
289 EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
295 EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
296 EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
301 EMAC->CTL &= ~EMAC_CTL_OPMODE_Msk;
302 EMAC->CTL &= ~EMAC_CTL_FUDUP_Msk;
311static void EMAC_TxDescInit(
void)
316 EMAC->TXDSA = (uint32_t)&tx_desc[0];
317 u32NextTxDesc = u32CurrentTxDesc = (uint32_t)&tx_desc[0];
323 tx_desc[i].u32Status1 = EMAC_TXFD_PADEN | EMAC_TXFD_CRCAPP | EMAC_TXFD_INTEN;
325 tx_desc[i].u32Status1 = EMAC_TXFD_PADEN | EMAC_TXFD_CRCAPP | EMAC_TXFD_INTEN | EMAC_TXFD_TTSEN;
327 tx_desc[i].u32Data = (uint32_t)((uint32_t)&tx_buf[i]);
328 tx_desc[i].u32Backup1 = tx_desc[i].u32Data;
329 tx_desc[i].u32Status2 = 0;
331 tx_desc[i].u32Backup2 = tx_desc[i].u32Next;
343static void EMAC_RxDescInit(
void)
349 EMAC->RXDSA = (uint32_t)&rx_desc[0];
350 u32CurrentRxDesc = (uint32_t)&rx_desc[0];
354 rx_desc[i].u32Status1 = EMAC_DESC_OWN_EMAC;
355 rx_desc[i].u32Data = (uint32_t)((uint32_t)&rx_buf[i]);
356 rx_desc[i].u32Backup1 = rx_desc[i].u32Data;
357 rx_desc[i].u32Status2 = 0;
359 rx_desc[i].u32Backup2 = rx_desc[i].u32Next;
369static uint32_t EMAC_Subsec2Nsec(uint32_t subsec)
373 i = 1000000000ll * subsec;
383static uint32_t EMAC_Nsec2Subsec(uint32_t nsec)
387 i = (1ll << 31) * nsec;
447 return (EMAC_PhyInit());
480 uint32_t u32Lsw, u32Msw;
482 u32Lsw = (pu8MacAddr[4] << 24) |
483 (pu8MacAddr[5] << 16);
484 u32Msw = (pu8MacAddr[0] << 24)|
485 (pu8MacAddr[1] << 16)|
486 (pu8MacAddr[2] << 8)|
489 *(uint32_t
volatile *)(&
EMAC->CAM0M + u32Entry * 2) = u32Msw;
490 *(uint32_t
volatile *)(&
EMAC->CAM0L + u32Entry * 2) = u32Lsw;
492 EMAC->CAMEN |= (1 << u32Entry);
502 EMAC->CAMEN &= ~(1 << u32Entry);
518 EMAC_DESCRIPTOR_T *desc;
519 uint32_t status, reg;
520 uint32_t u32Count = 0;
524 EMAC->INTSTS = reg & 0xFFFF;
529 printf(
"RX bus error\n");
536 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
541 if ((desc->u32Status1 & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
544 status = desc->u32Status1 >> 16;
547 if(status & EMAC_RXFD_RXGD)
550 *pu32Size = desc->u32Status1 & 0xffff;
551 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
557 if (status & EMAC_RXFD_RP) {}
559 if (status & EMAC_RXFD_ALIE) {}
561 if (status & EMAC_RXFD_PTLE) {}
563 if (status & EMAC_RXFD_CRCE) {}
584uint32_t
EMAC_RecvPktTS(uint8_t *pu8Data, uint32_t *pu32Size, uint32_t *pu32Sec, uint32_t *pu32Nsec)
586 EMAC_DESCRIPTOR_T *desc;
587 uint32_t status, reg;
588 uint32_t u32Count = 0;
592 EMAC->INTSTS = reg & 0xFFFF;
597 printf(
"RX bus error\n");
604 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
607 if(
EMAC->CRXDSA == (uint32_t)desc)
609 if ((desc->u32Status1 | EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
612 status = desc->u32Status1 >> 16;
615 if(status & EMAC_RXFD_RXGD)
618 *pu32Size = desc->u32Status1 & 0xffff;
619 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
621 *pu32Sec = desc->u32Next;
622 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data);
629 if (status & EMAC_RXFD_RP) {}
631 if (status & EMAC_RXFD_ALIE) {}
633 if (status & EMAC_RXFD_PTLE) {}
635 if (status & EMAC_RXFD_CRCE) {}
651 EMAC_DESCRIPTOR_T *desc;
653 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
656 desc->u32Data = desc->u32Backup1;
657 desc->u32Next = desc->u32Backup2;
660 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
663 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
666 u32CurrentRxDesc = (uint32_t)desc;
684 EMAC_DESCRIPTOR_T *desc;
688 desc = (EMAC_DESCRIPTOR_T *)u32NextTxDesc;
690 status = desc->u32Status1;
693 if((status & EMAC_DESC_OWN_EMAC))
696 memcpy((uint8_t *)desc->u32Data, pu8Data, u32Size);
699 desc->u32Status2 = u32Size;
702 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
705 u32NextTxDesc = (uint32_t)(desc->u32Next);
725 EMAC_DESCRIPTOR_T *desc;
726 uint32_t status, reg;
727 uint32_t last_tx_desc;
728 uint32_t u32Count = 0;
732 EMAC->INTSTS = reg & (0xFFFF0000 & ~EMAC_INTSTS_TSALMIF_Msk);
738 printf(
"TX bus error\n");
744 last_tx_desc =
EMAC->CTXDSA ;
746 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
750 if(desc->u32Status1 & EMAC_DESC_OWN_EMAC)
753 status = desc->u32Status2 >> 16;
754 if (status & EMAC_TXFD_TXCP)
761 if (status & EMAC_TXFD_TXABT) {}
763 if (status & EMAC_TXFD_DEF) {}
765 if (status & EMAC_TXFD_PAU) {}
767 if (status & EMAC_TXFD_EXDEF) {}
769 if (status & EMAC_TXFD_NCS) {}
771 if (status & EMAC_TXFD_SQE) {}
773 if (status & EMAC_TXFD_LC) {}
775 if (status & EMAC_TXFD_TXHA) {}
779 desc->u32Data = desc->u32Backup1;
780 desc->u32Next = desc->u32Backup2;
782 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
784 while (last_tx_desc != (uint32_t)desc);
786 u32CurrentTxDesc = (uint32_t)desc;
805 EMAC_DESCRIPTOR_T *desc;
806 uint32_t status, reg;
807 uint32_t u32Count = 0;
811 EMAC->INTSTS = reg & (0xFFFF0000 & ~EMAC_INTSTS_TSALMIF_Msk);
817 printf(
"TX bus error\n");
824 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
827 if(desc->u32Status1 & EMAC_DESC_OWN_EMAC)
830 status = desc->u32Status2 >> 16;
831 if (status & EMAC_TXFD_TXCP)
834 *pu32Sec = desc->u32Next;
835 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data);
840 if (status & EMAC_TXFD_TXABT) {}
842 if (status & EMAC_TXFD_DEF) {}
844 if (status & EMAC_TXFD_PAU) {}
846 if (status & EMAC_TXFD_EXDEF) {}
848 if (status & EMAC_TXFD_NCS) {}
850 if (status & EMAC_TXFD_SQE) {}
852 if (status & EMAC_TXFD_LC) {}
854 if (status & EMAC_TXFD_TXHA) {}
858 desc->u32Data = desc->u32Backup1;
859 desc->u32Next = desc->u32Backup2;
861 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
864 u32CurrentTxDesc = (uint32_t)desc;
882 EMAC->UPDSEC = u32Sec;
883 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
893 f = (100.0 * 2147483648.0) / (1000000000.0) + 0.5;
894 EMAC->TSINC = (reg = (uint32_t)f);
895 f = (double)9223372036854775808.0 / ((
double)(
CLK_GetHCLKFreq()) * (
double)reg);
896 EMAC->TSADDEND = (uint32_t)f;
919 *pu32Nsec = EMAC_Subsec2Nsec(
EMAC->TSSUBSEC);
920 *pu32Sec =
EMAC->TSSEC;
933 EMAC->UPDSEC = u32Sec;
934 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
948 EMAC->ALMSEC = u32Sec;
949 EMAC->ALMSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
962 EMAC->TSCTL &= ~EMAC_TSCTL_TSALMEN_Msk;
975 EMAC->UPDSEC = u32Sec;
976 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
NUC472/NUC442 peripheral access layer header file. This file contains all the peripheral register's d...
#define EMAC_INTEN_RXBEIEN_Msk
#define EMAC_TSCTL_TSIEN_Msk
#define EMAC_INTSTS_RXBEIF_Msk
#define EMAC_MIIMCTL_PHYADDR_Pos
#define EMAC_TSCTL_TSEN_Msk
#define EMAC_CAMCTL_AMP_Msk
#define EMAC_INTEN_TSALMIEN_Msk
#define EMAC_INTEN_TXCPIEN_Msk
#define EMAC_CTL_RMIIRXCTL_Msk
#define EMAC_CTL_OPMODE_Msk
#define EMAC_INTSTS_TXBEIF_Msk
#define EMAC_CAMCTL_ABP_Msk
#define EMAC_INTEN_TXBEIEN_Msk
#define EMAC_CTL_FUDUP_Msk
#define EMAC_TSCTL_TSALMEN_Msk
#define EMAC_INTEN_RXGDIEN_Msk
#define EMAC_INTEN_TXIEN_Msk
#define EMAC_CAMCTL_CMPEN_Msk
#define EMAC_INTEN_RXIEN_Msk
#define EMAC_CTL_STRIPCRC_Msk
#define EMAC_TSCTL_TSUPDATE_Msk
#define EMAC_MIIMCTL_MDCON_Msk
#define EMAC_MIIMCTL_WRITE_Msk
#define EMAC_MIIMCTL_BUSY_Msk
#define EMAC_CTL_RMIIEN_Msk
#define EMAC_TSCTL_TSMODE_Msk
#define EMAC_INTEN_WOLIEN_Msk
#define EMAC_INTEN_RDUIEN_Msk
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
int32_t g_EMAC_i32ErrCode
#define EMAC_PHY_ADDR
PHY address, this address is board dependent.
#define EMAC_RX_DESC_SIZE
Number of Rx Descriptors, should be 2 at least.
#define EMAC_TX_DESC_SIZE
Number of Tx Descriptors, should be 2 at least.
void EMAC_SetTime(uint32_t u32Sec, uint32_t u32Nsec)
Set current time stamp.
void EMAC_DisableTS(void)
Disable IEEE1588 time stamp function.
void EMAC_DisableAlarm(void)
Disable alarm function.
uint32_t EMAC_SendPktDoneTS(uint32_t *pu32Sec, uint32_t *pu32Nsec)
Clean up process after a packet is sent, and get the time stamp while packet is sent.
void EMAC_Close(void)
This function stop all receive and transmit activity and disable MAC interface.
void EMAC_RecvPktDone(void)
Clean up process after a packet is received.
void EMAC_EnableCamEntry(uint32_t u32Entry, uint8_t *pu8MacAddr)
Fill a CAM entry for MAC address comparison.
void EMAC_DisableCamEntry(uint32_t u32Entry)
Disable a specified CAM entry.
uint32_t EMAC_SendPktDone(void)
Clean up process after packet(s) are sent.
void EMAC_SetMacAddr(uint8_t *pu8MacAddr)
Set the device MAC address.
uint32_t EMAC_RecvPktTS(uint8_t *pu8Data, uint32_t *pu32Size, uint32_t *pu32Sec, uint32_t *pu32Nsec)
Receive an Ethernet packet and the time stamp while it's received.
int32_t EMAC_Open(uint8_t *pu8MacAddr)
Initialize EMAC interface, including descriptors, MAC address, and PHY.
void EMAC_GetTime(uint32_t *pu32Sec, uint32_t *pu32Nsec)
Get current time stamp.
uint32_t EMAC_RecvPkt(uint8_t *pu8Data, uint32_t *pu32Size)
Receive an Ethernet packet.
uint32_t EMAC_SendPkt(uint8_t *pu8Data, uint32_t u32Size)
Send an Ethernet packet.
void EMAC_UpdateTime(uint32_t u32Neg, uint32_t u32Sec, uint32_t u32Nsec)
Add a offset to current time.
void EMAC_EnableAlarm(uint32_t u32Sec, uint32_t u32Nsec)
Enable alarm function and set alarm time.
void EMAC_EnableTS(uint32_t u32Sec, uint32_t u32Nsec)
Enable IEEE1588 time stamp function and set current time.
#define BIT31
Bit 31 mask of an 32 bit integer.