TCP/IP協議學習(三) STM32中ETH驅動配置注意事項


1.MII/RMII/SMI接口連接和配置
SMI
又稱站點管理接口,用於cpu與外置PHY芯片通訊,配置相關參數,包含MDC和MDIO兩個管腳(CPU上有對應引腳,當然用普通GPIO口模擬SMI管理也是可行的,不過按照固定時序寫入和讀取數據)。‘
  MII和RMII則是是兩種不同的以太網數據傳輸接口,因為RMII在使用更少接口的情況下具有MII相同的功效,其中MII如下圖連接即可:
 
特別注意:RMII模式下REF_CLK要連接CPU的MCO引腳,且MCO輸出時鍾應為50MHz。
這里說下我最近遇到的stm32在MII模式不能正常接收數據,后來發現是STM的MII_ER腳被配置成以太網引腳,而實際懸空(並未連接到PHY),導致stm32認為接收出錯,將接收數據丟失。
解決辦法: 如果硬件還未完成設計,則MII_ER最好正確連接到PHY指定端口,可以提前過濾mac子層檢測到的錯誤包。
如果硬件設計已經完成,且出錯,那么就取消MII_ER引腳的配置即可(帶來的后果就是少一層錯誤過濾,問題不大)
2.PHY初始化

  一般來說,stm32外部驅動PHY芯片有兩種連接方式,MII和RMII總線,這個與硬件設計有關,不過stm32芯片一般都支持這兩種總線連接方式,因為RMII總線在傳輸效果不變的情況下占用接口更少,因此一般推薦RMII方式.
  以DP83848芯片為例:
 
從上面可以看出RMII總線對應的輸入時鍾要設置為50MHZ, 當然這與你原理圖的布線有,連接PHY芯片X1接口對應GPIO接口的外設區域時鍾就要設定為該值,
考慮到掛在同區域外設的時鍾要求.為了方便設計,對於stm32f207vet6(我用的芯片),將系統時鍾從120MHz改為100MHz,該區域外設時鍾設置為1/2即可。
對於stm32f107vc則需要通過PLL3將MCO端口時鍾拉高到50Mhz輸出到phy。目前來說大部分人對於stm32驅動的移植都是直接把官方例程拿過來用,
但我建議還是對照參考手冊仔細研讀每一項,自己配置ETH參數,因為stm32芯片集成的MAC配置對於數據的接收和發送影響很大。
 ETH_DeInit(); /* Software reset */ ETH_SoftwareReset(); /* Wait for software reset */
  while (ETH_GetSoftwareResetStatus() == SET); /* ETHERNET Configuration---------------------------------------------*/
  /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */ ETH_StructInit(&ETH_InitStructure); /* Fill ETH_InitStructure parametrs */
  /*------------------------ ETH_MACCR-----------------------------------*/
    //參數是否自動配置,選擇disable需要自動配置默認參數
   ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Disable; ETH_InitStructure.ETH_Watchdog = ETH_Watchdog_Disable;                            //關閉看門狗定時器,允許接收超長幀
    ETH_InitStructure.ETH_Jabber = ETH_Jabber_Disable;                                //關閉jabber定時器,允許發送超長幀
    ETH_InitStructure.ETH_InterFrameGap = ETH_InterFrameGap_40Bit;                //發送幀間間隙
    ETH_InitStructure.ETH_Speed = ETH_Speed_100M;                                     //快速以太網速度
    ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;                    //不啟用自循環模式
    ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;                                 //全雙工模式
  
    /*自動填充/CRC剝離處理不執行,轉發所有幀*/ ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable; #if CHECKSUM_BY_HARDWARE  ETH_InitStructure.ETH_ChecksumOffload = ETH_ChecksumOffload_Enable;                //IPV4頭文件硬件校驗
