【S32K 進階之旅】 NXP S32K3 以太網 RMII 接口調試(2)

前言

        前文介紹了 NXP S32K3 以太網 RMII 接口調試的開發環境搭建,下面開始詳解軟體調試步驟。沒看過第一節的小夥伴請移步《【S32K 進階之旅】 NXP S32K3 以太網 RMII 接口調試(1)》,話不多說我們直接進入正題。


lwip Stack 介紹

       TCP/IP Stack 是 TCP/IP 協議套件的輕量級實現,而實現 lwIP TCP/IP 的重點是減少代碼量的同時仍然擁有一個完整的 TCP,lwIP 適用於具有 10Kbytes+ RAM 和 40Kbytes ROM 空間的嵌入式系統。TCP/IP Stack 的代碼是開源的,可以參考以下鏈接:

lwIP - A Lightweight TCP/IP stack

  • 支持的協議:
  • IP(Internet Protocol)
  • ICMP(Internet Control Message Protocol)
  • IGMP(Internet Group Management Protocol)
  • UDP(User Datagram Protocol)
  • TCP(Transmission Control Protocol)
  • DHCP(Dynamic Host Configuration Protocol)
  • ARP(Address Resolution Protocol)
  • 支持的三類 APIs:
    • Raw API: Front/Back-ground structure, best performance, minimal code size.
    • Netconn API: Multi-threaded operations with OS, Increased usability, lower performance, higher memory footprint.
    • BSD Socket API: developed on top of the NetconnAPI, offers more portability.
  • 支持 SSL/TLS (WolfSSL):
    • 輕量級,可移植,基於 C 語言的 SSL/TLS 庫
    • 依賴 lwip 堆棧和 FreeRTOS 運行,通過 RTD/HSE 進行加密操作,硬體加速
    • WolfSSL 和 wolfCrypt 可以根據 GPLv2 或標準商業許可使用:wolfSSL – Embedded SSL/TLS Library


圖 1  TCP/IP 軟體架構



程序修改

