Did you know that using W5100S it is possible to execute ARP and PING requests without opening a socket?
Socket-less commands (SLC) for ARP and PING requests can be extremely useful when testing network environment or checking device connection status. These functions are supported only in W5100S & W6100 and can be operated by controlling following registers:
- SLCR – SOCKET-less Command,
- SLIR – SOCKET-less Interrupt,
- SLIMR – SOCKET-less Interrupt Mask,
- SLIRCLR – SOCKET-less Interrupt Clear,
- SLDIPR – SOCKET-less Destination IP Address,
- SLDHAR – SOCKET-less Destination Hardware Address,
- PINGIDR – PING ID,
- PINGSEQR – PING Sequence Number.
To learn more about W5100S refer to this link, more information about socket-less commands can be found here.
In this project I will demonstrate how to run these commands.
1. SW Environment
I used Win 10 and followed instructions in WIZnet repo for software environment setup.
2. SLC for ARP request
Operation flow is shown in WIZnet application note Figure 1 (below).
Using Socket-less functions with RP2040 and W5100S
This project will demonstrate how to use W5100S socket-less commands.
Things used in this project
Story
Did you know that using W5100S it is possible to execute ARP and PING requests without opening a socket?
Socket-less commands (SLC) for ARP and PING requests can be extremely useful when testing network environment or checking device connection status. These functions are supported only in W5100S & W6100 and can be operated by controlling following registers:
- SLCR – SOCKET-less Command,
- SLIR – SOCKET-less Interrupt,
- SLIMR – SOCKET-less Interrupt Mask,
- SLIRCLR – SOCKET-less Interrupt Clear,
- SLDIPR – SOCKET-less Destination IP Address,
- SLDHAR – SOCKET-less Destination Hardware Address,
- PINGIDR – PING ID,
- PINGSEQR – PING Sequence Number.
To learn more about W5100S refer to this link, more information about socket-less commands can be found here.
In this project I will demonstrate how to run these commands.
1. SW Environment
I used Win 10 and followed instructions in WIZnet repo for software environment setup.
2. SLC for ARP request
Operation flow is shown in WIZnet application note Figure 1 (below).
WIZnet ioLibrary already has everything to operate W5100S registers, just need to follow this flow.
Code is pretty straightforward.
configure_arp_request function will reset interrupt register and set values for SLRCR (Count Register) and SLRTR (Time register). W5100S will send ARP-requests unless it number of requests exceeds value in SLRCR, after that SLIR register will be set to Timeout.
static uint16_t ArpRCR = 0x08;
static uint16_t ArpRTR = 0x07d0;
void configure_arp_request(void)
{
setSLIR(SLIR_TIMEOUT | SLIR_ARP);
setSLRCR(ArpRCR);
setSLRTR(ArpRTR);
}
As W5100S automatically prepares packet, it is neccesary only to pass address as parameter and set SLCR register. send_arp_request will then send request to given address.
uint8_t send_arp_request(uint8_t *addr)
{
setSLPIPR(addr);
setSLCR(SLCMD_ARP);
}
Next, it is needed to check a result of sent request, which is done by recv_arp_reply function. In this function SLIR register is checked, if ARP bit is set to 1, then reply was received. If Timeout bit is set to 1, then response was not received and request count exceeded predefined number.
uint8_t recv_arp_reply()
{
if(getSLIR()&SLIR_ARP){
setSLIR(SLIR_ARP);
return ARP_SUCCESS;
}
else if(getSLIR()&SLIR_TIMEOUT){
setSLIR(SLIR_TIMEOUT);
return TIMEOUT_ERROR;
}
else return ARP_FAIL;
}
Once response is received, W5100S will put MAC-address automatically to SLPHAR register.
void get_arp_MacAddress(uint8_t* addr)
{
getSLPHAR(addr);
}
3. SLC for PING
PING operation flow is shown in same application note.
Functions for PING SLC. These are similar to ARP request, therefore I will skip description of each function.
static uint16_t RandomID = 0x1234;
static uint16_t RandomSeqNum = 0x4321;
static uint16_t PingRCR = 0x08;
static uint16_t PingRTR = 0x07d0;
void configure_ping_request(void){
setSLIR(SLIR_TIMEOUT | SLIR_PING);
setSLRCR(PingRCR);
setSLRTR(PingRTR);
setPINGSEQR(RandomID);
setPINGIDR(RandomSeqNum);
}
uint8_t send_ping_request(uint8_t s, uint8_t *addr)
{
setSLPIPR(addr);
setSLCR(SLCMD_PING);
}
uint8_t recv_ping_reply(uint8_t s){
if(getSLIR()&SLIR_PING){
setSLIR(SLIR_PING);
return PING_SUCCESS;
}
else if(getSLIR()&SLIR_TIMEOUT){
setSLIR(SLIR_TIMEOUT);
return TIMEOUT_ERROR;
}
else return PING_FAIL;
}// ping_reply
4. Simple code for testing
I used WIZnet examples as base and just updated main loop.
In my case I had 3 devices connected to my router, for simple test I sent ARP- and PING- requests to IP range from 192.168.0.4 ~ 10.
uint8_t dest_ip[4]={192,168,0,4};
while(dest_ip[3]<11)
{
printf("Send ARP to : %d.%d.%d.%dn", dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3]);
int8_t arp_ret=arp_auto(dest_ip);
if(arp_ret==1)
{
printf("ARP : successfulrn");
get_arp_MacAddress(addr0);
printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2xrn",addr0[0],addr0[1],addr0[2],addr0[3],addr0[4],addr0[5],addr0[6]);
}
else printf("ARP : failurern", arp_ret);
printf("Sending PING to : %d.%d.%d.%dn", dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3]);
int8_t ping_ret=ping_auto(0, dest_ip);
printf("Ping statistics for %d.%d.%d.%d:n", dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3]);
printf(" Sent = 4, Received = %d, Lost = %d (%d%% of loss)rn", ping_ret, 4 - ping_ret, (1 - ping_ret/4) * 100);
dest_ip[3] = dest_ip[3] +1;
printf("--------------------------------------------------nn");
}
Check final results below.
Image on the left shows information from router, image on the right shows code execution results.
There was no ping response from 192.168.0.10 because I forgot to turn off Windows Firewall and Defender, that’s why ARP was successful, but 100% loss of PING.
I enclosed 3 source files that I used for this project. In order to run on W5100S-EVB-Pico or Raspberry Pi Pico board, it would be necessary to update CMakeLists files accordingly.
Hope this project can help understanding concept of Socket-less commands.
COMMENTS