#endif

    /*------------------------ ETH_MACFFR----------------------------------*/  ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Disable;                                   //MAC過濾只接受通過源目的地址的數據
    ETH_InitStructure.ETH_SourceAddrFilter = ETH_SourceAddrFilter_Normal_Enable;                 //MAC過濾源地址錯誤幀?
    ETH_InitStructure.ETH_PassControlFrames = ETH_PassControlFrames_BlockAll;                    //MAC不轉發任何控制幀
    ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Enable;        //接收廣播幀
    ETH_InitStructure.ETH_DestinationAddrFilter = ETH_DestinationAddrFilter_Normal;              //目的地址過濾結果正常
    ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;                         //混雜模式,啟用幀過濾
    ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect;             //過濾器正常工作,不傳送控制幀
    ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect;                 //單播幀目的地址完美過濾

   /*------------------------ DMA ETH_DMAOMR -----------------------------------*/  
   /* 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_Disable; ETH_InitStructure.ETH_ReceiveStoreForward = ETH_ReceiveStoreForward_Disable;              //接收數據超過閾值轉發
    ETH_InitStructure.ETH_FlushReceivedFrame = ETH_FlushReceivedFrame_Enable;                 //描述符被占用和接收FIFO不可用時清空FIFO(解決堵塞)
    ETH_InitStructure.ETH_TransmitStoreForward = ETH_TransmitStoreForward_Disable;            //發送數據完整幀轉發
    ETH_InitStructure.ETH_TransmitThresholdControl = ETH_TransmitThresholdControl_64Bytes;    //發送閾值為64Bytes
    ETH_InitStructure.ETH_ForwardErrorFrames = ETH_ForwardErrorFrames_Disable;                //接收FIFO丟棄所有錯誤幀
    
    /*接收FIFO上傳長度不夠的好幀*/
  
ETH_InitStructure.ETH_ForwardUndersizedGoodFrames = ETH_ForwardUndersizedGoodFrames_Enable;
   ETH_InitStructure.ETH_ReceiveThresholdControl
= ETH_ReceiveThresholdControl_64Bytes; //接收閾值為64Bytes
ETH_InitStructure.ETH_SecondFrameOperate = ETH_SecondFrameOperate_Enable; //DMA直接發送第二個幀,不需要之前幀回復 /*------------------------ DMA ETH_DMABMR -----------------------------------*/ ETH_InitStructure.ETH_AddressAlignedBeats = ETH_AddressAlignedBeats_Enable; //傳輸地址對齊 ETH_InitStructure.ETH_FixedBurst = ETH_FixedBurst_Enable; //固定的突發 ETH_InitStructure.ETH_RxDMABurstLength = ETH_RxDMABurstLength_32Beat; ETH_InitStructure.ETH_TxDMABurstLength = ETH_TxDMABurstLength_32Beat; ETH_InitStructure.ETH_DMAArbitration = ETH_DMAArbitration_RoundRobin_RxTx_2_1; //發送和接收比例 2:1 /* Configure Ethernet */ ETH_Init(&ETH_InitStructure, DP83848_PHY_ADDRESS); /* Enable the Ethernet Rx-Tx Interrupt*/ETH_DMAITConfig(ETH_DMA_IT_NIS | ETH_DMA_IT_R | ETH_DMA_IT_T
                    , ENABLE);

     特別注意:以太網底層部分我主要遇到的bug有兩個

     (1).啟動時需要插上網線,否則啟動后以太網工作不正常     問題原因:

  ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable; //開啟PHY的自適應

  如果開啟了自適應(默認代碼是Enable,這就是坑的地方),ETH_Init中會有下面一段

do
{
  timeout++;
} while (!(ETH_ReadPHYRegister(PHYAddress, PHY_BSR) & PHY_Linked_Status) && (timeout < PHY_READ_TO));

 /* Return ERROR in case of timeout */
if(timeout == PHY_READ_TO)
{
    return ETH_ERROR;
}

  也就是說一段時間沒有讀到link狀態,就跳出ETH的配置函數了,這也就導致了stm的eth模塊直接沒有初始化(phy即使配置失敗或者不配置也會根據外部引腳有默認的配置), 然而stm的官方庫卻直接跳出,不得不說是很嚴重的bug。

 解決辦法: 將ETH_AutoNegotiation_Enable改為ETH_AutoNegotiation_Disable, 根據實際情況配置即可。

   (2) 網絡有丟包和卡頓

   這個問題其實是上述問題解決后衍生的問題,因為產品更換過幾次phy,用的同一套驅動,結果有的工作正常,有的雖然能工作,但又大數量的丟包。

   后來測試發現,更換phy后,不同phy的設置寄存器有差異, 出問題的寫入出錯,而默認配置與stm32內部不一致,導致丟包。解決問題發現如果不細致維護ETH_Init這個庫函數中讀寫寄存器部分,適配PHY在軟件上解決很麻煩,不過在對比了幾家phy的說明書后,通過硬件修改配置引腳高低,可以輕松完成stm32與PHY的適配。

   解決辦法: 完全注釋掉ETH_Init中與phy相關的配置,通過外部引腳硬件完成與stm適配,目前測試有dp83848, ip101alf, ip101gr, RTL8201等phy芯片都完美運行。

3.lwip中lwipopt.h文件的修改

 參見http://www.cnblogs.com/zc110747/p/4739588.html設置


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM