Files
RCU_C1P_Module/NetLib/eth_driver.c
caocong d2d8800788 feat:新建项目文件
BLV主机C1P模块
2025-12-06 13:49:01 +08:00

699 lines
23 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/********************************** (C) COPYRIGHT *******************************
* File Name : eth_driver.c
* Author : WCH
* Version : V1.0.0
* Date : 2024/05/05
* Description : eth program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
#include <string.h>
#include "eth_driver.h"
#include "net_config.h"
__attribute__((__aligned__(4))) ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB]; /* MAC receive descriptor, 4-byte aligned*/
__attribute__((__aligned__(4))) ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB]; /* MAC send descriptor, 4-byte aligned */
__attribute__((__aligned__(4))) uint8_t MACRxBuf[ETH_RXBUFNB*ETH_RX_BUF_SZE]; /* MAC receive buffer, 4-byte aligned */
__attribute__((__aligned__(4))) uint8_t MACTxBuf[ETH_TXBUFNB*ETH_TX_BUF_SZE]; /* MAC send buffer, 4-byte aligned */
__attribute__((__aligned__(4))) SOCK_INF SocketInf[WCHNET_MAX_SOCKET_NUM]; /* Socket information table, 4-byte alignment */
__attribute__((__aligned__(4))) uint8_t RemoteIp[4]; /* DNS information table, 4-byte alignment */
const uint16_t MemNum[8] = {WCHNET_NUM_IPRAW,
WCHNET_NUM_UDP,
WCHNET_NUM_TCP,
WCHNET_NUM_TCP_LISTEN,
WCHNET_NUM_TCP_SEG,
WCHNET_NUM_IP_REASSDATA,
WCHNET_NUM_PBUF,
WCHNET_NUM_POOL_BUF
};
const uint16_t MemSize[8] = {WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_IPRAW_PCB),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_UDP_PCB),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_PCB),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_PCB_LISTEN),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_SEG),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_IP_REASSDATA),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_PBUF),
WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_PBUF) + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_POOL_BUF)
};
__attribute__((__aligned__(4)))uint8_t Memp_Memory[WCHNET_MEMP_SIZE];
__attribute__((__aligned__(4)))uint8_t Mem_Heap_Memory[WCHNET_RAM_HEAP_SIZE];
__attribute__((__aligned__(4)))uint8_t Mem_ArpTable[WCHNET_RAM_ARP_TABLE_SIZE];
uint16_t gPHYAddress;
volatile uint32_t LocalTime;
volatile uint8_t PhyWaitNegotiationSuc = 0;
ETH_DMADESCTypeDef *pDMARxSet;
ETH_DMADESCTypeDef *pDMATxSet;
volatile uint8_t LinkSta = 0; //0:Link down 1:Link up
uint8_t LinkVaildFlag = 0; //0:invalid 1:valid
uint8_t AccelerateLinkFlag = 0; //0:invalid 1:valid
uint8_t LinkProcessingStep = 0;
uint32_t LinkProcessingTime = 0;
uint32_t TaskExecutionTime = 0;
void ETH_LinkDownCfg(void);
/*********************************************************************
* @fn WCHNET_TimeIsr
*
* @brief
*
* @return none.
*/
void WCHNET_TimeIsr( uint16_t timperiod )
{
LocalTime += timperiod;
}
/*********************************************************************
* @fn WCHNET_QueryPhySta
*
* @brief Query external PHY status
*
* @return none.
*/
void WCHNET_QueryPhySta(void)
{
if(PhyWaitNegotiationSuc)
{
ETH_PHYLink();
}
}
/*********************************************************************
* @fn WCHNET_CheckPHYPN
*
* @brief check PHY PN polarity
*
* @return none.
*/
void WCHNET_CheckPHYPN(uint16_t time)
{
uint16_t phy_stat;
//check PHY PN
if((LinkProcessingStep == 0)||(LocalTime >= LinkProcessingTime))
{
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE0 );
phy_stat = ETH_ReadPHYRegister( gPHYAddress, PHY_STATUS1);
if(phy_stat & (1<<4))
{
if(LinkProcessingStep == 0)
{
LinkProcessingStep = 1;
LinkProcessingTime = LocalTime + time;
}
else {
LinkProcessingStep = 0;
LinkProcessingTime = 0;
phy_stat = ETH_ReadPHYRegister( gPHYAddress, PHY_ANER);
if((time == 200) || ((phy_stat & 1) == 0))
{
phy_stat = ETH_ReadPHYRegister( gPHYAddress, PHY_CONTROL1);
phy_stat |= 1;
ETH_WritePHYRegister(gPHYAddress, PHY_CONTROL1, phy_stat );
}
}
}
else {
LinkProcessingStep = 0;
LinkProcessingTime = 0;
}
}
}
/*********************************************************************
* @fn WCHNET_AccelerateLink
*
* @brief accelerate Link processing
*
* @return none.
*/
void WCHNET_AccelerateLink(void)
{
uint16_t phy_stat;
if(AccelerateLinkFlag == 0)
{
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, 99 );
phy_stat = ETH_ReadPHYRegister( gPHYAddress, 0x19);
if((phy_stat & 0xf) == 3)
{
AccelerateLinkFlag = 1;
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE0 );
phy_stat = 0x4;
ETH_WritePHYRegister(gPHYAddress, 0x16, phy_stat );
}
}
}
/*********************************************************************
* @fn WCHNET_CheckLinkVaild
*
* @brief check whether Link is valid
*
* @return none.
*/
void WCHNET_CheckLinkVaild(void)
{
uint16_t phy_stat, phy_bcr;
if(LinkVaildFlag == 0)
{
phy_bcr = ETH_ReadPHYRegister( PHY_ADDRESS, PHY_BCR);
if((phy_bcr & (1<<13)) == 0) //Do nothing if Link mode is 10M.
{
LinkVaildFlag = 1;
LinkProcessingTime = 0;
return;
}
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, 99 );
phy_stat = ETH_ReadPHYRegister( gPHYAddress, 0x1b);
if((phy_stat & (1<<2)) == 0)
{
LinkProcessingTime++;
if(LinkProcessingTime == 5)
{
LinkProcessingTime = 0;
phy_stat = ETH_ReadPHYRegister(gPHYAddress, PHY_BCR);
ETH_WritePHYRegister(gPHYAddress, PHY_BCR, PHY_Reset );
Delay_Us(100);
ETH_WritePHYRegister(gPHYAddress, PHY_BCR, phy_stat );
ETH_LinkDownCfg();
}
}
else {
LinkVaildFlag = 1;
LinkProcessingTime = 0;
}
}
}
/*********************************************************************
* @fn WCHNET_LinkProcessing
*
* @brief process Link stage task
*
* @return none.
*/
void WCHNET_LinkProcessing(void)
{
u16 phy_bcr;
if(LocalTime >= TaskExecutionTime)
{
TaskExecutionTime = LocalTime + 10; //execution cycle:10ms
if(LinkSta == 0) //Link down
{
phy_bcr = ETH_ReadPHYRegister( PHY_ADDRESS, PHY_BCR);
if(phy_bcr & PHY_AutoNegotiation) //auto-negotiation is enabled
{
WCHNET_CheckPHYPN(300); //check PHY PN
WCHNET_AccelerateLink(); //accelerate Link processing
}
else { //auto-negotiation is disabled
if((phy_bcr & (1<<13)) == 0) // 10M
{
WCHNET_CheckPHYPN(200); //check PHY PN
}
}
}
else { //Link up
WCHNET_CheckLinkVaild(); //check whether Link is valid
}
}
}
/*********************************************************************
* @fn WCHNET_MainTask
*
* @brief library main task function
*
* @param none.
*
* @return none.
*/
void WCHNET_MainTask(void)
{
WCHNET_NetInput( ); /* Ethernet data input */
WCHNET_PeriodicHandle( ); /* Protocol stack time-related task processing */
WCHNET_QueryPhySta();
WCHNET_LinkProcessing();
}
/*********************************************************************
* @fn ETH_LinkUpCfg
*
* @brief When the PHY is connected, configure the relevant functions.
*
* @param none.
*
* @return none.
*/
void ETH_LinkUpCfg(void)
{
uint16_t phy_stat;
LinkSta = 1;
AccelerateLinkFlag = 0;
LinkProcessingStep = 0;
LinkProcessingTime = 0;
PhyWaitNegotiationSuc = 0;
ETH_Start( );
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE0 );
phy_stat = 0x0;
ETH_WritePHYRegister(gPHYAddress, 0x16, phy_stat );
}
/*********************************************************************
* @fn ETH_LinkDownCfg
*
* @brief When the PHY is disconnected, configure the relevant functions.
*
* @param none.
*
* @return none.
*/
void ETH_LinkDownCfg(void)
{
LinkSta = 0;
LinkVaildFlag = 0;
LinkProcessingTime = 0;
}
/*********************************************************************
* @fn ETH_PHYLink
*
* @brief Configure MAC parameters after the PHY Link is successful.
*
* @param none.
*
* @return none.
*/
void ETH_PHYLink( void )
{
uint32_t phy_stat, phy_anlpar, phy_bcr;
phy_stat = ETH_ReadPHYRegister( PHY_ADDRESS, PHY_BSR );
phy_anlpar = ETH_ReadPHYRegister( PHY_ADDRESS, PHY_ANLPAR);
phy_bcr = ETH_ReadPHYRegister( gPHYAddress, PHY_BCR);
WCHNET_PhyStatus( phy_stat );
if(phy_stat & PHY_Linked_Status) //LinkUp
{
if(phy_bcr & PHY_AutoNegotiation)
{
if(phy_anlpar == 0)
{
ETH_LinkUpCfg();
}
else {
if(phy_stat & PHY_AutoNego_Complete)
{
ETH_LinkUpCfg();
}
else{
PhyWaitNegotiationSuc = 1;
}
}
}
else {
ETH_LinkUpCfg();
}
}
else { //LinkDown
/*Link down*/
ETH_LinkDownCfg();
}
}
/*********************************************************************
* @fn ETH_CheckPhyInterruptStatus
*
* @brief MAC check PHY interrupt status.
*
* @param none.
*
* @return none.
*/
void ETH_CheckPhyInterruptStatus( void )
{
uint16_t phyIntStat;
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE17 );
phyIntStat = ETH_ReadPHYRegister( gPHYAddress, PHY_WOL_STATUS);
if(phyIntStat & WOL_DONE_INT)
{
/* Wol done */
}
else /* Link status change*/
{
ETH_PHYLink();
}
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE0 );
phyIntStat = ETH_ReadPHYRegister( gPHYAddress, 0x1E); /* Clear the Interrupt status */
}
/*********************************************************************
* @fn PHY_InterruptInit
*
* @brief Configure PHY interrupt function
*
* @param none.
*
* @return none.
*/
void PHY_InterruptInit(void)
{
uint16_t RegValue;
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE7 );
/* Configure interrupt function */
RegValue = ETH_ReadPHYRegister(gPHYAddress, PHY_INTERRUPT_MASK);
RegValue |= 0x01 << 13;
ETH_WritePHYRegister(gPHYAddress, PHY_INTERRUPT_MASK, RegValue );
/* Clear the Interrupt status */
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE0 );
ETH_ReadPHYRegister( gPHYAddress, PHY_INTERRUPT_IND);
}
/*********************************************************************
* @fn PHY_LEDCfg
*
* @brief Configure PHY LED function
*
* @param none.
*
* @return none.
*/
void PHY_LEDCfg(void)
{
uint16_t RegValue;
ETH_WritePHYRegister(gPHYAddress, PHY_PAG_SEL, PHY_REG_PAGE7 );
//turn on LED--PHY
RegValue = ETH_ReadPHYRegister(gPHYAddress, PHY_INTERRUPT_MASK);
RegValue |= 1<<9;
ETH_WritePHYRegister(gPHYAddress, PHY_INTERRUPT_MASK, RegValue );
//<2F><>link_led<65><64>ӳ<EFBFBD>䵽PB17
R32_AFIO_PCFR1 |= 1<<30;
//<2F><>act_led<65><64>ӳ<EFBFBD>䵽PB6
R32_AFIO_PCFR2 |= 1<<1;
//turn on LED--MCU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CH564RM V1.1<EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>ж<EFBFBD>Ӧ<EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʳ<EFBFBD><EFBFBD><EFBFBD>
ETH_LED_CTRL = 0x05;
}
/*********************************************************************
* @fn ETH_RegInit
*
* @brief ETH register initialization.
*
* @param ETH_InitStruct:initialization struct.
* PHYAddress:PHY address.
*
* @return Initialization status.
*/
uint32_t ETH_RegInit( ETH_InitTypeDef* ETH_InitStruct, uint16_t PHYAddress )
{
uint32_t tmpreg = 0;
/*---------------------- Physical layer configuration -------------------*/
/* Set the SMI interface clock, set as the main frequency divided by 42 */
tmpreg = ETH->MACMIIAR;
tmpreg &= MACMIIAR_CR_MASK;
tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
ETH->MACMIIAR = (uint32_t)tmpreg;
/*------------------------ MAC register configuration ----------------------- --------------------*/
tmpreg = ETH->MACCR;
tmpreg &= MACCR_CLEAR_MASK;
tmpreg |= (uint32_t)(ETH_InitStruct->ETH_Watchdog |
ETH_InitStruct->ETH_Jabber |
ETH_InitStruct->ETH_InterFrameGap |
ETH_InitStruct->ETH_ChecksumOffload |
ETH_InitStruct->ETH_AutomaticPadCRCStrip |
ETH_InitStruct->ETH_DeferralCheck |
(1 << 20));
/* Write MAC Control Register */
ETH->MACCR = (uint32_t)tmpreg;
ETH->MACFFR = (uint32_t)(ETH_InitStruct->ETH_ReceiveAll |
ETH_InitStruct->ETH_SourceAddrFilter |
ETH_InitStruct->ETH_PassControlFrames |
ETH_InitStruct->ETH_BroadcastFramesReception |
ETH_InitStruct->ETH_DestinationAddrFilter |
ETH_InitStruct->ETH_PromiscuousMode |
ETH_InitStruct->ETH_MulticastFramesFilter |
ETH_InitStruct->ETH_UnicastFramesFilter);
/*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
/* Write to ETHERNET MACHTHR */
ETH->MACHTHR = (uint32_t)ETH_InitStruct->ETH_HashTableHigh;
/* Write to ETHERNET MACHTLR */
ETH->MACHTLR = (uint32_t)ETH_InitStruct->ETH_HashTableLow;
/*----------------------- ETHERNET MACFCR Configuration --------------------*/
/* Get the ETHERNET MACFCR value */
tmpreg = ETH->MACFCR;
/* Clear xx bits */
tmpreg &= MACFCR_CLEAR_MASK;
tmpreg |= (uint32_t)((ETH_InitStruct->ETH_PauseTime << 16) |
ETH_InitStruct->ETH_UnicastPauseFrameDetect |
ETH_InitStruct->ETH_ReceiveFlowControl |
ETH_InitStruct->ETH_TransmitFlowControl);
ETH->MACFCR = (uint32_t)tmpreg;
ETH->MACVLANTR = (uint32_t)(ETH_InitStruct->ETH_VLANTagComparison |
ETH_InitStruct->ETH_VLANTagIdentifier);
tmpreg = ETH->DMAOMR;
tmpreg &= DMAOMR_CLEAR_MASK;
tmpreg |= (uint32_t)(ETH_InitStruct->ETH_DropTCPIPChecksumErrorFrame |
ETH_InitStruct->ETH_FlushReceivedFrame |
ETH_InitStruct->ETH_TransmitStoreForward |
ETH_InitStruct->ETH_ForwardErrorFrames |
ETH_InitStruct->ETH_ForwardUndersizedGoodFrames);
ETH->DMAOMR = (uint32_t)tmpreg;
/* Reset the physical layer */
ETH_WritePHYRegister(PHYAddress, PHY_BCR, PHY_Reset);
return ETH_SUCCESS;
}
/*********************************************************************
* @fn ETH_Configuration
*
* @brief Ethernet configure.
*
* @return none
*/
void ETH_Configuration( uint8_t *macAddr )
{
ETH_InitTypeDef ETH_InitStructure;
uint16_t timeout = 10000;
/* Configure Ethernet for normal operating mode*/
ETH->PHY_CR |= 1<<31;
ETH->PHY_CR &= ~(1<<30);
gPHYAddress = PHY_ADDRESS;
/* Software reset */
ETH_SoftwareReset();
/* Wait for software reset */
do{
Delay_Us(10);
if( !--timeout ) break;
}while(ETH->DMABMR & ETH_DMABMR_SR);
/* ETHERNET Configuration */
/* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
ETH_StructInit(&ETH_InitStructure);
/* Fill ETH_InitStructure parameters */
/*------------------------ MAC -----------------------------------*/
#if HARDWARE_CHECKSUM_CONFIG
ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;
#endif
ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;
/* Filter function configuration */
ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;
ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Enable;
ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;
ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;
ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;
/*------------------------ DMA -----------------------------------*/
/* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
ETH_InitStructure.ETH_DropTCPIPChecksumErrorFrame = ETH_DropTCPIPChecksumErrorFrame_Enable;
ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Enable;
ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Enable;
ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Enable;
/* Configure Ethernet */
ETH_RegInit( &ETH_InitStructure, gPHYAddress );
/* Configure MAC address */
ETH->MACA0HR = (uint32_t)((macAddr[5]<<8) | macAddr[4]);
ETH->MACA0LR = (uint32_t)(macAddr[0] | (macAddr[1]<<8) | (macAddr[2]<<16) | (macAddr[3]<<24));
/* Mask the interrupt that Tx good frame count counter reaches half the maximum value */
ETH->MMCTIMR = ETH_MMCTIMR_TGFM;
/* Mask the interrupt that Rx good unicast frames counter reaches half the maximum value */
/* Mask the interrupt that Rx crc error counter reaches half the maximum value */
ETH->MMCRIMR = ETH_MMCRIMR_RGUFM | ETH_MMCRIMR_RFAEM | ETH_MMCRIMR_RFCEM;
PHY_InterruptInit();
ETH_DMAITConfig(ETH_DMA_IT_NIS |\
ETH_DMA_IT_R |\
ETH_DMA_IT_T |\
ETH_DMA_IT_AIS |\
ETH_DMA_IT_RBU |\
ETH_DMA_IT_PHYSR,\
ENABLE);
}
/*********************************************************************
* @fn ETH_TxPktChainMode
*
* @brief Ethernet sends data frames in chain mode.
*
* @param len Send data length
* pBuff send buffer pointer
*
* @return Send status.
*/
uint32_t ETH_TxPktChainMode(uint16_t len, uint32_t *pBuff )
{
/* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
if((DMATxDescToSet->Status & ETH_DMATxDesc_OWN) != (uint32_t)RESET)
{
/* Return ERROR: OWN bit set */
return ETH_ERROR;
}
/* Setting the Frame Length: bits[12:0] */
DMATxDescToSet->ControlBufferSize = (len & ETH_DMATxDesc_TBS1);
DMATxDescToSet->Buffer1Addr = (uint32_t)pBuff;
/* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
#if HARDWARE_CHECKSUM_CONFIG
DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS | ETH_DMATxDesc_CIC_TCPUDPICMP_Full;
#else
DMATxDescToSet->Status |= ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
#endif
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
/* Clear TBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_TBUS;
/* Resume DMA transmission*/
ETH->DMATPDR = 0;
/* Update the ETHERNET DMA global Tx descriptor with next Tx descriptor */
/* Chained Mode */
/* Selects the next DMA Tx descriptor list for next buffer to send */
DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr);
/* Return SUCCESS */
return ETH_SUCCESS;
}
/*********************************************************************
* @fn WCHNET_ETHIsr
*
* @brief Ethernet Interrupt Service Routine
*
* @return none
*/
void WCHNET_ETHIsr(void)
{
uint32_t intStat;
intStat = ETH->DMASR;
if (intStat & ETH_DMA_FLAG_AIS)
{
if (intStat & ETH_DMA_FLAG_RBU)
{
ETH_DMAClearITPendingBit(ETH_DMA_FLAG_RBU);
}
ETH_DMAClearITPendingBit(ETH_DMA_FLAG_AIS);
}
if( intStat & ETH_DMA_FLAG_NIS )
{
if( intStat & ETH_DMA_FLAG_R )
{
/*If you don't use the Ethernet library,
* you can do some data processing operations here*/
ETH_DMAClearITPendingBit(ETH_DMA_FLAG_R);
}
if( intStat & ETH_DMA_FLAG_T )
{
ETH_DMAClearITPendingBit(ETH_DMA_FLAG_T);
}
if( intStat & ETH_DMA_FLAG_PHYSR)
{
ETH_CheckPhyInterruptStatus( );
ETH_DMAClearITPendingBit(ETH_DMA_FLAG_PHYSR);
}
ETH_DMAClearITPendingBit(ETH_DMA_FLAG_NIS);
}
}
/*********************************************************************
* @fn ETH_Init
*
* @brief Ethernet initialization.
*
* @return none
*/
void ETH_Init( uint8_t *macAddr )
{
ETH_Configuration( macAddr );
PHY_LEDCfg();
ETH_DMATxDescChainInit(DMATxDscrTab, MACTxBuf, ETH_TXBUFNB);
ETH_DMARxDescChainInit(DMARxDscrTab, MACRxBuf, ETH_RXBUFNB);
pDMARxSet = DMARxDscrTab;
pDMATxSet = DMATxDscrTab;
NVIC_EnableIRQ(ETH_IRQn);
NVIC_SetPriority(ETH_IRQn, 0);
}
/*********************************************************************
* @fn ETH_LibInit
*
* @brief Ethernet library initialization program
*
* @return command status
*/
uint8_t ETH_LibInit( uint8_t *ip, uint8_t *gwip, uint8_t *mask, uint8_t *macaddr )
{
uint8_t s;
struct _WCH_CFG cfg;
memset(&cfg,0,sizeof(cfg));
cfg.TxBufSize = ETH_TX_BUF_SZE;
cfg.TCPMss = WCHNET_TCP_MSS;
cfg.HeapSize = WCHNET_MEM_HEAP_SIZE;
cfg.ARPTableNum = WCHNET_NUM_ARP_TABLE;
cfg.MiscConfig0 = WCHNET_MISC_CONFIG0;
cfg.MiscConfig1 = WCHNET_MISC_CONFIG1;
cfg.net_send = ETH_TxPktChainMode;
cfg.CheckValid = WCHNET_CFG_VALID;
s = WCHNET_ConfigLIB(&cfg);
if( s ){
return (s);
}
s = WCHNET_Init(ip,gwip,mask,macaddr);
ETH_Init( macaddr );
return (s);
}
/******************************** endfile @ eth_driver ******************************/