Showing results for 
Search instead for 
Did you mean: 

ALTCP causes LAN7820 link detection to fail

Senior III

Working with STM32H743IIT single CM7 core MCU I was managed to have a stable product with Ethernet connectivity. Thanks everybody (@Piranha especially) for your advices

Now I was going to implement secure communication over ALTCP instead of regular manual mbedTLS way. It was very promising at the beginning with clean and understandable code... BUT! As soon as I enable ALTCP library in my project by having defined LWIP_ALTCP in lwipopts.h I have a problem:

It works like a charm for some time (from some minutes to couple of days) and then my application looses Ethernet link and gets it back again in a second, but with wrong DUPLEX state (half-duplex instead of full duplex). The problem originates in reading wrong values from LAN7820 link status register and is not related to stack overflow.

The only difference is in this macro. Link fails if ALTCP is enabled even it is not used (just regular clear-text protocol), but works fine with mbedTLS but not through ALTCP.




void ethernet_link_thread(void* argument)
    PHYLinkState = LAN8742_GetLinkState(&LAN8742); <= Wrong link state returned





int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
  pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval);
  pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval);
  pObj->IO.ReadReg(pObj->DevAddr, LAN8742_PHYSCSR, &readval);



Register values:

 Normal operationFailure
BSR0x782D (Auto-negotiation complete)0x780D
BCR0x1100 (Auto-negotiation, FDX)0x0000


So, the registers are clearly show that there is no auto-negotiation after link failure. But it does not explain why could it happen just because of the code like this:


  // fails even if client_info->tls_config == 0
  if (client_info->tls_config) {
    client->conn = altcp_tls_new(client_info->tls_config, IP_GET_TYPE(ip_addr));
  } else
  // Works only if LWIP_ALTCP is undefined
    client->conn = altcp_tcp_new_ip_type(IP_GET_TYPE(ip_addr));
  if (client->conn == NULL) {
    return ERR_MEM;