1.  重定向 printf,添加串口列印功能(此步驟可以忽略)

       GCC 中沒有 Micro,只能使用 newlib 標準庫,printf 定義在 <stdio.h> 頭文件中:“int printf(const char *_restrct, …”,根據 __restrict 字符串給出的格式列印輸出到 stdout(標準輸出)中,它調用更底層的函數“int _write(int iFileHandle, char *pcBuffer, int iLength)”來列印。

       新建 <retarget.c>文件,重新定義“_write”函數,並鏈接到 S32K3 的庫函數“Lpuart_Uart_Ip_SyncSend”(見下圖),實現 printf 串口列印,現在我們可以將初始化以太網模塊的數據直觀的列印出來。



圖 2  printf 重定向


圖 3  新建 printf 源文件



2.  以太網 PHY 初始化(JL3101)

       例程中已經有 DP83848/TLK110/TJA1100 等型號以太網模塊的初始化配置,初始化操作在 “main() -> device_init() -> Eth_T_InitPhys()”函數中。而本章我們使用國產的景略 JL3101百兆以太網模塊實現 S32K3 MAC 與 PHY 之間的 RMII 通信。通過 SMI 總線配置寄存器初始化 JL3101,重新改寫 Eth_T_InitPhys() 函數,並通過串口列印實時信息。


圖 4 讀寫 JL3101的數據

 

需要注意的是,JL3101 是通過 Clause45 幀結構方式訪問 PHY 的,在 S32K3 SDK 中有可直接調用的函數:

  • 讀寄存器:Gmac_Ip_MDIOReadMMD();
  • 寫寄存器:Gmac_Ip_MDIOWriteMMD();



初始化 PHY 具體步驟如下:

  • PHY 復位管腳拉低 4ms 以上解除復位,復位管腳拉高 15ms 後開始查找 ID
  • 查找 JL3101 PHY ID:
    • ID0 = 0x937C
    • ID1 = 0x4010
  • 關閉 TC10 車載以太網休眠和喚醒功能
  • 配置 MDI 接口速率為:100Mbs
    • 此時信號轉接器檔位應調成 100M
  • 配置 MDI 主從模式為:Master Mode
    • 此時信號轉接器檔位應調成 Slave Mode
  • 配置 MAC 工作模式,我們選擇 RMII to copper
  • 軟復位:寫入命令後,循環讀取寄存器直到復位完成
  • 復位後等待 MAC 與 PHY 建立鏈接:
    • 當讀到寄存器“PMA/PMD Status_1[2] = 1”代表鏈接成功



按照以上步驟編寫代碼:

static void Eth_T_InitPhys(void)

{

    uint16 phy_reg_val0, phy_reg_val1;

    uint16 phy_addr;

 

    Siul2_Dio_Ip_ClearPins(PTE_H_HALF, (1<<5));

    TestDelay(480000);

    Siul2_Dio_Ip_SetPins(PTE_H_HALF, (1<<5));

    TestDelay(4800000);

 

    Gmac_Ip_EnableMDIO(CFG_PHY_CTRL_IDX, FALSE, 80000000U);

 

    printf("This is a JL3101 Ethernet module demo for S32K3.\n");

 

    /* Search for the PHY address */

    for (phy_addr = 0U; phy_addr < 8U; ++phy_addr)

    {

       Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 2U, &phy_reg_val0, 1U);

       Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 3U, &phy_reg_val1, 1U);

 

        /* check for PHY ID */

        if ((phy_reg_val0 == JL3101_PHY_ID0) && (phy_reg_val1 == JL3101_PHY_ID1))


        {

            break; /* found the PHY ID*/

        }

    }

    printf("Search for the PHY address:\n");

    printf("  Phy_Addr = 0x%X   JL3101_PHY_ID0 = 0x%04X   JL3101_PHY_ID1 = 0x%04X.\n", phy_addr, phy_reg_val0 ,phy_reg_val1);

 

    /* TC10 Disable */

    Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, 3U, 0x8707U, 0x0000U, 1U);

    while (Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 3U, 0x8707U, &phy_reg_val0, 1U) & 0x8000U)

    { /* Busy Wait */

    }

    printf("TC10 Disable:\n");

    printf("  devad = 0x3   reg = 0x8707  reg_value = 0x%04X\n", phy_reg_val0);

 

    /* Speed_Select Lsb = 1 100Mbs */

    Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0U, 0x2000U, 1U);

    while (Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0U, &phy_reg_val0, 1U) & 0x8000U)

    { /* Busy Wait */

    }

    printf("Speed_Select 100Mbs:\n");

    printf("  devad = 0x1   reg = 0x0000  reg_value = 0x%04X\n", phy_reg_val0);

 

    /* Master Mode 0xC000, Slave Mode 0x8000 */

    Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0x0834U, 0xC000U, 1U);

    while (Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0x0834U, &phy_reg_val0, 1U) & 0x8000U)

    { /* Busy Wait */

    }

    printf("Master Mode 0xC000, Slave Mode 0x8000:\n");

    printf("  devad = 0x1   reg = 0x0834  reg_value = 0x%04X\n", phy_reg_val0);

 

    /* RMII to copper */

    Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, 3U, 0x8000U, 0x0246U, 1U);

    while (Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 3U, 0x8000U, &phy_reg_val0, 1U) & 0x8000U)

    { /* Busy Wait */

    }

    printf("RMII to copper:\n");

    printf("  devad = 0x3   reg = 0x8000  reg_value = 0x%04X\n", phy_reg_val0);

 

    /* soft Reset */

    Gmac_Ip_MDIOWriteMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0x0000U, 0xA000, 1U);

    printf("Soft Reset:\n");

    do

    {

       Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0x0000U, &phy_reg_val0, 1U);

       printf("  devad = 0x1   reg = 0x0000  reg_value = 0x%04X\n", phy_reg_val0);

    }while ((0U != (phy_reg_val0 & (1U << 15U))));

 

       /* Wait to establish link */

    printf("Wait to establish link:\n");

    do

    {

       Gmac_Ip_MDIOReadMMD(CFG_PHY_CTRL_IDX, phy_addr, 1U, 0x1, &phy_reg_val0, 1U);

    }while ((0U == (phy_reg_val0 & (1U << 2U))));

    printf("  devad = 0x1   reg = 0x0001  reg_value = 0x%04X\n", phy_reg_val0);

    printf("PMA/PMD receive link up.\n");

}


常見問題

1.  調試和運行程序時跳到“DevAssert();”

       這是因為 S32K3 板沒有安裝 HSE 固件,而 lwip 演示啟用了 ssl_echo 應用程序,會調用一些需要 HSE 固件支持的 API。


解決辦法:

  • 在 S32K3 MCU 板上安裝 HSE 固件,官網有 HSE 安裝教程,這裡不再展開描述
  • 在不需要測試 SSL service 的情況下,臨時注釋掉例程中 < test.c> 第 522 行的這個函數“secure_socket_init();”,如下圖所示



2.  HardFault_Handler()

       程序正常運行約 20 分鐘後突然停止運行,並跳到 HardFault_Handler() 硬體故障處,這是因為代碼中限制了測試時間(默認為 1200秒),超時後會停止執行程序。增加 tests_timeout 變量值可以解決問題(在 <test.c> 的第 250 行)




小結

       文中使用的開發板“Cavalry”現已上架大大購,鏈接如下:DVK2305- CAVALRY S32K344產品詳情_大大購 (wpgdadago.com)

       現在 S32K3 車載以太網模塊調試的軟體部分已經修改並編譯通過,最後一節進行以太網 RMII 通信功能驗證,敬請關注本章更新。獲取更多資訊,或進一步交流關於 S32K3 的技術問題,歡迎聯繫世平集團上海應用技術處 ATU <atu.sh@wpi-group.com>。




參考文檔


[1] Automotive TCP/IP Stack User Manual. Rev. 33.0

[2] lwip_s32k344 demo guide.




歡迎在博文下方留言評論,我們會及時回復您的問題。如有更多需求,歡迎聯繫大聯大世平集團 ATU 部門:atu.sh@wpi-group.com

作者:Jadyn Li /李瑞潔

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論