iMXRT1024 - Ethernet MAC not transmitting data

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

iMXRT1024 - Ethernet MAC not transmitting data

跳至解决方案
2,710 次查看
GUnderdown
Contributor III

I have an RT1024 on a custom board, but the hardware regarding the ethernet and memory is the same. Phy ksz8081, dram IS42S16160-6 at 125MHz. My issue is that for some reason, I never see any data coming out of the MAC over the RMII interface, and as a result, no data is ever transmitted to the network. I receive zero errors regarding this, and the phy registers/configuration matches the SDK example for the given connection (10Mbps half duplex vs 100Mbps full duplex, etc). I am confident that the phy is able to establish a link with the other side of the network, indicated by lights on both ends, and the fact that the link waiting period goes by and passes (see code below). 

Physically, I have verified that there is no data on the TX lines of the RMII, and that the RMII clock output from the CPU is a clean 50MHz (both verified with scope). I have defined "FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE", and like I said earlier, the phy registers match what I would expect.

 

I've also verified that it is not a hardware problem. If I modify the lwip_ping_freertos sdk example to link to RAM (DRAM), it runs perfectly. I have compared the register stacks for the ENET module between my code and the SDK example, and the only differences were the TDAR, MII data register, MIB (which I set to enable the counters), RDSR, and TDSR.

 

My memory map is setup like this:

  • Code/data: SDRAM loaded/copied by uTasker bootloader
  • Stack/Heap: DTCM, which has been resized to take the full 256k on the CPU. Heap size is 64k, stack is only 4k but the rtos task stack is derived from the heap so it's ok.
  • Cache is disabled globally in main(), right after the MPU configuration. I have also tried this with the driver cache control enable define, but there was no change.

 

 

class Hardware {
    ........
public:
	/**
	 * Phy resource object for the phy.
	 * Must be public so that the LWIP task can get it
	 */
	phy_ksz8081_resource_t g_phy_resource;

	/**
	 * Phy Handle
	 */
	phy_handle_t phyHandle;


	netif lwip_netif;
}

 

extern const phy_operations_t phyksz8081_ops;
static void lwIP_init(void *arg) {

	Hardware * hw = (Hardware *)arg;

	hw->g_phy_resource.write = MDIO_Write;
	hw->g_phy_resource.read = MDIO_Read;



	// Enable the 50MHz RMII Clock derived from ENET PLL
    IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);

	ethernetif_config_t lwIP_netif0_enet_config = {
			.phyHandle = 	&hw->phyHandle,
			.phyAddr = 		BECK_PHYKSZ8081_ADDRESS,
			.phyOps = 		&phyksz8081_ops,
			.phyResource =	&hw->g_phy_resource,
			.srcClockHz =	125000000UL,
	};
	// gotta memcpy in the MAC address
	// though we could just directly bit bang the registers later
	memcpy(&lwIP_netif0_enet_config.macAddress, hw->GetMACAddr(), 6);


	uint8_t * ip_addr = hw->GetIPAddr();
	uint8_t * ip_netmask = hw->GetSubnetMask();
	uint8_t * ip_gateway = hw->GetGateway();

	/* lwIP IP address initialization */
	IP4_ADDR(&lwIP_netif0_ipaddr, ip_addr[0], ip_addr[1],
			ip_addr[2], ip_addr[3]);
	/* lwIP netmask initialization */
	IP4_ADDR(&lwIP_netif0_netmask, ip_netmask[0], ip_netmask[1],
			ip_netmask[2], ip_netmask[3]);
	/* lwIP gateway initialization */
	IP4_ADDR(&lwIP_netif0_gw, ip_gateway[0], ip_gateway[1], ip_gateway[2],
			ip_gateway[3]);
	/* lwIP module initialization */
	tcpip_init(tcpip_init_done, NULL);
	/* ENET peripheral initialization */
	/* ENET clock enable */
    (void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(ENET)]);
	/* ENET set SMI (serial management interface) */
	ENET_SetSMI(ENET, CLOCK_GetFreq(kCLOCK_IpgClk), false);



	/* lwIP network interface initialization */
	netifapi_netif_add(&hw->lwip_netif, &lwIP_netif0_ipaddr, &lwIP_netif0_netmask,
			&lwIP_netif0_gw, &lwIP_netif0_enet_config, ethernetif0_init,
			tcpip_input);
	netifapi_netif_set_default(&hw->lwip_netif);
	netifapi_netif_set_up(&hw->lwip_netif);

