STM32ºÍlwip³õѧÕߣ¬·ÖÏíÒ»ÏÂÍø¿ÚÈȲå°Î¹¦Äܵ÷ÊÔ¹ý³Ì¡£
PHYоƬʹÓõÄLAN8720£¬Ê¹ÓÃÔ×Ó¸çµÄlwipÀ©Õ¹Àý³Ì£¬ÔÀý³Ì³õʼ»¯LAN8720ºóÊÇËÀµÈ¡£Êµ¼ÊÏîÄ¿ÖÐÍø¿Ú³õʼ¿ÉÄܲ»²åÍøÏߣ¬ÖÐ;²å°ÎÍøÏߵȣ¬Òò´Ë¶Ô³ÌÐò½øÐÐÐ޸ġ£
1£©ÏÈÊDzο¼ST¹Ù·½ÒÔÌ«Íø¿â£¬×îаæÒÔÌ«Íø¿âΪ2015Äê5Ô·ݣ¨keil5ÖÐsoftware packsÖÐÏÂÔØ£¬»òµ½keil¹ÙÍøÏÂÔØ½Ï¿ì£©£¬ÔÚ´Ë¿âÖвÉÓÃÁËÍⲿÖжϵķ½Ê½ÅжÏÍø¿Ú²å°Î״̬¡£ÓÉÓÚLAN8720µÄÖжϿںÍCLKOUT¸´Óã¬Òò´ËʹÓÃÖжϣ¬Ö»ÄÜʹÓÃ50MHZ·½°¸¡£µç·°´ÕÕ50MHZ¸ü¸Äºó¡£²ÎÕÕ¹ÙÍøÊµÏÖ˼·£¬Ìí¼Ó³ÌÐòµ½¹¤³ÌÖС£½á¹û·¢ÏÖ²å°ÎÍø¿ÚÄܹ»¼ì²âµ½Öжϣ¬µ«ÊǼì²âµÄ״̬ʼÖÕÊÇlink_down. ¿à¿àѰÕÒÔÒò£¬Î´¹û¡£×îÖÕ·ÅÆúÖжϷ½Ê½£¬²ÉÓÃÂÖѯ·½°¸¡£
2£©ÂÖѯ·½°¸µÄ˼·ÊÇ£¬½¨Á¢Ò»¸öµÍÓÅÏȼ¶ÈÎÎñ£¬Ã¿¸ôÒ»¶Îʱ¼ä¼ì²âlink״̬£¬Èç¹û³ÌÐòÔËÐеÚÒ»´Î¼ì²â£¬¼ì²â½á¹ûΪÁ¬½Ó£¬Ôò½«¸ÃÈÎÎñ¹ÒÆð¡£Èç¹ûµÚÒ»´Î¼ì²âΪ¶Ï¿ª£¬Ôò³ÌÐò»á¼ÌÐø¼ì²â£¬Ö±µ½¼ì²âµ½Á¬½Ó£¬Ôò¶ÔMACºÍDMAÖØÐÂ×öÒ»±é³õʼ»¯¡£¾¹ýµ÷ÊԸ÷½·¨¿ÉÐС£
¸½ÖжϷ½°¸£º£¨µ÷ÊÔδ³É¹¦£¬Ö÷ÒªÔÒòΪÖжÏÖмì²âlink״̬Óëʵ¼Ê²»·û£¬ÁíST¹ÙÍøÀý³Ì¼ì²âµ½Íø¿ÚÖØÐÂÁ¬½ÓºóÖ»½øÐÐÁËMACµÄÖØÐ³õʼ»¯£¬Î´½øÐÐDMA³õʼ»¯£¬¾¹ýʵÑ飬·¢ÏÖ³õʼ»¯MACºÍDMA²ÅÕý³££¬Ö»³õʼ»¯MAC£¬»á³ö´í£©
[mw_shl_code=c,true]ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; //????DMA?????????¡¤????????
ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; //???????¡§??¡¤?????
ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; //DMA¡¤?????¡Á??¨®??¡¤??¡è????32??????
ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; //DMA??????¡Á??¨®??¡¤??¡è????32??????
ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1;
rval=ETH_Init(Ð_InitStructure,LAN8720_PHY_ADDRESS); //????ETH
//=======2015/07/08 added by sucore ????????¡ã????¨ª???¨°========================
//?¨´??ST??¡¤???????????????????
if( rval == ETH_ERROR )
{
printf("ETH init error, may be no link\n");
}
EthStatus=rval;
if(ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, PHY_BSR) & 4)
{
EthStatus |= ETH_LINK_FLAG;
}
/* Configure the PHY to generate an interrupt on change of link status */
Eth_Link_PHYITConfig(LAN8720_PHY_ADDRESS);
/* Configure the EXTI for Ethernet link status. */
Eth_Link_EXTIConfig();
/* Enable the Ethernet Rx Interrupt */
ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R , ENABLE);
//==============================================================================
[/mw_shl_code]
[mw_shl_code=c,true]//==================2015/07/08 added by sucore ================================
//==================????????¡ã??¨¤?????¨ª????=====================================
/**
* @brief Configure the PHY to generate an interrupt on change of link status.
* @param PHYAddress: external PHY address
* @retval None
*/
uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress)
{
uint32_t tmpreg = 0;
/* Read MASK register */
tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_MASK);
/* Enable output interrupt events to signal via the INT pin */
tmpreg |= (uint32_t)PHY_MASK_LINK_INT_EN | PHY_MASK_ENERGYON_INT_EN;
if(!(ETH_WritePHYRegister(PHYAddress, PHY_MASK, tmpreg)))
{
/* Return ERROR in case of write timeout */
return ETH_ERROR;
}
/* Read INT register */
tmpreg = ETH_ReadPHYRegister(PHYAddress, PHY_INT);
/* Enable Interrupt on change of link status */
tmpreg |= (uint32_t)PHY_INT_LINK_STATUS|PHY_INT_ENERGYON_STATUS;
if(!(ETH_WritePHYRegister(PHYAddress, PHY_INT, tmpreg)))
{
/* Return ERROR in case of write timeout */
return ETH_ERROR;
}
/* Return SUCCESS */
return ETH_SUCCESS;
}
//==================2015/07/08 added by sucore ================================
//==================????????¡ã??¨¤?????¨ª????=====================================
/**
* @brief EXTI configuration for Ethernet link status.
* @param PHYAddress: external PHY address
* @retval None
*/
void Eth_Link_EXTIConfig(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the INT (PB14) Clock */
RCC_AHB1PeriphClockCmd(ETH_LINK_GPIO_CLK, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Configure INT pin as input */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Pin = ETH_LINK_PIN;
GPIO_Init(ETH_LINK_GPIO_PORT, &GPIO_InitStructure);
/* Connect EXTI Line to INT Pin */
SYSCFG_EXTILineConfig(ETH_LINK_EXTI_PORT_SOURCE, ETH_LINK_EXTI_PIN_SOURCE);
/* Configure EXTI line */
EXTI_InitStructure.EXTI_Line = ETH_LINK_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set the EXTI interrupt to priority 1*/
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//==================2015/07/08 added by sucore ================================
//==================????????¡ã??¨¤?????¨ª????=====================================
/**
* @brief This function handles Ethernet link status.
* @param None
* @retval None
*/
void Eth_Link_ITHandler(uint16_t PHYAddress)
{
u32 temp;
//OS_CPU_SR cpu_sr;
//OS_ENTER_CRITICAL();
/* Check whether the link interrupt has occurred or not */
if( ((ETH_ReadPHYRegister(PHYAddress, PHY_INT)) & PHY_INT_LINK_STATUS)!= 0)
{
delay_ms(1);
temp=(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & 4);
if(temp)
{
netif_set_link_up(&lwip_netif);
}
else
{
netif_set_link_down(&lwip_netif);
}
}
//OS_EXIT_CRITICAL();
}
//==================2015/07/08 added by sucore ================================
//==================????????¡ã??¨¤?????¨ª????=====================================
/**
* @brief This function handles External line 10 interrupt request.
* @param None
* @retval None
*/
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(ETH_LINK_EXTI_LINE) != RESET)
{
Eth_Link_ITHandler(LAN8720_PHY_ADDRESS);
// ETH_Init(Ð_InitStructure,LAN8720_PHY_ADDRESS);
/* Clear interrupt pending bit */
EXTI_ClearITPendingBit(ETH_LINK_EXTI_LINE);
}
}
[/mw_shl_code]
ÂÖѯ·½°¸
[mw_shl_code=c,true]/**********************************************************
?????????? ???????¨ª????¡Á??? 2015/07/11 added by sucore
?????????? ??
?????????? ¡Á????? 0???? 1????
???????¡Â?? ??
**********************************************************/
u8 netlink_status_check(void)
{
// u32 temp=0;
static u32 cursta,presta;
static u8 cnt;
//u8 retval;
cursta=(ETH_ReadPHYRegister(LAN8720_PHY_ADDRESS, PHY_BSR) & 4);
cnt++;
if(cursta!=presta)
{
if(cnt!=1)
{
if(cursta)
{
netif_set_link_up(&lwip_netif);
}
else
{
netif_set_link_down(&lwip_netif);
}
}
else
{;}
cnt=2;
}
else
{cnt=2;}
presta=cursta;
return cursta;
}
void netlink_task(void *pdata)
{
OS_CPU_SR cpu_sr;
static u8 sta=0;
while(1)
{
//u32 temp;
OSTimeDlyHMSM(0,0,2,500);
/* Check whether the link interrupt has occurred or not */
OS_ENTER_CRITICAL();
if(netlink_status_check())
{
sta=1;
}
OS_EXIT_CRITICAL();
if(sta) break;
}
OSTaskSuspend(OS_PRIO_SELF);
OSTimeDlyHMSM(0,0,0,500);
}
[/mw_shl_code]
|