Reputation: 432
I use a Raspberry Pi Pico with a ENC28J60 PCB connected to one of its SPI. I use the pico-sdK downloaded 2023-11-29, and I use pico-enc28j60 downloaded from https://git.sr.ht/~krystianch/pico-enc28j60 on the same day. I had to modify CMakeLists.txt of enc28j60 project since lwIP was moved from Pico Extras to Pico SDK.
The initialization function looks like this:
static bool ethernet_init()
{
err_t err;
lwip_init();
queue_init( &R.rx_queue, sizeof(struct pbuf *), ENC28J60_RX_QUEUE_SIZE );
critical_section_init( &R.spi_cs );
// initialize modbus clients
for( int i=0; i<MODBUS_CLIENTS_MAX; i++ )
{
R.modbus_clients[i].tcp = 0;
R.modbus_clients[i].state = ST_UNUSED;
R.modbus_clients[i].seq_nr = (i << 12) | ((i << 8) ^ 0x0F00);
}
R.enc28j60.spi = spi1;
R.enc28j60.cs_pin = SPI1_CSn_PIN;
R.enc28j60.mac_address[0] = R.cfg.mac_addr[0];
R.enc28j60.mac_address[1] = R.cfg.mac_addr[1];
R.enc28j60.mac_address[2] = R.cfg.mac_addr[2];
R.enc28j60.mac_address[3] = R.cfg.mac_addr[3];
R.enc28j60.mac_address[4] = R.cfg.mac_addr[4];
R.enc28j60.mac_address[5] = R.cfg.mac_addr[5];
R.enc28j60.next_packet = 0;
R.enc28j60.critical_section = &R.spi_cs;
R.netif.name[0] = 'e';
R.netif.name[1] = 'n';
gpio_set_function( SPI1_SCK_PIN, GPIO_FUNC_SPI );
gpio_set_function( SPI1_MOSI_PIN, GPIO_FUNC_SPI );
gpio_set_function( SPI1_MISO_PIN, GPIO_FUNC_SPI );
gpio_init( SPI1_CSn_PIN );
gpio_put( SPI1_CSn_PIN, true );
gpio_set_dir( SPI1_CSn_PIN, true );
gpio_init( ETH_INT_PIN );
gpio_init( ETH_RST_PIN );
// reset the chip
gpio_put( ETH_RST_PIN, false );
gpio_set_dir( ETH_RST_PIN, true );
sleep_ms( 1 );
gpio_put( ETH_RST_PIN, true );
spi_init( R.enc28j60.spi, SPI1_SPEED );
netif_add( &R.netif, &R.cfg.ip_addr, &R.cfg.netmask, &R.cfg.gateway,
&R.enc28j60, ethernetif_init, netif_input );
netif_set_up( &R.netif );
netif_set_link_up( &R.netif ); // +++ should check the enc if the link is up
gpio_set_irq_enabled_with_callback( ETH_INT_PIN, GPIO_IRQ_EDGE_FALL,
true, eth_irq );
enc28j60_interrupts( &R.enc28j60,
ENC28J60_PKTIE | ENC28J60_TXERIE | ENC28J60_RXERIE );
R.tcp_modbus = tcp_new_ip_type( IPADDR_TYPE_V4 );
err = tcp_bind( R.tcp_modbus, IP4_ADDR_ANY, TCP_PORT_MODBUS );
if( err != ERR_OK )
{
return false;
}
R.tcp_modbus = tcp_listen_with_backlog( R.tcp_modbus, BACKLOG_MODBUS );
if( !R.tcp_modbus )
{
return false;
}
tcp_accept( R.tcp_modbus, modbus_accept );
return true;
}
On the local network everything works fine. I can ping it, I can connect to the TCP port and do modbus queries, works perfect.
But when put a router between the computer and the Pico I get problems. Ping still works fine, but I get no TCP connects. I can see the SYN packets going towards the Pico but I see no SYN/ACK coming back. I put a printf into the modbus_accept function to see if it is called, but it is not called at all.
I believe the pico-enc28j60 works fine since there are no problems on the local network, and also since the ping over the router works too.
I believe the interface is configured correctly since ping is routed fine.
So I believe there must be a problem either in my code or in lwIP. I just can't see what is wrong.
Any hints?
Upvotes: 0
Views: 148
Reputation: 432
After digging and debugging through the lwIP source code if found out that netif_default
was NULL
. Calling netif_set_default
solves the problem.
The same thing was recommended in this email: https://lists.nongnu.org/archive/html/lwip-users/2012-03/msg00083.html
Upvotes: 0