This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi all TI experts,
I'm currently working on configuring our custom board featuring the AM2431, aiming to link the AM2431's RGMII interface with an external PHY, specifically an Ethernet switch IC (Realtek: RTL8363NB-V). Through my research, I've come across suggestions that largely align with the SDK documentation provided:
I've successfully tested the SDK example code "Enet Layer 2 CPSW Example" on the LP-AM243x board. My intention is to replicate this logic for our custom board.
So, based on my understanding of the documentation, I plan to create the necessary driver .c
and .h
files. Additionally, I'll enable the custom board item as illustrated in the documentation snippet below:
[Snippet of enabling custom board item]
Am I on the right track with this approach, or is there anything crucial that I might be overlooking?
Could you provide me more guidance on how to accomplish this task on my custom board?
Best regards,
Larry
Hi Larry,
Hope you are doing well! Thank you posting this question.
I see that you are trying to interface RGMII of AM243x switch to RGMII of RTL8363NB-V switch. Since RTL8363NB-V has two PHY additionally connected, one challenge is to handle both of them from AM243x.
I can suggest the bellow option to start with, if this does not meet your requirements, we have to explore other options-
Using No-PHY interface:
This probably is the easier way to start. This will ignore the PHY link status inside driver and assumes link is up always.
void EnetApp_initLinkArgs(Enet_Type enetType, uint32_t instId, EnetPer_PortLinkCfg *linkArgs, Enet_MacPort macPort) { ... - linkCfg->speed = ENET_SPEED_AUTO; - linkCfg->duplexity = ENET_DUPLEX_AUTO; + linkCfg->speed = ENET_SPEED_1GBIT; + linkCfg->duplexity = ENET_DUPLEX_FULL; ... }
Thanks and regards,
Pradeep
Hi Pradeep,
Thank you for your detailed explanation; let me add some details. Currently, our product board only has one RTL8363NB-V connected to the AM2431. The communication interfaces between them are only MDC/MDIO and RGMII. I have already done the following things:
I based this on the "Enet Layer 2 CPSW Example" and after running it, I saw the following content on the console:
[MAIN_Cortex_R5_0_0] ========================== Layer 2 CPSW Test ========================== Init all peripheral clocks ---------------------------------------------- Enabling clocks! Create RX tasks ---------------------------------------------- cpsw-3g: Create RX task Open all peripherals ---------------------------------------------- cpsw-3g: Open enet EnetAppUtils_reduceCoreMacAllocation: Reduced Mac Address Allocation for CoreId:1 From 4 To 2 Init all configs ---------------------------------------------- cpsw-3g: init config Mdio_open: MDIO Manual_Mode enabled cpsw-3g: Open port 1 Attach core id 1 on all peripherals ---------------------------------------------- cpsw-3g: Attach core cpsw-3g: Open DMA initQs() txFreePktInfoQ initialized with 16 pkts cpsw-3g: Waiting for link up...
As shown above, the console stops at "cpsw-3g: Waiting for link up...". It seems to me that it does not recognize the PHY. In debug mode, I found that the PHY driver I wrote was not executed. At line 313 in enetphy.c, there is a conditional statement that appears to confirm whether the PHY is alive through MDC/MDIO. Since it does not pass this conditional, the function EnetPhy_blindDriver, which would bind my PHY driver, is not executed. Strangely, when I deselect the MDC and MDIO signals in Enet(CPSW) -> Pinmux config, this conditional statement succeeds and EnetPhy_blindDriver is executed, allowing my PHY driver to run.
Finally, after studying the SDK code, I found that control over MDIO requires using IOCTL macros. However, the RTL8363NB-V requires me to write values to its registers through MDIO for initialization settings. Could you please share how exactly this should be done? Thank you!
Hi Larry,
- In syscfg, under Enet(CPSW) -> MAC Port Config -> MAC Port2 Config, I disabled Mac Port 2.
- In syscfg, under Enet(CPSW) -> Pinmux config, I deselected the RGMII2 signal.
- I also followed the SDK instructions to create a custom_board_config.c and a PHY driver.
This is the correct and right way to do it.
Regarding "cpsw-3g: Waiting for link up..."
Few followup questions-
Regarding -
Finally, after studying the SDK code, I found that control over MDIO requires using IOCTL macros. However, the RTL8363NB-V requires me to write values to its registers through MDIO for initialization settings. Could you please share how exactly this should be done?
It is not allowed / suggested to write the PHY registers directly from application. PHY registers read or write should happen only from 'my-phy-driver'.
If you have followed - https://software-dl.ti.com/mcu-plus-sdk/esd/AM243X/latest/exports/docs/api_guide_am243x/enetphy_guide_top.html#enetphy_guide_implementing
EnetPhy_Drv gEnetPhyDrvMyDrv = { .name = "My PHY driver", .isPhyDevSupported = MyPhy_isPhyDevSupported, .isMacModeSupported = MyPhy_isMacModeSupported, .config = MyPhy_config, .reset = MyPhy_reset, .isResetComplete = MyPhy_isResetComplete, .runComplianceTest = NULL, .readExtReg = GenericPhy_readExtReg, .writeExtReg = GenericPhy_writeExtReg, .printRegs = MyPhy_printRegs, };
EnetPhy_readReg(hPhy, PHY_REG_ADDRESS, &val); // to read a PHY register EnetPhy_writeReg(hPhy, PHY_REG_ADDRESS, val); // to write a PHY register
PS: If you still need to write/read PHY registers from application (bypassing enet-lld driver), then you can use the refer to below code-
// read a phy register void App_readPhyRegister() { Enet_IoctlPrms prms; EnetMdio_C22ReadInArgs inArgs; int32_t status = -1; uint16_t val; // register read value inArgs.group = ENET_MDIO_GROUP_0; // set to group 0 inArgs.phyAddr = phyAddr; // your phy address inArgs.reg = reg; // your phy regiser ENET_IOCTL_SET_INOUT_ARGS(&prms, &inArgs, &val); ENET_IOCTL(hEnet, EnetSoc_getCoreId(), ENET_MDIO_IOCTL_C22_READ, &prms, status); DebugP_assert(status == ENET_SOK); } // write a phy register void App_writePhyRegister() { Enet_IoctlPrms prms; EnetMdio_C22WriteInArgs inArgs; int32_t status = -1; inArgs.group = ENET_MDIO_GROUP_0; // set to group 0 inArgs.phyAddr = phyAddr; // your phy address inArgs.reg = reg; // your phy register address inArgs.val = val; // Value to be written in the phy register address ENET_IOCTL_SET_IN_ARGS(&prms, &inArgs); ENET_IOCTL(hEnet, EnetSoc_getCoreId(), ENET_MDIO_IOCTL_C22_WRITE, &prms, status); DebugP_assert(status == ENET_SOK); }
Pradeep
Hi Pradeep,
My SDK version is mcu_plus_sdk_am243x_09_00_00_35.
I defined in my custom_board_config.c.
The RTL8363NB-V is an Ethernet switch IC. We have connected to the PHY of the RTL8363 via RGMII. The other two ports are used as external communication interfaces for our product. The address is currently set to 0.
Additionally, I'd like to ask if your suggestion for implementing ExternalPhyManagement involves using my custom-defined PHY status to force the driver to directly connect to the PHY. This means disregarding the order of the state machine for PHY defined in Enetphy.c for confirmation, right?
Best regards,
Larry
Hi Larry,
Regarding-
Additionally, I'd like to ask if your suggestion for implementing ExternalPhyManagement involves using my custom-defined PHY status to force the driver to directly connect to the PHY. This means disregarding the order of the state machine for PHY defined in Enetphy.c for confirmation, right?
Yes, you are right. ExternalPhyManagement shall by pass the internal statemachine defined in enetphy.c and you may have to implement this in your externalPhyManagement implementation on more custom phy management as per your need.
About -
The RTL8363NB-V is an Ethernet switch IC. We have connected to the PHY of the RTL8363 via RGMII. The other two ports are used as external communication interfaces for our product. The address is currently set to 0.
Is '0'a valid address of the PHY that you are using. You may have to check the datasheet of RTL8363NB-V to confirm this. If phy address is not the right one, then you may face issues related to phy communication (such alive, linked, read, write, etc)
With regards,
Pradeep
Hi Pradeep,
I want to confirm whether the PHY address and PHY id are the same. According to the datasheet for the RTL836, my current hardware setup has set the PHY id to 0. I have also tried setting the MDC and MDIO pins as general GPIOs to emulate MDIO/MDC behavior, successfully initializing the RTL8363 through this simulation. Therefore, I believe there is no issue with this PHY id.
As shown in the diagram above, when I simulate MDIO communication through GPIO, I set the PHYAD position in the diagram to 0 for initializing the RTL8363. If the content of the PHY id was incorrect, my initialization would fail. However, the result is that I successfully completed the initialization of the RTL8363. Therefore, I want to confirm if there is a misunderstanding in our perception of the PHY address.
Best regard,
Larry
HI LArry,
Thanks for these details. Your understanding is correct and it should be find in setting phy ID (i.e. PHYAD ) to '0' as per your hardware setup.
Thanks and regards,
Pradeep
Hi Pradeep,
I attempted to integrate the example code you mentioned, 'examples/networking/lwip/enet_lwip_cpsw', into my current program, but encountered a problem in one of the sections.
static void EnetApp_waitForPhyAlive(Enet_Type enetType, uint32_t instId, uint32_t coreId, Enet_MacPort macPort) { bool alive = 1; Enet_IoctlPrms prms; int32_t status = 1; Enet_Handle hEnet = Enet_getHandle(enetType, instId); uint32_t phyAddr; EnetBoard_EthPort ethPort; const EnetBoard_PhyCfg *boardPhyCfg; EnetAppUtils_assert(hEnet != NULL); /* Setup board for requested Ethernet port */ ethPort.instId = instId; ethPort.macPort = macPort; ethPort.boardId = EnetBoard_getId(); ethPort.enetType = enetType; ethPort.mii.layerType = ENET_MAC_LAYER_GMII; ethPort.mii.sublayerType = ENET_MAC_SUBLAYER_REDUCED; ethPort.mii.variantType = ENET_MAC_VARIANT_FORCED; boardPhyCfg = EnetBoard_getPhyCfg(ðPort); EnetAppUtils_assert(boardPhyCfg != NULL); phyAddr = boardPhyCfg->phyAddr; do { ENET_IOCTL_SET_INOUT_ARGS(&prms, &phyAddr, &alive); ENET_IOCTL(hEnet, coreId, ENET_MDIO_IOCTL_IS_ALIVE, &prms, status); } while ((status == ENET_SOK) && (alive != true)); EnetAppUtils_assert (status == ENET_SOK); }
In this function, it appears that MDIO continuously fails to detect the PHY alive, preventing the loop from being exited. I'm curious about the underlying implementation: how does it determine the non-existence of the PHY? I need to ascertain if the issue stems from my coding approach, specifically if incorrect initial setup previously is leading to this failure in detection. Below, I provide the content of other parameters for further reference.
ethPort.instId = 0
ethPort.macPort = ENET_MAC_PORT_FIRST
ethPort.boardId = 3
ethPort.enetType = ENET_CPSW_3G
phyAddr = 0
Could you please help me identify where the problem lies?
Best regards,
Larry
Hi Larry,
About -
I'm curious about the underlying implementation: how does it determine the non-existence of the PHY?
Implementation depends on MDIO operating mode that is selected in syscfg-gui;
On AM243x, out of box examples are configured with MDIO_MODE_MANUAL mode. To debug the issue, can you try changing MDIO mode to MDIO_MODE_STATE_CHANGE_MON in syscfg-gui and tick all the PHY address in monitored PHY address? You may reduce the MDCLK Frequency to a lower value say, 200 KHz, to overcome any PCB track issues on MDIO-CLK lines.
Let me know the results of 'EnetApp_waitForPhyAlive' with above changes.
About-
Could you please help me identify where the problem lies?
You had mentioned earlier that you had to untick MDC and MDIO in syscfg-gui pinmux setting:
Since it does not pass this conditional, the function EnetPhy_blindDriver, which would bind my PHY driver, is not executed. Strangely, when I deselect the MDC and MDIO signals in Enet(CPSW) -> Pinmux config, this conditional statement succeeds and EnetPhy_blindDriver is executed, allowing my PHY driver to run.
I don't think this is right way to do, we need to use MDC and MDIO signals. Else, SOC cannot communicate with PHY using MDIO lines. You may have to debug why 'EnetPhy_blindDriver' has failed when you use these signals in pinmux.
Thanks and regards,
Pradeep
A side note, you can run the below function to confirm the PHYs that are setup.
static void EnetApp_scanPhy(Enet_Type enetType, uint32_t instId, uint32_t coreId) { EnetMdio_C22ReadInArgs inArgs; Enet_IoctlPrms prms; Enet_Handle hEnet = Enet_getHandle(enetType, instId); uint32_t phyAddr; while (1) { int32_t status = -1; DebugP_logInfo(">>> Scan Start\r\n"); for (phyAddr = 0; phyAddr < 32; phyAddr++) { uint16_t val = 0; inArgs.group = ENET_MDIO_GROUP_0; inArgs.phyAddr = phyAddr; inArgs.reg = reg; ENET_IOCTL_SET_INOUT_ARGS(&prms, &inArgs, &val); ENET_IOCTL(hEnet, coreId, ENET_MDIO_IOCTL_C22_READ, &prms, status); if (ENET_SOK != status) { DebugP_logInfo("PHY NOT FOUND at address: %d\r\n", phyAddr); } else { DebugP_logInfo("PHY FOUND at address: %d\r\n", phyAddr); } ClockP_usleep(100000); // sleep for 100 m-sec } } return; }
Pradeep
Hi Pradeep,
I tried the EnetApp_scanPhy function you provided, but it failed. Here is the content of the log: Below,
Mdio_manual_ioctl_handler_ENET_MDIO_IOCTL_C22_READ: failed to read PHY 0 C22 reg 4864: -1 EnetMod_ioctl: cpsw3g.mdio: Failed to do IOCTL cmd 0x01000605: -1 EnetPer_ioctl: cpsw3g: Failed to do IOCTL cmd 0x01000605: -1 Enet_ioctl: cpsw3g: IOCTL 0x01000605 failed: -1
enetType = ENET_CPSW_3G
instId = 0
coreId = 1
Additionally, I tried modifying the content of inArgs.group = ENET_MDIO_GROUP_0, replacing it with ENET_MDIO_GROUP_1 and ENET_MDIO_GROUP_NUM, but still, all attempts failed.
This attempt to read the register content should be the switch IC's chip number, but it's clear it cannot be read. Is this Clause-22 frame consistent with the MDIO structure shown in the PHY id image I previously asked you about?
Best regards,
Larry
As an additional point, I attempted to write values to MDC/MDIO. Using a Logic analyzer to monitor the MDC and MDIO pins, I noticed that these two pins showed no activity at all. Could it be possible that there is an issue with my initial setup?
Below is my test code,
static void EnetApp_writeMagicId(Enet_Type enetType, uint32_t instId, uint32_t coreId) { EnetMdio_C22WriteInArgs inArgs; Enet_IoctlPrms prms; Enet_Handle hEnet = Enet_getHandle(enetType, instId); uint32_t phyAddr = 0; //while (1) { int32_t status = -1; EnetAppUtils_print(">>> Write Start\r\n"); //for (phyAddr = 0; phyAddr < 32; phyAddr++) { uint16_t val = 0; inArgs.group = ENET_MDIO_GROUP_0; inArgs.phyAddr = phyAddr; inArgs.reg = 0x13c2; inArgs.val = 0x0249; ENET_IOCTL_SET_IN_ARGS(&prms, &inArgs); ENET_IOCTL(hEnet, coreId, ENET_MDIO_IOCTL_C22_WRITE, &prms, status); if (ENET_SOK != status) { EnetAppUtils_print("PHY write at address: %d fail\r\n", phyAddr); } else { EnetAppUtils_print("PHY write at address: %d success\r\n", phyAddr); } ClockP_usleep(100000); // sleep for 100 m-sec } } return; }
Hi Larry,
On:
Is this Clause-22 frame consistent with the MDIO structure shown in the PHY id image I previously asked you about?
Yes, MDIO frame structure that you had mentioned earlier is indeed a clause-22 type
ref: https://en.wikipedia.org/wiki/Management_Data_Input/Output#Bus_timing_(clause_22)
About:
I tried the EnetApp_scanPhy function you provided, but it failed.
Using a Logic analyzer to monitor the MDC and MDIO pins, I noticed that these two pins showed no activity at all. Could it be possible that there is an issue with my initial setup?
Pradeep
Hi Pradeep,
Did you check the MDC and MDIO signals pinmux settings. I think you had disabled this as per your initial comment. Without these signal pins set, you will not see any signal on the wire/scope. Please keep it set.
Also, please try with mdio operation mode as MDIO_MODE_STATE_CHANGE_MON s suggested earlier till we understand the current issue.
As indicated, I have confirmed that the MDC and MDIO functions have not been disabled and are enabled in the CPSW pinmux.
I also followed your suggestion and set the MDIO config's operation mode to MDIO_MODE_STATE_CHANGE_MON, with the frequency set to 200KHz and the address set to all.
However, when I attempted to write values to the PHY's register,
static void EnetApp_writeMagicId(Enet_Type enetType, uint32_t instId, uint32_t coreId) { EnetMdio_C22WriteInArgs inArgs; Enet_IoctlPrms prms; Enet_Handle hEnet = Enet_getHandle(enetType, instId); uint32_t phyAddr = 0; //while (1) { int32_t status = -1; EnetAppUtils_print(">>> Write Start\r\n"); //for (phyAddr = 0; phyAddr < 32; phyAddr++) { uint16_t val = 0; inArgs.group = ENET_MDIO_GROUP_0; inArgs.phyAddr = phyAddr; inArgs.reg = 0x13c2; inArgs.val = 0x0249; ENET_IOCTL_SET_IN_ARGS(&prms, &inArgs); ENET_IOCTL(hEnet, coreId, ENET_MDIO_IOCTL_C22_WRITE, &prms, status); if (ENET_SOK != status) { EnetAppUtils_print("PHY write at address: %d fail\r\n", phyAddr); } else { EnetAppUtils_print("PHY write at address: %d success\r\n", phyAddr); } ClockP_usleep(100000); // sleep for 100 m-sec } } return; }
I observed the process getting stuck in the following function:
DId you confirm RTL8363NB configuratation is set in MDIO mode for PHY Management Interface and not is I2C mode?
I have confirmed that the RTL8363 is in MDIO mode, as I have indeed used GPIO to simulate MDIO behavior and was able to initialize the RTL8363.
Did you confirm that you have external pull-up resistors on MDIO clock and MDIO data lines on your board?
We have added a pull-up resistor on the MDIO pin.
Best regards,
Larry
I observed the process getting stuck in the following function:
It could happen if MDIO is not initialized.
Can you confirm that MDIO_open() is executed, using debugger? Please verify the MDIO confirg parameters received in the Mdio_Open() call?
Moreover, please continue using MDIO mode as STATE_CHANGE_MON until we root this issue.
With regards,
Pradeep
In debug mode, I have confirmed that Mdio_open() is executed. Here are the values of the parameters passed in:
Mdio_Handle hMdio = (Mdio_Handle)hMod;
enetType = ENET_CPSW_3G
instId = 0
const Mdio_Cfg *mdioCfg = (const Mdio_Cfg *)cfg;
cfgSize = 24
Best regards,
Larry
Thanks for the details!
I am sorry that I need to ask you some more questions:
With regards,
Pradeep
Can you also share the complete/exact part number of AM243x SOC used in your board?
AM2431BSDGHIALXR
Does MDIO Clause 22 register read is also stuck with STATE_CHANGE_MON mode?
The read operation also gets stuck, but this happens in the CSL_MDIO_phyRegRead2 function.
Any changes that you did in the application code with respect to out of box example? Are you using TI delivered SBL or are there any change in SBL?
Since I have enabled 'Custom Board', I added a custom_board_config.c file. If needed, I can attach the contents of this .c file.
As our custom board uses a different brand of external flash, and I'm using uart_uniflash.py to flash the Secondary Boot Loader (SBL), I modified the contents of sbl_uart_uniflash following the SDK guidelines to allow the flashing of a second SBL. This second SBL is a modification of the default_sbl_null. The original process is designed for initialization on the LP-AM243x, but the LP board's AM243 has four cores, whereas our board's AM2431 has only one core, so I only initialized a single core. Here are the modifications I made:
DebugP_log("\r\n"); DebugP_log("Starting NULL Bootloader ... \r\n"); status = Sciclient_getVersionCheck(1); if(status == SystemP_SUCCESS) { Bootloader_Params bootParams; Bootloader_BootImageInfo bootImageInfo; Bootloader_Handle bootHandle; Bootloader_Params_init(&bootParams); /* set default which will basically allow to simply power on reset the CPU and run a while(1) loop */ Bootloader_BootImageInfo_init(&bootImageInfo); bootHandle = Bootloader_open(CONFIG_BOOTLOADER0, &bootParams); if(bootHandle != NULL) { uint32_t coreVariant = Bootloader_socGetCoreVariant(); // if((coreVariant == BOOTLOADER_DEVICE_VARIANT_QUAD_CORE) || (coreVariant == BOOTLOADER_DEVICE_VARIANT_DUAL_CORE)) // { // if(status == SystemP_SUCCESS) // { // status = Bootloader_bootCpu(bootHandle, &bootImageInfo.cpuInfo[CSL_CORE_ID_R5FSS1_0]); // } // if((Bootloader_socIsR5FSSDual(BOOTLOADER_R5FSS1) == TRUE) && (status == SystemP_SUCCESS)) // { // status = Bootloader_bootCpu(bootHandle, &bootImageInfo.cpuInfo[CSL_CORE_ID_R5FSS1_1]); // } // } /* Do not boot M4 when MCU domain is reset isolated */ if (!Bootloader_socIsMCUResetIsoEnabled()) { if(status == SystemP_SUCCESS) { status = Bootloader_bootCpu(bootHandle, &bootImageInfo.cpuInfo[CSL_CORE_ID_M4FSS0_0]); } } if(status == SystemP_SUCCESS) { /* Reset self cluster, both Core0 and Core 1. Init RAMs and run dummy loop */ //status = Bootloader_bootSelfCpu(bootHandle, &bootImageInfo); /* Initial Core0 */ uint32_t isSelfBoot = FALSE; if(TRUE == Bootloader_isCorePresent(bootHandle, CSL_CORE_ID_R5FSS0_0)) { isSelfBoot = TRUE; } bootImageInfo.cpuInfo[CSL_CORE_ID_R5FSS0_0].clkHz = Bootloader_socCpuGetClkDefault(CSL_CORE_ID_R5FSS0_0); status = Bootloader_loadSelfCpu(bootHandle, &bootImageInfo.cpuInfo[CSL_CORE_ID_R5FSS0_0], FALSE); if(status == SystemP_SUCCESS) { status = Bootloader_runSelfCpu(bootHandle, &bootImageInfo); } } /* it should not return here, if it does, then there was some error */ Bootloader_close(bootHandle); } }
Best regards,
Larry
AM2431BSDGHIALXR
Thanks for this. Just wanted to confirm the pin number used. Looks correct.
Can you please try one more thing - There was an MDIO driver bug fixed on 09.01 SDK. This bug is applicable only to Manual mode though. Since MDIO operations are not getting success I an think that MDIO module clock probably is not set.
Patch is here - https://github.com/TexasInstruments/mcupsdk-enet-lld/commit/34ad60f9035633eaebdbe33d57bb19c32bd93717
Can you apply the above change in your workspace and re-run the tests in MDIO MODE = MDIO_MODE_MANUAL?
With regards,
Pradeep
Since MDIO operations are not getting success I an think that MDIO module clock probably is not set.
Are you suggesting that there might be an issue with my initialization settings, which could have led to the MDIO clock not being properly initialized? If so, what part might need to be modified?
Can you apply the above change in your workspace and re-run the tests in MDIO MODE = MDIO_MODE_MANUAL?
Yes, I have already changed the MDIO_MODE to MDIO_MODE_MANUAL, and I have also incorporated the changes from the link into the SDK modifications. However, does this only involve adding a preamble before sending MDIO messages?
After making these modifications, I still don't see any MDIO messages being transmitted when observed through the Logic Analyzer, whether for writing or reading data.
Best regards,
Larry
Hi Pradeep,
I've realized that MDIO is actually functioning; it was just an error in the parameter settings of my Logic Analyzer (LA) that prevented the trigger from activating, for which I apologize.
However, I noticed that the MDIO does not send the 32-bit high preamble as shown in the diagram below:
I have indeed made the modifications in the SDK as you mentioned. Is there any additional action needed after adding those two lines of code to ensure the SDK correctly executes the newly added part?
Best regards,
Larry
Hi Larry,
Thanks for sharing this.
You have to recompile the libraries for changes to take into effect.
Please follow below steps to re-compile the libraries
cd <mcu_plus_sdk_intall_dir> gmake -s -j4 DEVICE=am243x PROFILE=debug libs-clean gmake -s -j4 DEVICE=am243x PROFILE=debug libs gmake -s -j4 DEVICE=am243x PROFILE=release libs-clean gmake -s -j4 DEVICE=am243x PROFILE=release libs
Then re-compile and run the example/application.
With regards,
Pradeep
Hi Larry,
Please note that bellow issue is fixed on latest MCU+ SDK version Version: 09.01.00.41 (Release date: 13 Dec 2023).
With regards,
Pradeep
Hi Pradeep,
Thank you for your detailed reply. I have already replaced the SDK version with mcu_plus_sdk_am243x_09_01_00_41, and upgraded the SysConfig version to sysconfig_1.18.1. Now, I can see from the Logic Analyzer that the MDIO operations are functioning as expected.
However, the ENET_MDIO_IOCTL_IS_ALIVE still cannot be used. I think it's because our switch IC has a unique control method. Reading the PHY register requires four steps:
Therefore, if ENET_MDIO_IOCTL_IS_ALIVE attempts to directly read from the PHY, it fails and cannot pass the conditional check. That's why I removed the parts concerning MDIO read and write in the subsequent code. Thus, the initialization part is now complete, but I still can't read the contents of RGMII.
We have attempted to use an oscilloscope to observe the TX pin of RTL8363. After completing the initialization of RTL8363, we can see that the TX pin is continuously outputting data, as we have another device continuously sending out Ethernet raw packets. However, inside the AM2431, in debug mode, I can't see any data entering the DMA, so the rxTask is never triggered, and thus, we can't receive the raw packets sent by RTL8363. Could you advise which areas I should check to resolve this issue? Thank you!!
Best regards,
Larry
HI Larry,
Great to see that you are able to read or write into PHY registers.
Therefore, if ENET_MDIO_IOCTL_IS_ALIVE attempts to directly read from the PHY, it fails and cannot pass the conditional check. That's why I removed the parts concerning MDIO read and write in the subsequent code. Thus, the initialization part is now complete, but I still can't read the contents of RGMII.
thanks for this update!
About-
Could you advise which areas I should check to resolve this issue? Thank you!!
There could be few things we need to check first-
With regards,
Pradeep
Hi Pradeep,
Do you see a link-up event?
No, I added breakpoints in cpsw.c, and whether it's V1 or V2, I did not observe Cpsw_handleLinkUp() being executed. Nor did I see Cpsw_periodicTick() running. It appears that in the driver, Cpsw_periodicTick() needs to be executed to have the opportunity to run Cpsw_handleLinkUp(), right?
You may see CPSW statistics to check number of packets received or transmitted by CPSW HW peripheral using gel scripts?
After executing the gel scripts you mentioned, the log shows the following, which seems to indicate that the CPSW was not started at all, correct?
Is it possible that this phenomenon is caused by my failure to execute some function? My current procedure is still fundamentally based on the 'Enet Layer 2 CPSW Example'. I have incorporated the 'mcu_plus_sdk/examples/networking/lwip/enet_lwip_cpsw/extPhyMgmt' part about external PHY management, as you previously mentioned, into my program. However, I have not included any parts related to lwip. Could this be the primary reason why the CPSW has not started?
Best regards,
Larry
Hi Pradeep,
I noticed in the external PHY management example code that I did not execute EnetApp_createPhyRegisterPollingTask(). Inside, there is an IOCTL command: ENET_IOCTL_SET_IN_ARGS(&prms, &linkupEventInfo); ENET_IOCTL(hEnet, selfCoreId, ENET_PER_IOCTL_HANDLE_EXTPHY_LINKUP_EVENT, &prms, status); I'm guessing its function is similar to what you mentioned with CPSW_MACPORT_IOCTL_ENABLE, right? Because after executing it, the log showed the following content:
Does this indicate a link-up event?
Additionally, after running the gel scripts again, I still can't see an output similar to what your link displayed.
Best regards,
Larry
Hi Larry,
In the lo yourut sharedby you, there are failures related to MDIO reads
EnetPhy_rmwreg: PHY 0 : FAILED to read reg0: -3
Did you try to solve this?
I am suspecting MAC port configurations.
Thanks and regards,
Pradeep
Hi Pradeep,
Did you try to solve this?
Yes, I have already resolved this error.
Which CPSW MAC port is connected to "RTL8363NB-V" out of PORT1 and PORT2?
I believe it is connected to Port 1. On the hardware side, I am connected to the pins of RGMII1, as shown in the following diagram.
In the program, I have set it to connect to ENET_MAC_PORT_1. I'm not sure if you are referring to the hardware port or the MAC port? I have also tried adding ENET_MAC_PORT_2 in the program, but it failed. I will try again.
Can you try to interchange the port using syscfg-gui to see if there are different results (try to disable other port)?
I have already disabled Mac Port 2 in the original syscfg. I will try switching to using Mac Port 2 to see if there is a chance to make it work.
Can you try to enable both the MAC ports of CPSW in syscfg-gui tool and see if there are any change in the statistics?
It seems the result is the same as before; there is no difference.
Can you compare the CPSW MAC Port registers setting between working board (TI-LP Board) and not working setup (custom board)?
Did you interchanging PORT or RGMII?
Additionally, are there other parts that I could try modifying? Below are some register settings that I have found so far, which I believe meet my current needs, but I am still unable to communicate with the switch IC.
CPSW_SS_RGMII1_STATUS_REG
FULLDUPLEX = 1h = Full-duplex
SPEED = 10 = 2h = 1000Mbps
LINK = 1h = Link is up
CPSW_STAT_PORT_EN_REG
P2_STAT_EN = 1h = Port 2 statistics are enabled.
P1_STAT_EN = 1h = Port 1 statistics are enabled.
P0_STAT_EN = 1h = Port 0 statistics are enabled.
CTRLMMR_ENET1_CTRL
PORT_MODE_SEL = 010 = 2h - RGMII
CTRLMMR_CPTS_CLKSEL
CPTS_CLKSEL_CPTS_CLKSEL = 0h = MAIN_PLL2_HSDIV5_CLKOUT
Regarding the feasibility of connecting the AM-243 to a switch IC, my understanding is that if the MAC inside the AM-243 is configured correctly, then as long as the PHY on the switch IC side is initialized, communication should be possible. Is there a chance for us to engage in more detailed communication? This feature is quite important for our product.
Best regards,
Larry
Hi Larry,
We have attempted to use an oscilloscope to observe the TX pin of RTL8363.
Did you try to measure clock frequency of TX_CLK on RGMII interface? Is it matching as per RGMII spec of 125MHz?
With regards,
Pradeep
Hi Pradeep,
I attempted to add a task to continuously send packets to the RTL8363. It was observed that the packets were successfully sent. We verified through Wireshark that the packets were indeed transmitted in the format I designed. However, the data sent from the RTL8363 to the AM2431, specifically the RX of AM2431, still couldn't be received. Could there be any settings that might cause this issue?
Is it possible that the issue arises because the packets we are sending are broadcast packets? The MAC address is 0xFF:0xFF:0xFF:0xFF:0xFF:0xFF. Do we need to enable something in a specific register?
Because I saw a register in the Registers list on CCS as follows:
Based on the datasheet description, it appears to be related to broadcast. Is there a similar register that needs to be configured?
Additionally, have you received the firmware I sent you? Also, our Electrical Engineer (EE) has emailed you our circuit diagram. Could you please contact your EE to help review the circuit for any flaws? Thank you!
Best regards,
Larry
HI LArry,
About:
I attempted to add a task to continuously send packets to the RTL8363. It was observed that the packets were successfully sent.
What is the voltage level observed on AM2431 Tx side ?
About schematics analysis, let me follow this with TI EE and share you the update.
Thanks and regards,
Pradeep
Hi Pradeep,
Thank you for your detailed assistance and explanation. We have identified the issue. It was due to a rework causing continuous failure in the RGMII. Our Electrical Engineer (EE) carefully re-examined and resolved the issue. Thank you!!
Best regards,
Larry
Thanks Larry, for the confirmation! Glad to see that issue is resolved!
With regards,
Pradeep