---
title: "WIZ550io Ver1.3 using MPLab X IDE v6.0 and Wiznet_DHCP project with iolibrary"
url: "https://maker.wiznet.io/forum/15706"
markdown_url: "https://maker.wiznet.io/forum/15706/md"
type: "Forum topic"
category: "Ethernet Chips"
author: "dbabayev"
created: "2025-04-22T00:11:28+09:00"
last_activity: "2025-04-23T11:08:16+09:00"
language: "en"
views: 7
replies: 3
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# WIZ550io Ver1.3 using MPLab X IDE v6.0 and Wiznet_DHCP project with iolibrary

## Question

Asked by dbabayev on 2025-04-22 in Ethernet Chips.

Hello,

I am trying to evaluate WIZ550io board for use in a simple Ethernet bridge as a Telnet server.

The easiest interface I had was a PIC32 eval board and I wired up the SPI interface as needed.

I came across a Wiznet_DHCP project with ioLibrary for MPLab.

With minor mods and running in MPLab X v6.0 the DHCP is defaulting to static IP which is fine and once socket is established, all is working.

The one issue is that the code goes into a while loop when socket is listening

// Delay for 1ms for the connection process
while ((sockStatus = getSn_SR(DATASOCKET)) == SOCK_LISTEN) {
tmp = 0xFFFF;
while (tmp--);
}

Once SOCK_ESTABLISHED, fall out of loop and connected!

I don't want to stay in this loop and added timer to check getSn_SR register for SOCK_ESTABLISHED.

It never works!!!

How often or how fast do I need to check? Is there an interrupt?

Does it time out if I don't follow up with something when request comes in?

## Replies

### Reply 1 by Grace_Koo, 2025-04-22

Hello, I’d like to provide a follow-up with additional details to complement the previous answer.

If you want to avoid a `while(getSn_SR() == SOCK_LISTEN)` style of polling, you can use the **INTn interrupt pin of the WIZ550io **to handle connection events asynchronously. This allows your MCU to react only when needed, avoiding busy loops and saving CPU resources.

