Files
vd_960/vd960DBN/ETH/NetLib/eth_driver.c
wangfq 95808f9f25 refactor(vd960Loop): 算法回退到 DLD154V4B,四通道适配
- 用 DLD154V4B vd1_task/per_channel 替换 vds_task 复杂算法
- 移除 FUNCTION_B/二次判断/快速变化/多重确认等增强特性
- 保留平坦性离开算法 (CN200910309382),每通道独立状态
- 灵敏度表改为 DLD154V4B 4级: {216,108,36,10} / {108,72,18,9}
- 清理废弃类型: FltHistoryManager, Loop_ACS_Info, StageRangeConfig 等
- 首次添加 vd960DBN 完整源码
2026-06-25 16:21:57 +08:00

746 lines
23 KiB
C

/********************************** (C) COPYRIGHT *******************************
* File Name : eth_driver.c
* Author : WCH
* Version : V1.3.0
* Date : 2022/05/26
* 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"
__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 */
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];
uint32_t volatile LocalTime;
ETH_DMADESCTypeDef *DMATxDescToSet;
ETH_DMADESCTypeDef *DMARxDescToGet;
ETH_DMADESCTypeDef *pDMARxSet;
volatile uint8_t phyLinkReset;
volatile uint32_t phyLinkTime;
uint8_t phyPN = 0x01;
uint8_t phyStatus = 0;
uint8_t phySucCnt = 0;
uint8_t phyLinkCnt = 0;
uint8_t phyRetryCnt = 0;
uint8_t CRCErrPktCnt = 0;
uint8_t phyLinkStatus = 0;
uint8_t phyPNChangeCnt = 0;
uint8_t PhyPolarityDetect = 0;
/*********************************************************************
* @fn WCHNET_GetMacAddr
*
* @brief Get MAC address
*
* @return none.
*/
void WCHNET_GetMacAddr( uint8_t *p )
{
uint8_t i;
uint8_t *macaddr=(uint8_t *)(ROM_CFG_USERADR_ID+5);
for(i=0;i<6;i++)
{
*p = *macaddr;
p++;
macaddr--;
}
}
/*********************************************************************
* @fn WCHNET_TimeIsr
*
* @brief
*
* @return none.
*/
void WCHNET_TimeIsr( uint16_t timperiod )
{
LocalTime += timperiod;
}
/*********************************************************************
* @fn WritePHYReg
*
* @brief MCU write PHY register.
*
* @param reg_add - PHY address,
* reg_val - value you want to write.
*
* @return none
*/
void WritePHYReg(uint8_t reg_add,uint16_t reg_val)
{
R32_ETH_MIWR = (reg_add & RB_ETH_MIREGADR_MIRDL) | (1<<8) | (reg_val<<16);
}
/*********************************************************************
* @fn ReadPHYReg
*
* @brief MCU read PHY register.
*
* @param reg_add - PHY address.
*
* @return value you want to get.
*/
uint16_t ReadPHYReg(uint8_t reg_add)
{
R8_ETH_MIREGADR = reg_add; // write address
return R16_ETH_MIRD; // get data
}
/*********************************************************************
* @fn WCHNET_LinkProcess
*
* @brief link process.
*
* @param none.
*
* @return none.
*/
void WCHNET_LinkProcess( void )
{
uint16_t phy_anlpar, phy_bmcr, phy_bmsr;
phy_anlpar = ReadPHYReg(PHY_ANLPAR);
phy_bmsr = ReadPHYReg(PHY_BMSR);
if(phy_anlpar&PHY_ANLPAR_SELECTOR_FIELD)
{
if( !(phyLinkStatus&PHY_LINK_WAIT_SUC) )
{
if( (phyPN&0x0C) == PHY_PN_SWITCH_P )
{
phySucCnt = 0;
phyLinkCnt = 0;
phyLinkStatus = PHY_LINK_WAIT_SUC;
}
else
{
if( !(phyLinkStatus&PHY_LINK_SUC_N) )
{
phyRetryCnt = 0;
phyLinkStatus |= PHY_LINK_SUC_N;
phyPN &= ~PHY_PN_SWITCH_N;
phy_bmcr = ReadPHYReg(PHY_BMCR);
phy_bmcr |= 1<<9;
WritePHYReg(PHY_BMCR, phy_bmcr);
WritePHYReg(PHY_MDIX, phyPN);
}
else
{
phySucCnt = 0;
phyLinkCnt = 0;
phyLinkStatus = PHY_LINK_WAIT_SUC;
}
}
}
else{
if((phySucCnt++ == 5) && ((phy_bmsr&PHY_AutoNego_Complete) == 0))
{
phySucCnt = 0;
phyRetryCnt = 0;
phyPNChangeCnt = 0;
phyLinkStatus = PHY_LINK_INIT;
phy_bmcr = ReadPHYReg(PHY_BMCR);
phy_bmcr |= 1<<9;
WritePHYReg(PHY_BMCR, phy_bmcr);
if((phyPN&0x0C) == PHY_PN_SWITCH_P)
{
phyPN |= PHY_PN_SWITCH_N;
}
else {
phyPN &= ~PHY_PN_SWITCH_N;
}
WritePHYReg(PHY_MDIX, phyPN);
}
}
}
else
{
if(phy_bmsr & PHY_AutoNego_Complete)
{
phySucCnt = 0;
phyLinkCnt = 0;
phyLinkStatus = PHY_LINK_WAIT_SUC;
}
else {
if( phyLinkStatus == PHY_LINK_WAIT_SUC )
{
if(phyLinkCnt++ == 10)
{
phyLinkCnt = 0;
phyRetryCnt = 0;
phyPNChangeCnt = 0;
phyLinkStatus = PHY_LINK_INIT;
}
}
else if(phyLinkStatus == PHY_LINK_INIT)
{
if(phyPNChangeCnt++ == 10)
{
phyPNChangeCnt = 0;
phyPN = ReadPHYReg(PHY_MDIX);
phyPN &= ~0x0c;
phyPN ^= 0x03;
WritePHYReg(PHY_MDIX, phyPN);
}
else{
if((phyPN&0x0C) == PHY_PN_SWITCH_P)
{
phyPN |= PHY_PN_SWITCH_N;
}
else {
phyPN &= ~PHY_PN_SWITCH_N;
}
WritePHYReg(PHY_MDIX, phyPN);
}
}
else if(phyLinkStatus == PHY_LINK_SUC_N)
{
if((phyPN&0x0C) == PHY_PN_SWITCH_P)
{
phyPN |= PHY_PN_SWITCH_N;
phy_bmcr = ReadPHYReg(PHY_BMCR);
phy_bmcr |= 1<<9;
WritePHYReg(PHY_BMCR, phy_bmcr);
Delay_Us(10);
WritePHYReg(PHY_MDIX, phyPN);
}
else{
if(phyRetryCnt++ == 15)
{
phyRetryCnt = 0;
phyPNChangeCnt = 0;
phyLinkStatus = PHY_LINK_INIT;
}
}
}
}
}
}
/*********************************************************************
* @fn WCHNET_PhyPNProcess
*
* @brief Phy PN Polarity related processing
*
* @param none.
*
* @return none.
*/
void WCHNET_PhyPNProcess(void)
{
uint32_t PhyVal;
phyLinkTime = LocalTime;
if(CRCErrPktCnt >= 3)
{
PhyVal = ReadPHYReg(PHY_MDIX);
if((PhyVal >> 2) & 0x01)
PhyVal &= ~(3 << 2); //change PHY PN Polarity to normal
else
PhyVal |= 1 << 2; //change PHY PN Polarity to reverse
WritePHYReg(PHY_MDIX, PhyVal);
CRCErrPktCnt = 0;
}
}
/*********************************************************************
* @fn WCHNET_HandlePhyNegotiation
*
* @brief Handle PHY Negotiation.
*
* @param none.
*
* @return none.
*/
void WCHNET_HandlePhyNegotiation(void)
{
if(phyLinkReset) /* After the PHY link is disconnected, wait 500ms before turning on the PHY clock*/
{
if( LocalTime - phyLinkTime >= 500 )
{
phyLinkReset = 0;
EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN;
WritePHYReg(PHY_BMCR, PHY_Reset);
PHY_NEGOTIATION_PARAM_INIT();
}
}
else
{
if( !phyStatus ) /* Handling PHY Negotiation Exceptions */
{
if( LocalTime - phyLinkTime >= PHY_LINK_TASK_PERIOD ) /* 50ms cycle timing call */
{
phyLinkTime = LocalTime;
WCHNET_LinkProcess( );
}
}
else{
if(PhyPolarityDetect)
{
if( LocalTime - phyLinkTime >= 2 * PHY_LINK_TASK_PERIOD )
{
WCHNET_PhyPNProcess();
}
}
}
}
}
/*********************************************************************
* @fn WCHNET_MainTask
*
* @brief library main task function
*
* @return none.
*/
void WCHNET_MainTask(void)
{
WCHNET_NetInput( ); /* Ethernet data input */
WCHNET_PeriodicHandle( ); /* Protocol stack time-related task processing */
WCHNET_HandlePhyNegotiation( );
}
/*********************************************************************
* @fn ETH_LedLinkSet
*
* @brief set eth link led,setbit 0 or 1,the link led turn on or turn off
*
* @return none
*/
void ETH_LedLinkSet( uint8_t mode )
{
if( mode == LED_OFF )
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
}
/*********************************************************************
* @fn ETH_LedDataSet
*
* @brief set eth data led,setbit 0 or 1,the data led turn on or turn off
*
* @return none
*/
void ETH_LedDataSet( uint8_t mode )
{
if( mode == LED_OFF )
{
GPIO_SetBits(GPIOA, GPIO_Pin_13);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_13);
}
}
/*********************************************************************
* @fn ETH_LedConfiguration
*
* @brief set eth data and link led pin
*
* @return none
*/
void ETH_LedConfiguration(void)
{
GPIO_InitTypeDef GPIO={0};
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_13;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO);
ETH_LedDataSet(LED_OFF);
ETH_LedLinkSet(LED_OFF);
}
/*********************************************************************
* @fn ETH_DMATxDescChainInit
*
* @brief Initializes the DMA Tx descriptors in chain mode.
*
* @param DMATxDescTab - Pointer on the first Tx desc list
* TxBuff - Pointer on the first TxBuffer list
* TxBuffCount - Number of the used Tx desc in the list
*
* @return none
*/
void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount)
{
ETH_DMADESCTypeDef *DMATxDesc;
DMATxDescToSet = DMATxDescTab;
DMATxDesc = DMATxDescTab;
DMATxDesc->Status = 0;
DMATxDesc->Buffer1Addr = (uint32_t)TxBuff;
DMATxDesc->Buffer2NextDescAddr = (uint32_t)DMATxDescTab;
}
/*********************************************************************
* @fn ETH_DMARxDescChainInit
*
* @brief Initializes the DMA Rx descriptors in chain mode.
*
* @param DMARxDescTab - Pointer on the first Rx desc list.
* RxBuff - Pointer on the first RxBuffer list.
* RxBuffCount - Number of the used Rx desc in the list.
*
* @return none
*/
void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount)
{
uint8_t i = 0;
ETH_DMADESCTypeDef *DMARxDesc;
DMARxDescToGet = DMARxDescTab;
for(i = 0; i < RxBuffCount; i++)
{
DMARxDesc = DMARxDescTab + i;
DMARxDesc->Status = ETH_DMARxDesc_OWN;
DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_MAX_PACKET_SIZE]);
if(i < (RxBuffCount - 1))
{
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1);
}
else
{
DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
}
}
}
/*********************************************************************
* @fn ETH_Start
*
* @brief Enables ENET MAC and DMA reception/transmission.
*
* @return none
*/
void ETH_Start(void)
{
R16_ETH_ERXST = DMARxDescToGet->Buffer1Addr;
R8_ETH_ECON1 |= RB_ETH_ECON1_RXEN; //receive enable
}
/*********************************************************************
* @fn ETH_SetClock
*
* @brief Set ETH Clock(60MHz).
*
* @return none
*/
void ETH_SetClock(void)
{
/* ETH initialization */
RCC_ETHDIVConfig(RCC_ETHCLK_Div2); // 120M/2 = 60MHz
}
/*********************************************************************
* @fn ETH_Configuration
*
* @brief Ethernet configure.
*
* @return none
*/
void ETH_Configuration( uint8_t *macAddr )
{
ETH_SetClock( );
R8_ETH_EIE = 0;
R8_ETH_EIE |= RB_ETH_EIE_INTIE |
RB_ETH_EIE_RXIE|
RB_ETH_EIE_LINKIE|
RB_ETH_EIE_TXIE |
RB_ETH_EIE_TXERIE|
RB_ETH_EIE_RXERIE; //Turn on all interrupts
R8_ETH_EIE |= RB_ETH_EIE_R_EN50; //Turn on 50 ohm pull-up
R8_ETH_EIR = 0xff; //clear interrupt flag
R8_ETH_ESTAT |= RB_ETH_ESTAT_INT | RB_ETH_ESTAT_BUFER; //clear state
R8_ETH_ECON1 |= (RB_ETH_ECON1_TXRST|RB_ETH_ECON1_RXRST); //Transceiver module reset
R8_ETH_ECON1 &= ~(RB_ETH_ECON1_TXRST|RB_ETH_ECON1_RXRST);
//Filter mode, received packet type
R8_ETH_ERXFCON = 0;
R8_ETH_MAADRL1 = macAddr[5]; // MAC assignment
R8_ETH_MAADRL2 = macAddr[4];
R8_ETH_MAADRL3 = macAddr[3];
R8_ETH_MAADRL4 = macAddr[2];
R8_ETH_MAADRL5 = macAddr[1];
R8_ETH_MAADRL6 = macAddr[0];
//Filter mode, limit packet type
R8_ETH_MACON1 |= RB_ETH_MACON1_MARXEN; //MAC receive enable
R8_ETH_MACON2 &= ~RB_ETH_MACON2_PADCFG;
R8_ETH_MACON2 |= PADCFG_AUTO_3; //All short packets are automatically padded to 60 bytes
R8_ETH_MACON2 |= RB_ETH_MACON2_TXCRCEN; //Hardware padded CRC
R8_ETH_MACON2 &= ~RB_ETH_MACON2_HFRMEN; //Jumbo frames are not received
R8_ETH_MACON2 |= RB_ETH_MACON2_FULDPX;
R16_ETH_MAMXFL = ETH_MAX_PACKET_SIZE;
R8_ETH_ECON2 &= ~(0x07 << 1);
R8_ETH_ECON2 |= 5 << 1;
EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN;
}
/*********************************************************************
* @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 )
{
/* Return ERROR: OWN bit set */
return ETH_ERROR;
}
DMATxDescToSet->Status |= ETH_DMATxDesc_OWN;
R16_ETH_ETXLN = len;
R16_ETH_ETXST = (uint32_t)pBuff;
R8_ETH_ECON1 |= RB_ETH_ECON1_TXRTS; //start sending
/* 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 ETH_LinkUpCfg
*
* @brief When the PHY is connected, configure the relevant functions.
*
* @param regval BMSR register value
*
* @return none.
*/
void ETH_LinkUpCfg(uint16_t regval)
{
WCHNET_PhyStatus( regval );
/* Receive CRC error packets */
R8_ETH_ERXFCON |= RB_ETH_ERXFCON_CRCEN;
CRCErrPktCnt = 0;
PhyPolarityDetect = 1;
phyLinkTime = LocalTime;
phyStatus = PHY_Linked_Status;
ETH_Start( );
}
/*********************************************************************
* @fn ETH_LinkDownCfg
*
* @brief When the PHY is disconnected, configure the relevant functions.
*
* @param regval BMSR register value
*
* @return none.
*/
void ETH_LinkDownCfg(uint16_t regval)
{
WCHNET_PhyStatus( regval );
EXTEN->EXTEN_CTR &= ~EXTEN_ETH_10M_EN;
phyLinkReset = 1;
phyLinkTime = LocalTime;
}
/*********************************************************************
* @fn ETH_PHYLink
*
* @brief
*
* @return none
*/
void ETH_PHYLink( void )
{
u16 phy_bsr, phy_anlpar;
phy_bsr = ReadPHYReg(PHY_BMSR);
phy_anlpar = ReadPHYReg(PHY_ANLPAR);
if(phy_bsr & PHY_Linked_Status) //Valid link established
{
if(phy_bsr & PHY_AutoNego_Complete) //Auto-negotiation completed -- LinkUp
{
ETH_LinkUpCfg(phy_bsr);
}
else {
if(phy_anlpar == 0) //The auto-negotiation signal of the peer device is not obtained
{
WritePHYReg(PHY_BMCR, PHY_Reset);
PHY_NEGOTIATION_PARAM_INIT();
}
else {
ETH_LinkDownCfg(phy_bsr);
}
}
}
else { //LinkDown
ETH_LinkDownCfg(phy_bsr);
}
}
/*********************************************************************
* @fn WCHNET_ETHIsr
*
* @brief
*
* @return none
*/
void WCHNET_ETHIsr( void )
{
uint8_t eth_irq_flag, estat_regval;
eth_irq_flag = R8_ETH_EIR;
if(eth_irq_flag&RB_ETH_EIR_RXIF) //Receive complete
{
R8_ETH_EIR = RB_ETH_EIR_RXIF;
/* Check if the descriptor is owned by the ETHERNET DMA */
if( DMARxDescToGet->Status & ETH_DMARxDesc_OWN )
{
estat_regval = R8_ETH_ESTAT;
if(estat_regval & \
(RB_ETH_ESTAT_BUFER | RB_ETH_ESTAT_RXCRCER | RB_ETH_ESTAT_RXNIBBLE | RB_ETH_ESTAT_RXMORE))
{
return;
}
if( ((ETH_DMADESCTypeDef*)(DMARxDescToGet->Buffer2NextDescAddr))->Status& ETH_DMARxDesc_OWN )
{
DMARxDescToGet->Status &= ~ETH_DMARxDesc_OWN;
DMARxDescToGet->Status &= ~ETH_DMARxDesc_ES;
DMARxDescToGet->Status |= (ETH_DMARxDesc_FS|ETH_DMARxDesc_LS);
DMARxDescToGet->Status &= ~ETH_DMARxDesc_FL;
DMARxDescToGet->Status |= ((R16_ETH_ERXLN+4)<<ETH_DMARxDesc_FrameLengthShift);
/* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
/* Selects the next DMA Rx descriptor list for next buffer to read */
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
R16_ETH_ERXST = DMARxDescToGet->Buffer1Addr;
}
}
if(PhyPolarityDetect)
{
PhyPolarityDetect = 0;
/* Discard CRC error packet */
R8_ETH_ERXFCON &= ~RB_ETH_ERXFCON_CRCEN;
}
}
if(eth_irq_flag&RB_ETH_EIR_TXIF) //send completed
{
DMATxDescToSet->Status &= ~ETH_DMATxDesc_OWN;
R8_ETH_EIR = RB_ETH_EIR_TXIF;
}
if(eth_irq_flag&RB_ETH_EIR_LINKIF) //Link change
{
ETH_PHYLink();
R8_ETH_EIR = RB_ETH_EIR_LINKIF;
}
if(eth_irq_flag&RB_ETH_EIR_TXERIF) //send error
{
DMATxDescToSet->Status &= ~ETH_DMATxDesc_OWN;
R8_ETH_EIR = RB_ETH_EIR_TXERIF;
}
if(eth_irq_flag&RB_ETH_EIR_RXERIF) //receive error
{
if(PhyPolarityDetect) CRCErrPktCnt++;
R8_ETH_EIR = RB_ETH_EIR_RXERIF;
}
}
/*********************************************************************
* @fn ETH_Init
*
* @brief Ethernet initialization.
*
* @return none
*/
void ETH_Init( uint8_t *macAddr )
{
ETH_LedConfiguration( );
Delay_Ms(100);
ETH_Configuration( macAddr );
ETH_DMATxDescChainInit(DMATxDscrTab, MACTxBuf, ETH_TXBUFNB);
ETH_DMARxDescChainInit(DMARxDscrTab, MACRxBuf, ETH_RXBUFNB);
pDMARxSet = DMARxDscrTab;
NVIC_EnableIRQ(ETH_IRQn);
}
/*********************************************************************
* @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.led_link = ETH_LedLinkSet;
cfg.led_data = ETH_LedDataSet;
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 ******************************/