2024-10-24 08:36 AM - last edited on 2024-10-24 10:16 AM by SofLit
Hello everyone,
I'm currently using Nucleo-H743ZI2 but this aim to go on a custum PCB. LWIP (2.1.2) is activated without FREERTOS and my TCP server is working. I'm also using HAL function with CubeIDE (1.16.1). And I'm using an Aruba 2530-8G switch to visualize the Speed and Duplex Mode
But I'm having issues with the LAN8742A. Especially with the Duplex Mode of the LAN8742. I can't manage to make the duplex mode to Full Duplex . I already manage the speed and autonegociation well, but the Full Duplex mode is not working without AutoNegociation.
What I did in order to manually configure the LAN8742 ?
- Writing in the SMR (Special Modes Register) of the LAN8742 which mode I wanted (Bit 5->7)
- Writing in the BCR (Basic Control Register) of the LAN8742 the speed (Bit 13), the Auto-Negotiation (Bit 12), and the Duplex Mode (Bit 8)
- Specify the Link State via lan8742.c function given by ST
// Function that write the configuration for the LAN8742
void appMain_initLAN8742(void) {
// Read the current mode configuration
LAN8742.IO.ReadReg(LAN8742.DevAddr, LAN8742_SMR, &readWriteVal);
readWriteVal |= (1 << 5) | (1 << 6); // Change mode to 011 AKA AKA 100BASE-TX Full Duplex
readWriteVal &= ~((1 << 7)); // Change mode to 011 AKA AKA 100BASE-T Full Duplex
// Writing in SMR (Special Mode Register) the mode that we want
rc = LAN8742.IO.WriteReg(LAN8742.DevAddr, LAN8742_SMR, readWriteVal);
// Read current value in register
LAN8742.IO.ReadReg(LAN8742.DevAddr, LAN8742_BCR, &writeVal);
// Deactivate AutoNegoce
writeVal = (writeVal & ~(1 << 12));
// Set Speed to 100Mb
writeVal = (writeVal | (1 << 13));
// Set DuplexMode to Full Duplex
writeVal = (writeVal | (1 << 8));
// Writing in BCR the speed, Duplex and AutoNegoce
rc = LAN8742.IO.WriteReg(LAN8742.DevAddr, LAN8742_BCR, writeVal);
printf("[appMain_initLAN8742] - Writing LAN8742 : %s\n", (rc == 0) ? "SUCCESS" : "FAIL");
// Specify the Link State via lan8742.c function given by ST
rc = LAN8742_SetLinkState(&LAN8742, LAN8742_STATUS_100MBITS_FULLDUPLEX);
if (rc != LAN8742_STATUS_OK) // Error Case
printf("[appMain_handleLAN8742] - ERROR in LAN8742_SetLinkState()\n");
}
// Function that print value from LAN8742 register (BCR, PHYSCR, SMR)
void appMain_logLAN8742(void) {
static uint32_t tickDebug = 0;
char duplexMode = 0;
uint32_t readBCRVal = 0, readPHYSCSRVal = 0, readSMR = 0, speed = 0, tmpVar = 0;
char speedIndicator[25] = { 0 };
char speedIndicator2[25] = { 0 };
char modeIndicator[30] = { 0 };
bool autoDone = false;
int32_t PHYLinkState = 0;
bool autoNegoce, speedBool, duplexModeBool, restartAutoNegoce, softReset, powerDown, loopBack;
LAN8742.IO.ReadReg(LAN8742.DevAddr, LAN8742_BCR, &readBCRVal);
LAN8742.IO.ReadReg(LAN8742.DevAddr, LAN8742_PHYSCSR, &readPHYSCSRVal);
LAN8742.IO.ReadReg(LAN8742.DevAddr, LAN8742_SMR, &readSMR);
autoDone = (readPHYSCSRVal & (1 << 12)) ? true : false;
tmpVar = (readPHYSCSRVal >> 2) & 0x7; // Extract only 2->4 bit.
// Parse PHY STATUS CONTROL Regster
if (tmpVar == 0b001) {
strncpy(speedIndicator, "10BASE-T HalfDuplex", sizeof(speedIndicator) - 1);
} else if (tmpVar == 0b010) {
strncpy(speedIndicator, "100BASE-T HalfDuplex", sizeof(speedIndicator) - 1);
} else if (tmpVar == 0b101) {
strncpy(speedIndicator, "10BASE-T FullDuplex", sizeof(speedIndicator) - 1);
} else if (tmpVar == 0b110) {
strncpy(speedIndicator, "100BASE-T FullDuplex", sizeof(speedIndicator) - 1);
} else {
strncpy(speedIndicator, "Unknown Duplex", sizeof(speedIndicator) - 1);
}
autoNegoce = (readBCRVal & (1 << 12)) ? true : false;
speedBool = (readBCRVal & (1 << 13)) ? true : false;
speed = speedBool == 1 ? 100 : 10;
duplexModeBool = (readBCRVal & (1 << 8)) ? true : false;
duplexMode = duplexModeBool == 1 ? 'F' : 'H';
restartAutoNegoce = (readBCRVal & (1 << 9)) ? true : false;
softReset = (readBCRVal & (1 << 15)) ? true : false;
powerDown = (readBCRVal & (1 << 11)) ? true : false;
loopBack = (readBCRVal & (1 << 11)) ? true : false;
// Parse Special Modes Register
tmpVar = (readSMR >> 5) & 0x7;
if (tmpVar == 0b000) {
strncpy(modeIndicator, "10BASE-T HalfDuplex", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b001) {
strncpy(modeIndicator, "10BASE-T FullDuplex", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b010) {
strncpy(modeIndicator, "100BASE-T HalfDuplex", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b011) {
strncpy(modeIndicator, "100BASE-T FullDuplex", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b100) {
strncpy(modeIndicator, "100BASE-T HalfDuplex (AN)", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b101) {
strncpy(modeIndicator, "100BASE-T HalfDuplex (AN)", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b110) {
strncpy(modeIndicator, "PowerDown Mode", sizeof(modeIndicator) - 1);
} else if (tmpVar == 0b111) {
strncpy(modeIndicator, "All Capable (AN)", sizeof(modeIndicator) - 1);
} else {
strncpy(speedIndicator, "Unknown Duplex", sizeof(speedIndicator) - 1);
}
// Parse LAN8742_GetLinkState()
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
if (PHYLinkState == 5) {
strncpy(speedIndicator2, "10Mb HD", sizeof(speedIndicator2) - 1);
} else if (PHYLinkState == 4) {
strncpy(speedIndicator2, "10Mb FD", sizeof(speedIndicator2) - 1);
} else if (PHYLinkState == 3) {
strncpy(speedIndicator2, "100Mb HD", sizeof(speedIndicator2) - 1);
} else if (PHYLinkState == 2) {
strncpy(speedIndicator2, "100Mb FD", sizeof(speedIndicator2) - 1);
} else {
strncpy(speedIndicator2, "Error in LINK", sizeof(speedIndicator2) - 1);
}
if ((HAL_GetTick() - tickDebug) > TICK_LOG_LAN8742) {
tickDebug = HAL_GetTick();
printf("############## LOG START ##############\n");
printf(
"[appMain_logLAN8742] - [BCR] Restart AutoNegotiate : %d, AutoNegoce : %d, DuplexMode : %c, Speed : %ld, SoftReset : %d, powerDown : %d, LoopBack : %d\n",
restartAutoNegoce, autoNegoce, duplexMode, speed, softReset, powerDown, loopBack);
printf("[appMain_logLAN8742] - [PHYSCSR] AutoDone : %d, Speed Indication : %s (%ld), SI2 : %s \n", autoDone,
speedIndicator, tmpVar, speedIndicator2);
printf("[appMain_logLAN8742] - [SMR] Mode indicator : %s\n", modeIndicator);
}
}
I also have some code that handles the MACConfig to match the configuration I'm currently in (Speed and DuplexMode).
The weird thing is that my log function for the lan8742 ("appMain_logLAN8742") returns the state that I want (AKA full duplex), even though the switch sees the link as Half Duplex. I also try with an other switch but I had the same result.
Log from appMain_logLAN8742()
############## LOG START ##############
[appMain_logLAN8742] - [BCR] Restart AutoNegotiate : 0, AutoNegoce : 0, DuplexMode : F, Speed : 100, SoftReset : 0, powerDown : 0, LoopBack : 0
[appMain_logLAN8742] - [PHYSCSR] AutoDone : 0, Speed Indication : 100BASE-T FullDuplex (3), SI2 : 100Mb FD
[appMain_logLAN8742] - [SMR] Mode indicator : 100BASE-T FullDuplex
[appMain_logMACConfig] - duplexMode : F, Speed : 100
############## LOG STOP ##############
View of the switch where the nucleo is connected to Port 7
switch(config)# show interfaces brief
Status and Counters - Port Status
| Intrusion MDI Flow
Port Type | Alert Enabled Status Mode Mode Ctrl
----- ---------- + --------- ------- ------ ---------- ---- ----
1 100/1000T | No Yes Down 100FDx MDIX on
2 100/1000T | No Yes Down 1000FDx MDI on
3 100/1000T | No Yes Down 1000FDx MDIX on
4 100/1000T | No Yes Down 1000FDx MDI on
5 100/1000T | No Yes Down 1000FDx MDI on
6 100/1000T | No Yes Down 1000FDx MDIX on
7 100/1000T | No Yes Up 100HDx MDI on
8 100/1000T | No Yes Down 1000FDx MDIX on
9 100/1000T | No Yes Up 1000FDx MDIX on
10 100/1000T | No Yes Up 1000FDx MDI on
I have the same problem for 10Mb Full Duplex and 100Mb Full duplex. I also try with a Soft Reset (Bit 15 from BRC) but didn't work.
Datasheet from LAN8742 : https://ww1.microchip.com/downloads/en/DeviceDoc/DS_LAN8742_00001989A.pdf
2024-10-24 09:13 AM
> Full Duplex mode is not working without AutoNegociation.
AFAIK this is normal. Some time ago I asked about this professional Ethernet engineers and they stated that full duplex works only when auto-negotiated with the peer. I haven't understood the explanation, only the bottom line.
2024-10-24 10:04 AM
Do you have any source or paper that say that ?
2024-10-24 11:39 AM
Unfortunately I don't. But I had this question too, googled a lot and have not found other answers.
2024-10-24 12:03 PM
I forgot to mention, but the switch is in full auto