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);
558 if (status & EMAC_RXFD_ALIE);
559 if (status & EMAC_RXFD_PTLE);
560 if (status & EMAC_RXFD_CRCE);
581uint32_t
EMAC_RecvPktTS(uint8_t *pu8Data, uint32_t *pu32Size, uint32_t *pu32Sec, uint32_t *pu32Nsec)
583 EMAC_DESCRIPTOR_T *desc;
584 uint32_t status, reg;
585 uint32_t u32Count = 0;
589 EMAC->INTSTS = reg & 0xFFFF;
594 printf(
"RX bus error\n");
601 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
604 if(
EMAC->CRXDSA == (uint32_t)desc)
606 if ((desc->u32Status1 | EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
609 status = desc->u32Status1 >> 16;
612 if(status & EMAC_RXFD_RXGD)
615 *pu32Size = desc->u32Status1 & 0xffff;
616 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
618 *pu32Sec = desc->u32Next;
619 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data);
626 if (status & EMAC_RXFD_RP);
627 if (status & EMAC_RXFD_ALIE);
628 if (status & EMAC_RXFD_PTLE);
629 if (status & EMAC_RXFD_CRCE);
645 EMAC_DESCRIPTOR_T *desc;
647 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
650 desc->u32Data = desc->u32Backup1;
651 desc->u32Next = desc->u32Backup2;
654 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
657 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
660 u32CurrentRxDesc = (uint32_t)desc;
678 EMAC_DESCRIPTOR_T *desc;
682 desc = (EMAC_DESCRIPTOR_T *)u32NextTxDesc;
684 status = desc->u32Status1;
687 if((status & EMAC_DESC_OWN_EMAC))
690 memcpy((uint8_t *)desc->u32Data, pu8Data, u32Size);
693 desc->u32Status2 = u32Size;
696 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
699 u32NextTxDesc = (uint32_t)(desc->u32Next);
719 EMAC_DESCRIPTOR_T *desc;
720 uint32_t status, reg;
721 uint32_t last_tx_desc;
722 uint32_t u32Count = 0;
726 EMAC->INTSTS = reg & (0xFFFF0000 & ~EMAC_INTSTS_TSALMIF_Msk);
732 printf(
"TX bus error\n");
738 last_tx_desc =
EMAC->CTXDSA ;
740 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
744 if(desc->u32Status1 & EMAC_DESC_OWN_EMAC)
747 status = desc->u32Status2 >> 16;
748 if (status & EMAC_TXFD_TXCP)
755 if (status & EMAC_TXFD_TXABT);
756 if (status & EMAC_TXFD_DEF);
757 if (status & EMAC_TXFD_PAU);
758 if (status & EMAC_TXFD_EXDEF);
759 if (status & EMAC_TXFD_NCS);
760 if (status & EMAC_TXFD_SQE);
761 if (status & EMAC_TXFD_LC);
762 if (status & EMAC_TXFD_TXHA);
766 desc->u32Data = desc->u32Backup1;
767 desc->u32Next = desc->u32Backup2;
769 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
771 while (last_tx_desc != (uint32_t)desc);
773 u32CurrentTxDesc = (uint32_t)desc;
792 EMAC_DESCRIPTOR_T *desc;
793 uint32_t status, reg;
794 uint32_t u32Count = 0;
798 EMAC->INTSTS = reg & (0xFFFF0000 & ~EMAC_INTSTS_TSALMIF_Msk);
804 printf(
"TX bus error\n");
811 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
814 if(desc->u32Status1 & EMAC_DESC_OWN_EMAC)
817 status = desc->u32Status2 >> 16;
818 if (status & EMAC_TXFD_TXCP)
821 *pu32Sec = desc->u32Next;
822 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data);
827 if (status & EMAC_TXFD_TXABT);
828 if (status & EMAC_TXFD_DEF);
829 if (status & EMAC_TXFD_PAU);
830 if (status & EMAC_TXFD_EXDEF);
831 if (status & EMAC_TXFD_NCS);
832 if (status & EMAC_TXFD_SQE);
833 if (status & EMAC_TXFD_LC);
834 if (status & EMAC_TXFD_TXHA);
838 desc->u32Data = desc->u32Backup1;
839 desc->u32Next = desc->u32Backup2;
841 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
844 u32CurrentTxDesc = (uint32_t)desc;
862 EMAC->UPDSEC = u32Sec;
863 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
873 f = (100.0 * 2147483648.0) / (1000000000.0) + 0.5;
874 EMAC->TSINC = (reg = (uint32_t)f);
875 f = (double)9223372036854775808.0 / ((
double)(
CLK_GetHCLKFreq()) * (
double)reg);
876 EMAC->TSADDEND = (uint32_t)f;
899 *pu32Nsec = EMAC_Subsec2Nsec(
EMAC->TSSUBSEC);
900 *pu32Sec =
EMAC->TSSEC;
913 EMAC->UPDSEC = u32Sec;
914 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
928 EMAC->ALMSEC = u32Sec;
929 EMAC->ALMSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
942 EMAC->TSCTL &= ~EMAC_TSCTL_TSALMEN_Msk;
955 EMAC->UPDSEC = u32Sec;
956 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.