#if (BECK_BOARD_REVISION_MAJOR == 1U)	// Board Revision A
#warning Forcing Ethernet Phy RMII Mode (BA5533A)
	// Strapping options are f'd up
	// Force RMII mode override
	MDIO_Write(1, 0x16, 2);
#endif

#ifdef DEBUG
	xTaskCreate(get_phyregs, "Phy Debug", 128, NULL,0, NULL);
    // enable the ethenet statistics counters
    ENET->MIBC &= 0x7FFF;	// set b31 0
#endif
	/* lwIP interface auto-negotiation check */
	while (ethernetif_wait_linkup(&hw->lwip_netif, 5000UL) != ERR_OK) {
		PRINTF(
				"PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
	}
	// link status is now UP
	// print debug stuff
    PRINTF("\r\n************************************************\r\n");
    PRINTF(" BA-5533 Network Configuration\r\n");
    PRINTF("************************************************\r\n");
    PRINTF(" IPv4 Address     : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_ipaddr)[0], ((u8_t *)&lwIP_netif0_ipaddr)[1],
           ((u8_t *)&lwIP_netif0_ipaddr)[2], ((u8_t *)&lwIP_netif0_ipaddr)[3]);
    PRINTF(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_netmask)[0], ((u8_t *)&lwIP_netif0_netmask)[1],
           ((u8_t *)&lwIP_netif0_netmask)[2], ((u8_t *)&lwIP_netif0_netmask)[3]);
    PRINTF(" IPv4 Gateway     : %u.%u.%u.%u\r\n", ((u8_t *)&lwIP_netif0_gw)[0], ((u8_t *)&lwIP_netif0_gw)[1],
           ((u8_t *)&lwIP_netif0_gw)[2], ((u8_t *)&lwIP_netif0_gw)[3]);
    /*PRINTF(" MAC Address      : %02X:%02X:%02X:%02X:%02X:%02X\r\n", (u8_t *)(&hw->lwip_netif.hwaddr[0]), &hw->lwip_netif.hwaddr[1],
    		&hw->lwip_netif.hwaddr[2], &hw->lwip_netif.hwaddr[3], &hw->lwip_netif.hwaddr[4], &hw->lwip_netif.hwaddr[5]);
    		*/
    PRINTF("************************************************\r\n");

    ping_init(&lwIP_netif0_gw);

    // because tasks must not return, call task delete
	vTaskDelete(NULL);
}

 

the stack size for the init task is 512, but I don't think it really needs all that much. The TCPIP thread spawns just fine, as well as the LWIP RX thread.

 

Any help or insight is appreciated.

标签 (1)
0 项奖励
回复
1 解答
2,057 次查看
GUnderdown
Contributor III

@nxf77486I have solved most of the issues (at least related to this topic).

 

In summary:

 

The MAC not working at all seemed to be caused by my use of NewLibNano. How the libc implementation breaks the MAC is beyond me, but that was the change I made and it started working.

 

Then once the MAC worked, the receiving did not work. This was due to USE_RTOS not being defined.

 

@nxf77486is there a list of all the #defines used in the SDK, and what they control?

 

I am going to close this issue now.

在原帖中查看解决方案

0 项奖励
回复
22 回复数
338 次查看
GUnderdown
Contributor III

After copying the SDK example's fsl_enet.c + .h into my project, the reserved values not being zero issue was resolved. I think that's a bit odd, seeing as I hadn't modified them, and the SDK version reported by MCUXpresso is the same, but that issue seems to be fixed

 

0 项奖励
回复
165 次查看
GUnderdown
Contributor III

@nxf77486 

So now it seems that the data gets sent, but there is no data received.

I think now the problem is within LWIP, as looking at the MIB counters within the MAC, I see that data is being sent and received. For some reason, though, no data makes it up the layers to LWIP so the only data that gets sent ends up being a repeated ARP request looking for the same address every time.

 

Do you have any troubleshooting tips on this?

So far I have not observed the lwip rx_task get past the xTaskNotifyWait() call in rx_task(), which makes me think that the rx interrupt or notification is never called.

0 项奖励
回复