![](https://maker.wiznet.io/upload/mirror/body/4dffaa318c77d4d8bb5d.jpg)

By connecting the INTn pin to the external interrupt input of your MCU (typically configured for falling-edge), the MCU can detect the event and respond by checking the appropriate interrupt registers.

**Reference**:

- W5500 Datasheet, **Page 56**: Interrupt Mask Register (Sn_IMR (Socket n Interrupt Mask Register) [R/W] [0x002C] [0xFF])

- W5500 Datasheet, **Page 48**: Socket n Interrupt Register (Sn_IR (Socket n Interrupt Register) [RCW1] [0x0002] [0x00])

#### **Basic Workflow**

1. Open a socket and call `listen()`.

2. Enable the connection interrupt in the `Sn_IMR` register for the target socket.

3. Set up an external interrupt on the MCU connected to the W5500’s INTn pin.

4. When the INTn signal goes low, the MCU interrupt handler should read the `Sn_IR` register, check for the `Sn_IR_CON` bit, and handle the connection event.

5. Clear the interrupt flag by writing `1` back to the corresponding bit in `Sn_IR`.

#### Example Code

```c
// Enable connection interrupt for the socket
setSn_IMR(DATASOCKET, getSn_IMR(DATASOCKET) | Sn_IR_CON);

// In the main loop — do not block
if (getSn_SR(DATASOCKET) == SOCK_LISTEN) {
    // Socket is listening, waiting for peer connection
    // The interrupt will notify when connected
}

// Interrupt handler (called when INTn is triggered)
void wiznet_irq_handler(void) {
    uint8_t sn_ir = getSn_IR(DATASOCKET);

    if (sn_ir & Sn_IR_CON) {
        // Connection established
        // Proceed with connection handling here
    }

    // Clear interrupt flag
    setSn_IR(DATASOCKET, sn_ir);
}
```

#### Notes

- INTn is active-low, so configure the MCU interrupt for falling-edge detection.

- The `Sn_IMR` register must have the corresponding bit enabled to allow the interrupt to occur.

- Interrupt flags in `Sn_IR` must be cleared by writing `1` back to the bit position (write-1-to-clear).

- For multiple sockets, iterate through each to check which one triggered the interrupt

If the issue is not resolved or if you have any further questions, please feel free to let me know.

Best regards,
Grace

### Reply 2 by dbabayev, 2025-04-23 (in reply to reply 1)

Both responses are perfect and seem very simple to implement but I cannot get past INTn (J2 pin 5) not moving.

It stays high even disconnected from MCU board.

I set the IMR right after socket opened and listen is successfully called.

I left same polling code beyond that and I monitor the INTn pin to see if it moves.

Is anything resetting the IR register during the polling before INTn is active?

I even replaced polling code with just a while(1) loop after socket opened and listen is successfully called, connection with client establishes in the background but no activity on INTn pin.

#include &lt;stdio.h>
#include &lt;stddef.h>
#include &lt;stdbool.h>
#include &lt;stdlib.h>
#include &lt;string.h>
#include "definitions.h"
#include "../src/ioLibrary_Driver-master/ioLibrary_Driver-master/Application/multicast/multicast.h"
#include "../src/ioLibrary_Driver-master/ioLibrary_Driver-master/Ethernet/W5500/w5500.h"
#include "../src/ioLibrary_Driver-master/ioLibrary_Driver-master/Ethernet/socket.h"
#include "../src/ioLibrary_Driver-master/ioLibrary_Driver-master/Internet/DHCP/dhcp.h"

// Constants
#define DATASOCKET 1
#define portNumber 23

// Global variables
uint8_t SOCK_DHCP = 0;
uint8_t gDATABUF[600];
int8_t retVal;
uint8_t sockStatus = 0;
char message[500] = " ";

// Network information structure
wiz_NetInfo networkInfo = {
.mac = {0x00, 0x08, 0xdc,0x.., 0x.., 0x..},
.ip = {192, 168, 1, 22},
.sn = {255, 255, 255, 0},
.gw = {192, 168, 1, 1},
.dns = {0,0,0,0},
.dhcp = NETINFO_DHCP
};

// Timeout configuration structure
wiz_NetTimeout gWIZNETTIME = {
.retry_cnt = 1, // RCR = 1
.time_100us = 1000 // RTR = 2000
};

// Function prototypes
void TIMER2_InterruptSvcRoutine(uint32_t status, uintptr_t context);
void network_init(wiz_NetInfo net);
**void handleClientCommunication();**

int **main**(void) {
// Initialization
SYS_Initialize(NULL);
wizInit();

// Set MAC address
setSHAR(networkInfo.mac);

// Initialize DHCP
DHCP_init(SOCK_DHCP, gDATABUF);

// Set up a timer interrupt to be called every second
TMR2_CallbackRegister(TIMER2_InterruptSvcRoutine, (uintptr_t)NULL);
TMR2_Start();

// Set network timeout
ctlnetwork(CN_SET_TIMEOUT, (void *)&gWIZNETTIME);

// Main Loop
while (1) {
if (getPHYCFGR() & PHYCFGR_LNK_ON) {
switch (DHCP_run()) {
case DHCP_IP_ASSIGN:
case DHCP_IP_CHANGED:
// Customize actions for IP assignment or change
break;

case DHCP_IP_LEASED:
// Handle network-related tasks when IP is leased
..... **NOT USING DHCP NETWORK**
break;

** case DHCP_FAILED:**
// Notify about DHCP failure
memset(message, 0, sizeof(message));
strcpy(message, ">> DHCP Retry Limit Exceeded\r\n");
UART1_Write(message, strlen(message));

// Stop DHCP and retry initialization
DHCP_stop();

// Notify applying default network settings
memset(message, 0, sizeof(message));
strcpy(message, ">> Applying Default Network Settings\r\n");
UART1_Write(message, strlen(message));

// Display default network information
memset(message, 0, sizeof(message));
sprintf(message, "Network Information:\r\n"
" Assigned IP: %d.%d.%d.%d\r\n"
" Subnet Mask: %d.%d.%d.%d\r\n"
" Gateway: %d.%d.%d.%d\r\n"
" DNS Server: %d.%d.%d.%d\r\n"
" MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
.....);
UART1_Write(message, strlen(message));

// Initialize network with default settings and handle client communication
network_init(networkInfo);
**handleClientCommunication();**
TMR2_Stop();
TMR2_CallbackRegister(TIMER2_InterruptSvcRoutine, (uintptr_t)NULL);
TMR2_Start();
DHCP_init(SOCK_DHCP, gDATABUF);
break;

default:
break;
}
} else {
// Handle error connecting
memset(message, 0, sizeof(message));
strcpy(message, ">> Error Connecting \r\n");
UART1_Write(message, strlen(message));
}
}

return EXIT_SUCCESS;
}

/* Initializes network settings */
void network_init(wiz_NetInfo net) {
setSn_KPALVTR(DATASOCKET, 1); // Set keep alive, 1 = 5 sec, 10 = 50 sec
ctlnetwork(CN_SET_NETINFO, (void*)&net);
}

/* This function is called after a period matches in Timer 3 (32-bit timer) */
void TIMER2_InterruptSvcRoutine(uint32_t status, uintptr_t context) {
LED2_Toggle();

DHCP_time_handler();
}

// Handles communication with the client //
void handleClientCommunication() {

if ((retVal = socket(DATASOCKET, Sn_MR_TCP, portNumber, 0)) == DATASOCKET) {
if ((retVal = listen(DATASOCKET)) == SOCK_OK) {
memset(message, 0, sizeof(message));
strcpy(message, ">> Looking for connection\r\n");
UART1_Write(message, strlen(message));

**setSn_IMR(DATASOCKET, (getSn_IMR(DATASOCKET) | Sn_IR_CON));**

while (1) {
;
}
}
}

### Reply 3 by Grace_Koo, 2025-04-23 (in reply to reply 1)

Hello,

I'd like to share an example that demonstrates a simpler way to configure interrupts.

Please refer to the following GitHub repository:
<https://github.com/WIZnet-ioNIC/WIZnet-PICO-FREERTOS-C.git>
This project was originally created to use FreeRTOS with the Raspberry Pi Pico board, but please note that the `tcp_client_over_ssl` example in the repository **does make use of interrupts**.
For reference, the `dhcp_dns` example in the same repository does not use interrupts.

You'll find a useful file named `w5x00_gpio_irq.c` under the `libraries/iolibrary_driver/src` directory.
The callback function used in this file is based on the Pico SDK, so please feel free to adapt it as needed to suit your own development environment.

Try using the functions defined in that file, and let me know how it goes.

I've also included a simple `tcp_server` example that triggers an INTn interrupt only when a socket is connected.
I hope this helps. Thank you.

Best regards,
Grace

// w5x00_loopback.c

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "port_common.h"

#include "wizchip_conf.h"
#include "w5x00_spi.h"
#include "w5x00_gpio_irq.h"

#include "loopback.h"


#define PLL_SYS_KHZ (133 * 1000)

#define ETHERNET_BUF_MAX_SIZE (1024 * 2)

#define SOCKET_LOOPBACK 0

#define PORT_LOOPBACK 5000

static wiz_NetInfo g_net_info =
    {
        .mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56}, // MAC address
        .ip = {192, 168, 11, 50},                     // IP address
        .sn = {255, 255, 255, 0},                    // Subnet Mask
        .gw = {192, 168, 11, 1},                     // Gateway
        .dns = {168, 126, 63, 1},                         // DNS server
        .dhcp = NETINFO_STATIC                       // DHCP enable/disable
};


static uint8_t g_loopback_buf[ETHERNET_BUF_MAX_SIZE] = {
    0,
};

static void set_clock_khz(void);

static void gpio_callback(void);

int main()
{
    /* Initialize */
    int retval = 0;

    set_clock_khz();

    stdio_init_all();

    wizchip_spi_initialize();
    wizchip_cris_initialize();

    wizchip_reset();
    wizchip_initialize();
    wizchip_check();

    wizchip_gpio_interrupt_initialize(SOCKET_LOOPBACK, gpio_callback);

    network_initialize(g_net_info);

    /* Get network information */
    print_network_information(g_net_info);

    /* Infinite loop */
    while (1)
    {
        /* TCP server loopback test */
        if ((retval = loopback_tcps(SOCKET_LOOPBACK, g_loopback_buf, PORT_LOOPBACK)) < 0)
        {
            printf(" Loopback error : %d\n", retval);

            while (1)
                ;
        }
    }
}

static void gpio_callback(void)
{
    printf("INT pin21 falling\r\n");
}

static void set_clock_khz(void)
{
    // set a system clock frequency in khz
    set_sys_clock_khz(PLL_SYS_KHZ, true);

    // configure the specified clock
    clock_configure(
        clk_peri,
        0,                                                // No glitchless mux
        CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, // System PLL on AUX mux
        PLL_SYS_KHZ * 1000,                               // Input frequency
        PLL_SYS_KHZ * 1000                                // Output (must be same as no divider)
    );
}
```

// w5x00_gpio_irq.c (only socket connected)

```c
/**
 * Copyright (c) 2022 WIZnet Co.,Ltd
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/**
 * ----------------------------------------------------------------------------------------------------
 * Includes
 * ----------------------------------------------------------------------------------------------------
 */
#include <stdio.h>

#include "pico/stdlib.h"
#include "hardware/gpio.h"

#include "wizchip_conf.h"
#include "socket.h"
#include "w5x00_gpio_irq.h"

/**
 * ----------------------------------------------------------------------------------------------------
 * Variables
 * ----------------------------------------------------------------------------------------------------
 */
static void (*callback_ptr)(void);

/**
 * ----------------------------------------------------------------------------------------------------
 * Functions
 * ----------------------------------------------------------------------------------------------------
 */
/* GPIO */
void wizchip_gpio_interrupt_initialize(uint8_t socket, void (*callback)(void))
{
    uint16_t reg_val;
    int ret_val;

    // reg_val = (SIK_CONNECTED | SIK_DISCONNECTED | SIK_RECEIVED | SIK_TIMEOUT); // except SendOK
    reg_val = SIK_CONNECTED; // except SendOK
    ctlsocket(socket, CS_CLR_INTERRUPT, (void *)&reg_val);
    ret_val = ctlsocket(socket, CS_SET_INTMASK, (void *)&reg_val);

#if (_WIZCHIP_ == W5100S)
    reg_val = (1 << socket);
#elif (_WIZCHIP_ == W5500)
    reg_val = ((1 << socket) << 8);
#endif
    ret_val = ctlwizchip(CW_SET_INTRMASK, (void *)&reg_val);

    callback_ptr = callback;
    gpio_set_irq_enabled_with_callback(PIN_INT, GPIO_IRQ_EDGE_FALL, true, &wizchip_gpio_interrupt_callback);
}

static void wizchip_gpio_interrupt_callback(uint gpio, uint32_t events)
{
    if (callback_ptr != NULL)
    {
        callback_ptr();
    }
}
```

---

Source: https://maker.wiznet.io/forum/15706
