31 #define PHY_CNTL_REG 0x00UL 32 #define PHY_STATUS_REG 0x01UL 33 #define PHY_ID1_REG 0x02UL 34 #define PHY_ID2_REG 0x03UL 35 #define PHY_ANA_REG 0x04UL 36 #define PHY_ANLPA_REG 0x05UL 37 #define PHY_ANE_REG 0x06UL 40 #define PHY_CNTL_RESET_PHY (1UL << 15UL) 41 #define PHY_CNTL_DR_100MB (1UL << 13UL) 42 #define PHY_CNTL_ENABLE_AN (1UL << 12UL) 43 #define PHY_CNTL_POWER_DOWN (1UL << 11UL) 44 #define PHY_CNTL_RESTART_AN (1UL << 9UL) 45 #define PHY_CNTL_FULLDUPLEX (1UL << 8UL) 48 #define PHY_STATUS_AN_COMPLETE (1UL << 5UL) 49 #define PHY_STATUS_LINK_VALID (1UL << 2UL) 52 #define PHY_ANA_DR100_TX_FULL (1UL << 8UL) 53 #define PHY_ANA_DR100_TX_HALF (1UL << 7UL) 54 #define PHY_ANA_DR10_TX_FULL (1UL << 6UL) 55 #define PHY_ANA_DR10_TX_HALF (1UL << 5UL) 56 #define PHY_ANA_IEEE_802_3_CSMA_CD (1UL << 0UL) 59 #define PHY_ANLPA_DR100_TX_FULL (1UL << 8UL) 60 #define PHY_ANLPA_DR100_TX_HALF (1UL << 7UL) 61 #define PHY_ANLPA_DR10_TX_FULL (1UL << 6UL) 62 #define PHY_ANLPA_DR10_TX_HALF (1UL << 5UL) 65 #define EMAC_DESC_OWN_EMAC 0x80000000UL 66 #define EMAC_DESC_OWN_CPU 0x00000000UL 69 #define EMAC_RXFD_RTSAS 0x0080UL 70 #define EMAC_RXFD_RP 0x0040UL 71 #define EMAC_RXFD_ALIE 0x0020UL 72 #define EMAC_RXFD_RXGD 0x0010UL 73 #define EMAC_RXFD_PTLE 0x0008UL 74 #define EMAC_RXFD_CRCE 0x0002UL 75 #define EMAC_RXFD_RXINTR 0x0001UL 78 #define EMAC_TXFD_TTSEN 0x08UL 79 #define EMAC_TXFD_INTEN 0x04UL 80 #define EMAC_TXFD_CRCAPP 0x02UL 81 #define EMAC_TXFD_PADEN 0x01UL 84 #define EMAC_TXFD_TXINTR 0x0001UL 85 #define EMAC_TXFD_DEF 0x0002UL 86 #define EMAC_TXFD_TXCP 0x0008UL 87 #define EMAC_TXFD_EXDEF 0x0010UL 88 #define EMAC_TXFD_NCS 0x0020UL 89 #define EMAC_TXFD_TXABT 0x0040UL 90 #define EMAC_TXFD_LC 0x0080UL 91 #define EMAC_TXFD_TXHA 0x0100UL 92 #define EMAC_TXFD_PAU 0x0200UL 93 #define EMAC_TXFD_SQE 0x0400UL 94 #define EMAC_TXFD_TTSAS 0x0800UL 128 static uint32_t u32CurrentTxDesc, u32NextTxDesc, u32CurrentRxDesc;
129 static uint32_t s_u32EnableTs = 0UL;
131 static void EMAC_MdioWrite(uint32_t u32Reg, uint32_t u32Addr, uint32_t u32Data);
132 static uint32_t EMAC_MdioRead(uint32_t u32Reg, uint32_t u32Addr);
133 static void EMAC_TxDescInit(
void);
134 static void EMAC_RxDescInit(
void);
135 static uint32_t EMAC_Subsec2Nsec(uint32_t subsec);
136 static uint32_t EMAC_Nsec2Subsec(uint32_t nsec);
150 static void EMAC_MdioWrite(uint32_t u32Reg, uint32_t u32Addr, uint32_t u32Data)
153 EMAC->MIIMDAT = u32Data ;
171 static uint32_t EMAC_MdioRead(uint32_t u32Reg, uint32_t u32Addr)
183 return EMAC->MIIMDAT;
197 EMAC_MdioWrite(PHY_CNTL_REG,
EMAC_PHY_ADDR, PHY_CNTL_RESET_PHY);
204 if ((reg & PHY_CNTL_RESET_PHY) == 0UL)
210 while (!(EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID))
223 EMAC_MdioWrite(PHY_ANA_REG,
EMAC_PHY_ADDR, PHY_ANA_DR100_TX_FULL |
224 PHY_ANA_DR100_TX_HALF |
225 PHY_ANA_DR10_TX_FULL |
226 PHY_ANA_DR10_TX_HALF |
227 PHY_ANA_IEEE_802_3_CSMA_CD);
232 while (!(EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_AN_COMPLETE))
238 while (!(EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID))
246 if (reg & PHY_ANLPA_DR100_TX_FULL)
251 else if (reg & PHY_ANLPA_DR100_TX_HALF)
256 else if (reg & PHY_ANLPA_DR10_TX_FULL)
274 static void EMAC_TxDescInit(
void)
279 EMAC->TXDSA = (uint32_t)&tx_desc[0];
280 u32NextTxDesc = u32CurrentTxDesc = (uint32_t)&tx_desc[0];
287 tx_desc[i].u32Status1 = EMAC_TXFD_PADEN | EMAC_TXFD_CRCAPP | EMAC_TXFD_INTEN;
291 tx_desc[i].u32Status1 = EMAC_TXFD_PADEN | EMAC_TXFD_CRCAPP | EMAC_TXFD_INTEN | EMAC_TXFD_TTSEN;
294 tx_desc[i].u32Data = (uint32_t)((uint32_t)&tx_buf[i]);
295 tx_desc[i].u32Backup1 = tx_desc[i].u32Data;
296 tx_desc[i].u32Status2 = 0UL;
298 tx_desc[i].u32Backup2 = tx_desc[i].u32Next;
310 static void EMAC_RxDescInit(
void)
316 EMAC->RXDSA = (uint32_t)&rx_desc[0];
317 u32CurrentRxDesc = (uint32_t)&rx_desc[0];
321 rx_desc[i].u32Status1 = EMAC_DESC_OWN_EMAC;
322 rx_desc[i].u32Data = (uint32_t)((uint32_t)&rx_buf[i]);
323 rx_desc[i].u32Backup1 = rx_desc[i].u32Data;
324 rx_desc[i].u32Status2 = 0UL;
326 rx_desc[i].u32Backup2 = rx_desc[i].u32Next;
336 static uint32_t EMAC_Subsec2Nsec(uint32_t subsec)
340 i = 1000000000ull * (uint64_t)subsec;
342 return ((uint32_t)i);
350 static uint32_t EMAC_Nsec2Subsec(uint32_t nsec)
354 i = (1ull << 31) * nsec;
356 return ((uint32_t)i);
446 uint32_t u32Lsw, u32Msw;
448 u32Lsw = (uint32_t)(((uint32_t)pu8MacAddr[4] << 24) |
449 ((uint32_t)pu8MacAddr[5] << 16));
450 u32Msw = (uint32_t)(((uint32_t)pu8MacAddr[0] << 24) |
451 ((uint32_t)pu8MacAddr[1] << 16) |
452 ((uint32_t)pu8MacAddr[2] << 8) |
453 (uint32_t)pu8MacAddr[3]);
455 reg = (uint32_t)&
EMAC->CAM0M + u32Entry * 2UL * 4UL;
456 *(uint32_t
volatile *)reg = u32Msw;
457 reg = (uint32_t)&
EMAC->CAM0L + u32Entry * 2UL * 4UL;
458 *(uint32_t
volatile *)reg = u32Lsw;
460 EMAC->CAMEN |= (1UL << u32Entry);
470 EMAC->CAMEN &= ~(1UL << u32Entry);
485 EMAC_DESCRIPTOR_T *desc;
486 uint32_t status, reg;
487 uint32_t u32Count = 0UL;
491 EMAC->INTSTS = reg & 0xFFFFUL;
502 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
505 if ((desc->u32Status1 & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
508 status = desc->u32Status1 >> 16;
511 if (status & EMAC_RXFD_RXGD)
514 *pu32Size = desc->u32Status1 & 0xFFFFUL;
515 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
521 if (status & EMAC_RXFD_RP) {}
523 if (status & EMAC_RXFD_ALIE) {}
525 if (status & EMAC_RXFD_PTLE) {}
527 if (status & EMAC_RXFD_CRCE) {}
548 uint32_t
EMAC_RecvPktTS(uint8_t *pu8Data, uint32_t *pu32Size, uint32_t *pu32Sec, uint32_t *pu32Nsec)
550 EMAC_DESCRIPTOR_T *desc;
551 uint32_t status, reg;
552 uint32_t u32Count = 0UL;
556 EMAC->INTSTS = reg & 0xFFFFUL;
567 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
570 if (
EMAC->CRXDSA != (uint32_t)desc)
572 if ((desc->u32Status1 | EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
575 status = desc->u32Status1 >> 16;
578 if (status & EMAC_RXFD_RXGD)
581 *pu32Size = desc->u32Status1 & 0xFFFFUL;
582 memcpy(pu8Data, (uint8_t *)desc->u32Backup1, *pu32Size);
584 *pu32Sec = desc->u32Next;
585 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data);
592 if (status & EMAC_RXFD_RP) {}
594 if (status & EMAC_RXFD_ALIE) {}
596 if (status & EMAC_RXFD_PTLE) {}
598 if (status & EMAC_RXFD_CRCE) {}
616 EMAC_DESCRIPTOR_T *desc;
618 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
621 desc->u32Data = desc->u32Backup1;
622 desc->u32Next = desc->u32Backup2;
625 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
628 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
631 u32CurrentRxDesc = (uint32_t)desc;
648 EMAC_DESCRIPTOR_T *desc;
652 desc = (EMAC_DESCRIPTOR_T *)u32NextTxDesc;
654 status = desc->u32Status1;
657 if ((status & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
659 memcpy((uint8_t *)desc->u32Data, pu8Data, u32Size);
662 desc->u32Status2 = u32Size;
665 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
668 u32NextTxDesc = (uint32_t)(desc->u32Next);
688 EMAC_DESCRIPTOR_T *desc;
689 uint32_t status, reg;
690 uint32_t last_tx_desc;
691 uint32_t u32Count = 0UL;
706 last_tx_desc =
EMAC->CTXDSA ;
708 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
713 if (desc->u32Status1 & EMAC_DESC_OWN_EMAC)
719 status = desc->u32Status2 >> 16UL;
721 if (status & EMAC_TXFD_TXCP)
728 if (status & EMAC_TXFD_TXABT) {}
730 if (status & EMAC_TXFD_DEF) {}
732 if (status & EMAC_TXFD_PAU) {}
734 if (status & EMAC_TXFD_EXDEF) {}
736 if (status & EMAC_TXFD_NCS) {}
738 if (status & EMAC_TXFD_SQE) {}
740 if (status & EMAC_TXFD_LC) {}
742 if (status & EMAC_TXFD_TXHA) {}
746 desc->u32Data = desc->u32Backup1;
747 desc->u32Next = desc->u32Backup2;
749 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
750 }
while (last_tx_desc != (uint32_t)desc);
753 u32CurrentTxDesc = (uint32_t)desc;
772 EMAC_DESCRIPTOR_T *desc;
773 uint32_t status, reg;
774 uint32_t u32Count = 0UL;
790 desc = (EMAC_DESCRIPTOR_T *) u32CurrentTxDesc;
793 if ((desc->u32Status1 & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
796 status = desc->u32Status2 >> 16UL;
798 if (status & EMAC_TXFD_TXCP)
801 *pu32Sec = desc->u32Next;
802 *pu32Nsec = EMAC_Subsec2Nsec(desc->u32Data);
807 if (status & EMAC_TXFD_TXABT) {}
809 if (status & EMAC_TXFD_DEF) {}
811 if (status & EMAC_TXFD_PAU) {}
813 if (status & EMAC_TXFD_EXDEF) {}
815 if (status & EMAC_TXFD_NCS) {}
817 if (status & EMAC_TXFD_SQE) {}
819 if (status & EMAC_TXFD_LC) {}
821 if (status & EMAC_TXFD_TXHA) {}
825 desc->u32Data = desc->u32Backup1;
826 desc->u32Next = desc->u32Backup2;
828 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
831 u32CurrentTxDesc = (uint32_t)desc;
849 EMAC->UPDSEC = u32Sec;
850 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
860 f = (100.0 * 2147483648.0) / (1000000000.0) + 0.5;
861 EMAC->TSINC = (reg = (uint32_t)f);
862 f = (double)9223372036854775808.0 / ((
double)(
CLK_GetHCLKFreq()) * (
double)reg);
863 EMAC->TSADDEND = (uint32_t)f;
886 *pu32Nsec = EMAC_Subsec2Nsec(
EMAC->TSSUBSEC);
887 *pu32Sec =
EMAC->TSSEC;
900 EMAC->UPDSEC = u32Sec;
901 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
915 EMAC->ALMSEC = u32Sec;
916 EMAC->ALMSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
942 EMAC->UPDSEC = u32Sec;
943 EMAC->UPDSUBSEC = EMAC_Nsec2Subsec(u32Nsec);
970 if (EMAC_MdioRead(PHY_STATUS_REG,
EMAC_PHY_ADDR) & PHY_STATUS_LINK_VALID)
975 if (reg & PHY_ANLPA_DR100_TX_FULL)
981 else if (reg & PHY_ANLPA_DR100_TX_HALF)
987 else if (reg & PHY_ANLPA_DR10_TX_FULL)
1013 uint32_t *EMAC_CAMxM;
1014 uint32_t *EMAC_CAMxL;
1020 EMAC_CAMxM = (uint32_t *)((uint32_t)&
EMAC->CAM0M + (index * 8));
1021 EMAC_CAMxL = (uint32_t *)((uint32_t)&
EMAC->CAM0L + (index * 8));
1023 mac[0] = (*EMAC_CAMxM >> 24) & 0xff;
1024 mac[1] = (*EMAC_CAMxM >> 16) & 0xff;
1025 mac[2] = (*EMAC_CAMxM >> 8) & 0xff;
1026 mac[3] = (*EMAC_CAMxM) & 0xff;
1027 mac[4] = (*EMAC_CAMxL >> 24) & 0xff;
1028 mac[5] = (*EMAC_CAMxL >> 16) & 0xff;
1030 if (memcmp(mac, pu8MacAddr,
sizeof(mac)) == 0)
1032 goto exit_emac_fillcamentry;
1035 if (*EMAC_CAMxM == 0 && *EMAC_CAMxL == 0)
1044 goto exit_emac_fillcamentry;
1049 exit_emac_fillcamentry:
1064 EMAC_DESCRIPTOR_T *desc;
1068 desc = (EMAC_DESCRIPTOR_T *)u32NextTxDesc;
1070 status = desc->u32Status1;
1073 if ((status & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
1076 desc->u32Status2 = u32Size;
1079 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
1082 u32NextTxDesc = (uint32_t)(desc->u32Next);
1100 EMAC_DESCRIPTOR_T *desc = (EMAC_DESCRIPTOR_T *)u32NextTxDesc;
1102 if (desc->u32Status1 & EMAC_DESC_OWN_EMAC)
1108 return (uint8_t *)desc->u32Data;
1120 EMAC_DESCRIPTOR_T *desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
1122 if ((desc->u32Status1 & EMAC_DESC_OWN_EMAC) != EMAC_DESC_OWN_EMAC)
1124 uint32_t status = desc->u32Status1 >> 16;
1127 if ((status & EMAC_RXFD_RXGD) && !(status & EMAC_RXFD_CRCE))
1129 return desc->u32Status1 & 0xFFFFUL;
1152 EMAC_DESCRIPTOR_T *desc;
1154 desc = (EMAC_DESCRIPTOR_T *)u32CurrentRxDesc;
1157 desc->u32Data = desc->u32Backup1;
1158 desc->u32Next = desc->u32Backup2;
1161 desc->u32Status1 |= EMAC_DESC_OWN_EMAC;
1164 desc = (EMAC_DESCRIPTOR_T *)desc->u32Next;
1167 u32CurrentRxDesc = (uint32_t)desc;
#define EMAC_INTEN_TSALMIEN_Msk
int32_t EMAC_FillCamEntry(uint8_t pu8MacAddr[])
Fill a MAC address to list and enable.
void EMAC_SetTime(uint32_t u32Sec, uint32_t u32Nsec)
Set current time stamp.
#define BIT31
Bit 31 mask of an 32 bit integer.
#define EMAC_MIIMCTL_WRITE_Msk
#define EMAC_TX_DESC_SIZE
void EMAC_SetMacAddr(uint8_t *pu8MacAddr)
Set the device MAC address.
#define EMAC_MIIMCTL_BUSY_Msk
void EMAC_GetTime(uint32_t *pu32Sec, uint32_t *pu32Nsec)
Get current time stamp.
#define EMAC_CAMCTL_AMP_Msk
#define EMAC_INTEN_RXBEIEN_Msk
void EMAC_EnableAlarm(uint32_t u32Sec, uint32_t u32Nsec)
Enable alarm function and set alarm time.
void EMAC_DisableTS(void)
Disable IEEE1588 time stamp function.
#define EMAC_CTL_STRIPCRC_Msk
NuMicro peripheral access layer header file.
#define EMAC_CTL_OPMODE_Msk
#define EMAC_CAMCTL_ABP_Msk
#define EMAC_TSCTL_TSEN_Msk
#define EMAC_INTEN_TXBEIEN_Msk
void EMAC_DisableAlarm(void)
Disable alarm function.
#define EMAC_INTEN_TXIEN_Msk
void EMAC_EnableTS(uint32_t u32Sec, uint32_t u32Nsec)
Enable IEEE1588 time stamp function and set current time.
void EMAC_EnableCamEntry(uint32_t u32Entry, uint8_t pu8MacAddr[])
Fill a CAM entry for MAC address comparison.
#define EMAC_RX_DESC_SIZE
uint32_t EMAC_CheckLinkStatus(void)
Check Ethernet link status.
#define EMAC_INTEN_RXGDIEN_Msk
#define EMAC_TSCTL_TSMODE_Msk
#define EMAC_INTEN_TXCPIEN_Msk
uint32_t EMAC_RecvPkt(uint8_t *pu8Data, uint32_t *pu32Size)
Receive an Ethernet packet.
#define EMAC_INTEN_RXIEN_Msk
#define EMAC_TRIGGER_TX()
Trigger EMAC Tx function.
uint32_t EMAC_SendPktDone(void)
Clean up process after packet(s) are sent.
void EMAC_Close(void)
This function stop all receive and transmit activity and disable MAC interface.
void EMAC_DisableCamEntry(uint32_t u32Entry)
Disable a specified CAM entry.
void EMAC_Open(uint8_t *pu8MacAddr)
Initialize EMAC interface, including descriptors, MAC address, and PHY.
void EMAC_RecvPktDone(void)
Clean up process after a packet is received.
#define EMAC_TSCTL_TSUPDATE_Msk
#define EMAC_INTSTS_TXBEIF_Msk
void EMAC_RecvPktDoneWoRxTrigger(void)
Clean up process after a packet is received.
void EMAC_UpdateTime(uint32_t u32Neg, uint32_t u32Sec, uint32_t u32Nsec)
Add a offset to current time.
uint32_t EMAC_SendPktWoCopy(uint32_t u32Size)
Send an Ethernet packet.
#define EMAC_MAX_PKT_SIZE
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.
#define EMAC_CTL_RMIIEN_Msk
#define EMAC_INTEN_RDUIEN_Msk
#define EMAC_CTL_FUDUP_Msk
uint32_t CLK_GetHCLKFreq(void)
Get HCLK frequency.
#define EMAC_INTSTS_TSALMIF_Msk
uint32_t EMAC_GetAvailRXBufSize(void)
Get data length of avaiable RX buffer.
#define EMAC_INTSTS_RXBEIF_Msk
#define EMAC_MIIMCTL_PHYADDR_Pos
#define NULL
NULL pointer.
#define EMAC_TRIGGER_RX()
Trigger EMAC Rx function.
#define EMAC_INTEN_WOLIEN_Msk
uint32_t EMAC_SendPkt(uint8_t *pu8Data, uint32_t u32Size)
Send an Ethernet packet.
#define EMAC_CAMCTL_CMPEN_Msk
#define EMAC_TSCTL_TSIEN_Msk
#define EMAC_MIIMCTL_MDCON_Msk
#define EMAC_TSCTL_TSALMEN_Msk
uint8_t * EMAC_ClaimFreeTXBuf(void)
Get avaiable TX buffer 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.